Migrating from e3nn/PyTorch¶
The high-level namespaces deliberately resemble upstream e3nn:
e3nn/PyTorch |
e3nn-mlx |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Most constructors preserve the upstream names and representation arguments:
import mlx.core as mx
from e3nn_mlx import nn, o3
linear = o3.Linear("16x0e + 8x1o", "32x0e + 8x1o")
gate = nn.Gate(
"16x0e", [mx.tanh],
"8x0e", [mx.sigmoid],
"8x1o",
)
Moving Linear weights¶
Default Linear paths and flattened weights follow upstream’s input-major,
then output-index order. A flat upstream weight array can be copied without
reordering when the input irreps, output irreps, and explicit instructions are
the same. Use weight_views(..., yield_instruction=True) on both sides of a
converter to verify every path shape and meaning.
For weights generated per sample or graph edge, construct the MLX layer with
internal_weights=False, shared_weights=False and pass an array shaped
(..., weight_numel). See the Linear guide for the complete
layout and normalization contract.
Deliberate differences¶
MLX evaluates lazily. Include
mx.eval(...)before reading results and when timing work.mx.compiletraces fixed array computation. Dynamic neighbor discovery is eager; construct edges once and use a model’sforward_with_edgesmethod in compiled training or inference.IrrepsArrayis optional ine3nn_mlx.o3ande3nn_mlx.nn, but the original flat API continues to use it for explicit representation checking.Generated Metal kernels are selected automatically and remain subject to dtype, shape, and autodiff-transform boundaries.
TorchScript-specific APIs do not apply to MLX.
For an operation-by-operation statement of supported behavior, see the compatibility and numerical conventions and high-level API notes.