Skip to content

Epic: Apple-Silicon GPU acceleration for AMICATorchNG (float32 -> MLX -> benchmark) #74

Description

@neuromechanist

Goal

Enable GPU acceleration of the natural-gradient EM backend (AMICATorchNG) on Apple
Silicon. The research in #72 (.context/mps_pathways.md) established the governing
constraint and a sequenced set of pathways; this epic executes them.

Governing constraint (why this is not a one-liner)

Apple-Silicon GPUs have no FP64 hardware. Neither PyTorch MPS nor MLX exposes
float64 on the GPU (float64 is CPU-only on both). AMICATorchNG computes in float64
for Fortran parity, so the parity path can never run on an Apple GPU. Every
Apple-GPU pathway is therefore gated on a numerically stable float32 (mixed-precision)
AMICA.

Phases (sequenced A -> C -> B)

  1. Phase A - float32 stabilization (the enabler). Kahan/compensated summation +
    mixed precision on the sufficient-stat accumulation and density/LL. Reopens and
    supersedes the parked Stabilize float32 AMICATorchNG for the GPU fast path #70 technical work. Unblocks everything else.
  2. Phase C - MLX backend port. Apple-native array framework (2-3x over PyTorch MPS,
    fused lazy graph). float32-only on GPU, so it depends on Phase A. Higher ceiling,
    higher cost; a v2 backend, kept optional.
  3. Phase B - dimension-sweep benchmark. Measure MPS/MLX-float32 vs CPU across
    channel count / block size / n_models to find the crossover. The 32-channel test in
    Optimize AMICATorchNG per-iteration cost (pow hot spot + CPU threading) #63 was the wrong regime: MPS dispatch overhead is fixed per op and amortizes on
    large tensors. Runs last so it can benchmark A (and C) together.

Non-goals / ruled out

  • FP64 emulation on Apple GPUs (metal-float64): dead end - custom-Metal-only (not
    callable from PyTorch), no transcendentals (AMICA needs exp/log/pow), 18-32x
    penalty. Ruled out in the research.
  • Changing the production default: float64-CUDA (4.5x, bit-safe, auto-selected)
    stays the production GPU path. MPS/MLX stay experimental until Phase B validates them.

Acceptance (epic-level)

  • Phase A: float32 (mixed) fit converges on the full sample data across seeds, LL within
    parity tolerance of float64, no seed-flaky NaN; float64 default stays bit-identical.
  • Phase C: MLX backend equivalent to the PyTorch float32 backend on the same data.
  • Phase B: documented crossover curve (where Apple GPU beats CPU) in the perf notes +
    a single-flag sweep in benchmarks/benchmark_gpu.py.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestepicEpic tracking issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions