lato.2_mrp_mlx/lato_mlx
John 2a0f64375c Cache the prepared device gather index (5.9x total on the hot op)
Caching only the raw indice map left two thirds of the runtime on the table. Every
layer still rebuilt the missing->N sentinel substitution over 5.6M elements in numpy
and re-uploaded a 22.6MB index to the GPU. Isolating the kernel showed ~13ms of
actual GPU work behind ~26ms of CPU bookkeeping.

The transposed, sentinel-substituted index depends only on the coordinate set - the
same invariant that justifies caching the indice map - so it is now cached on-device
whole.

m3ultra 128^3/128ch, cumulative:
  per-offset loop      81.6ms   2.57 Mvox/s
  fused gather+matmul  39.3ms   5.34
  cached device index  13.8ms  15.25   <- 5.9x total

A chunk-size sweep confirmed 256MB (11 dispatches) is at the optimum; unchunked is
marginally slower (14.2ms), so the chunking is free insurance for small-memory boxes.
2026-08-02 10:09:57 +10:00
..
sparse Cache the prepared device gather index (5.9x total on the hot op) 2026-08-02 10:09:57 +10:00
__init__.py MLX sparse core: SubMConv3d + SparseTensor + weight converter 2026-08-02 10:04:24 +10:00
convert.py MLX sparse core: SubMConv3d + SparseTensor + weight converter 2026-08-02 10:04:24 +10:00