# lato.2_mrp_mlx — working notes MLX port of LATO.2 (factorised mesh gen: vertex flow -> connectivity flow) for Apple Silicon. ## Key facts established by measurement (don't re-derive) - Upstream is CUDA-locked via `modules/sparse/__init__.py`: BACKEND accepts only spconv/torchsparse, ATTN only xformers/flash_attn. No SDPA fallback exists upstream. - The ONLY CUDA-locked op that matters is submanifold 3x3x3 conv. Every SparseConv3d in the model uses default `stride=1, padding=None` -> SubMConv3d. No strided/inverse conv. - Of 7 checkpoints, only vvae.pt has sparse conv kernels (18). vflow.pt is sparse-typed but conv-free. voxel_encoder.pt is dense nn.Conv3d (29). Rest are fully dense. - spconv weight layout is KRSC `[out, kz, ky, kx, in]` (verified against vvae.pt). torch nn.Conv3d is `[out, in, kz, ky, kx]`. Both are 5-D -> `classify_5d()` disambiguates; do not treat rank-5 as automatically sparse. - Upsampling is `SparseSubdivide` (coords*2 + unit cube, feats replicated), not inverse conv. ## Unresolved - Kernel orientation (correlation vs convolution) is unverified and numerically silent. Settle it via V-VAE reconstruction quality, not by argument. `--flip-kernel` builds the mirrored weights. ## Conventions - Project venv at `.venv` (mlx + numpy + torch + trimesh). torch is CONVERSION-ONLY. - `upstream/LATO.2` is vendored read-only reference; never edit it. - Tests must compare against an independent implementation, not a second copy of the same indexing logic. spconv is unavailable here so there is no upstream numerical oracle.