Modular v2106 point models¶
Scope¶
This package ports the complete upstream e3nn.nn.models.v2106 point-model
family to MLX:
points_convolution.Convolution;gate_points_message_passing.MessagePassingandCompose;gate_points_networks.SimpleNetwork;gate_points_networks.NetworkForAGraphWithAttributes.
The implementation keeps the upstream tensor-product paths, gate selection,
hidden representation construction, ten-component smooth_finite radial
basis, component-normalized spherical harmonics, learned residual mixing, and
sqrt(num_neighbors) / sqrt(num_nodes) normalizations. Public model calls
return IrrepsArray objects so the output representation remains explicit.
Public API¶
The canonical imports mirror the upstream module layout:
from e3nn_mlx.models.v2106 import (
Convolution,
MessagePassing,
NetworkForAGraphWithAttributes,
SimpleNetwork,
)
The package root also exports V2106Convolution, V2106MessagePassing,
SimpleNetwork, and NetworkForAGraphWithAttributes.
SimpleNetwork¶
SimpleNetwork derives node attributes, spherical-harmonic edge attributes,
and radial features from node positions:
network = SimpleNetwork(
irreps_in="3x0e + 2x1o",
irreps_out="4x0e + 1x1o",
max_radius=2.0,
num_neighbors=3.0,
num_nodes=5.0,
)
output = network({"pos": positions, "x": node_features, "batch": batch})
batch is optional and defaults to one graph. With pool_nodes=True, the
result has one row per graph. With pool_nodes=False, it has one row per node.
NetworkForAGraphWithAttributes¶
This variant accepts representation-aware node and edge attributes:
network = NetworkForAGraphWithAttributes(
irreps_node_input="3x0e + 2x1o",
irreps_node_attr="4x0e + 1x1o",
irreps_edge_attr="1e",
irreps_node_output="3x0o + 1e",
max_radius=2.0,
num_neighbors=3.0,
num_nodes=5.0,
)
output = network(
{
"pos": positions,
"node_input": node_features, # "x" is an equivalent alias
"node_attr": node_attributes,
"edge_attr": edge_attributes,
"edge_index": edge_index, # optional
"batch": batch, # optional
}
)
When edge_index is omitted, the model constructs a directed, loop-free
radius graph within each batch. edge_attr must follow the resulting edge
order. When attributes come from an existing graph or neighbor list, supplying
edge_index explicitly is therefore recommended.
Fixed-topology compilation¶
MLX 0.31 has no device-side dynamic nonzero, so radius-graph discovery is an
eager operation. Both network classes expose forward_with_edges to keep the
entire differentiable calculation inside a compiled MLX graph once a topology
is known.
For SimpleNetwork:
edges = e3nn.radius_graph(positions, network.max_radius, batch)
def forward(pos, x, batch, src, dst):
return network.forward_with_edges(
pos, x, batch, src, dst, num_graphs=num_graphs
).array
compiled_forward = mx.compile(forward)
For NetworkForAGraphWithAttributes, pass node_attr and the caller-provided
edge_attr between node_input and batch. Position gradients continue
through edge vectors, distances, the radial basis, and spherical harmonics;
only the discrete edge selection is fixed.
Lower-level modules¶
Convolution accepts IrrepsArray node features, node attributes, and edge
attributes plus integer edge_src / edge_dst arrays and invariant radial
features. forward_arrays is the raw-array compilation entry point.
The v2106 residual rule is preserved exactly. The learned scalar tensor product
alpha starts at zero, so paths supported by the self connection initially
equal that self connection. Unlike a conventional fixed residual coefficient,
alpha becomes an invariant, data-dependent mixing factor during training.
MessagePassing builds a gated convolution for every hidden representation,
filters unreachable tensor-product paths, tracks the actual post-gate irrep
sequence, and finishes with an ungated convolution. It also provides
forward_arrays.
Empty edge lists are supported by every layer. They bypass the per-edge tensor product and produce the same residual-only result without invoking unsupported zero-sized compiled Metal kernels.
Verification evidence¶
The focused v2106 tests cover:
scalar middle paths, zero-initialized and active learned residual mixing;
repeated proper rotations and inversion for convolution, message passing, and both complete networks;
translation invariance of the complete networks;
exact upstream-sized three-hidden-layer configurations;
compiled execution and cached reuse at every layer of the public stack;
gradients for positions, node inputs, node attributes, edge attributes, radial inputs, and every trainable parameter;
an optimizer-style parameter update;
edge-order invariance, empty edges, isolated nodes, and automatic graphs;
batched graphs versus independent evaluation and pooled versus node output;
x/node_inputaliases, validation failures, deepcopy, and MLX weight save/load round-trips.
The corresponding tests are:
tests/test_v2106_convolution.py;tests/test_v2106_message_passing.py;tests/test_v2106_networks.py.