Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions docs/guides/amica-differences.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,39 @@ Separate from reference divergences: the optional MLX backend is a subset.
| Outlier rejection | yes | yes | no | yes |
| Precision | f64/f32 | f64 | f32 only | f64 |
| Rank detection | yes | yes | yes | yes (absolute floor) |

MLX limitations raise `NotImplementedError` rather than differing silently, per
`.rules/backend_parity.md`.
| `min_dll` stop | yes | yes | **no** | yes |
| `min_nd` stop / gradient norm | yes | yes (as `min_grad_norm`) | **no** | yes |
| `keep_best` best-iterate restore | yes | no | no | n/a |
| MIR diagnostic | yes | no | no | n/a |
| Persistence | `state_dict` | EEGLAB `amicaout` | none | EEGLAB `amicaout` |

Most MLX limitations fail loudly: `do_newton=True` and non-GG `pdftype` raise
`NotImplementedError`, and every unsupported parameter is simply absent from the
constructor, so passing it raises `TypeError`.

**The convergence stops are the exception, and the one difference to plan
around.** `pamica/mlx_impl/core.py` implements neither stop — it has no
`min_dll`/`use_min_dll`/`maxincs` and no `min_nd`/`use_grad_norm`/`ndtmpsum`, so
its only outcomes are `max_iter`, `lrate_floor`, and the degenerate reasons
(`nan_ll`, `singular_ll`, `nan_params`).

The distinction is not that an MLX fit runs to `max_iter` — a PyTorch fit does
too at its own `max_iter=100` default, because `min_dll` needs several hundred
iterations to trigger on a recording this size. The distinction is what raising
`max_iter` buys you. On the other backends, a larger budget lets the likelihood
stop end the fit when it stops improving. **On MLX a larger budget is simply
spent**, however long the fit has stopped making progress.

Nothing warns you about this, because there is no parameter to reject. Two
consequences:

- Moving a working configuration from the PyTorch backend to MLX for the
Apple-GPU speedup does more work than the same `max_iter` implies. Size
`max_iter` for MLX from where the other backends actually stop improving on
your data.
- MLX cannot be evaluated on gradient-norm behaviour at all, because it never
computes the quantity. Any statement elsewhere in these guides about whether
the `min_nd` threshold is reachable covers Fortran, PyTorch and NumPy only.
(`numpy_impl` spells that same threshold `min_grad_norm`.)

Tracked in issue #248.
Loading