Override the Backend trait's host-round-trip defaults: gather is S @ X with
S the [E x N] one-hot selection CSR; scatter-add is the adjoint S^T @ X,
whose CSR is built directly by counting sort so duplicate indices land in
one row and the spmm kernel (one thread per output element) accumulates
them without atomics. CSR matrices are cached per thread keyed by the
exact index list + dims, so a static graph topology (GNN message passing)
builds each matrix once. Host fallback on degenerate shapes or any
sparse-pipeline failure.
13 new parity tests vs CPU reference: duplicates, unreferenced rows,
D=1/2/3, 15k x 5k x 64 gather/scatter, cache reuse, adjoint roundtrip.
Verified on-device that the SpMM path (not the fallback) serves all 13.
Co-Authored-By: Claude Fable 5 <[email protected]>