Skip to content

bench: roofline datapoint for Apple M2 Pro (Mac mini, cliffs + perf) - #145

Merged
sbryngelson merged 3 commits into
sbryngelson:mainfrom
axiom-of-choice:roofline-m2-pro
Aug 1, 2026
Merged

bench: roofline datapoint for Apple M2 Pro (Mac mini, cliffs + perf)#145
sbryngelson merged 3 commits into
sbryngelson:mainfrom
axiom-of-choice:roofline-m2-pro

Conversation

@axiom-of-choice

@axiom-of-choice axiom-of-choice commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Datapoint for #137. Adds Apple M2 Pro to the map.

Run from a clean checkout of 263e02f (dirty: false in the report), Mac14,12 Mac mini, macOS 26.5.2 (25F84), AC, automatic energy mode.

matmul inf-cliff ~32758.8  |  slice cliff 4094.1  |  reduce exact <= 2048

The interesting one: the slice clamp is present on M2 Pro

Chip slice-x16 (Q.4 crop-DMA)
Apple M2 Pro (this run) clamp @ 4094
Apple M5 Pro exact (no clamp)

The issue says the pre-A16 crop-DMA clamp is gone by A16/M5, and this is the first M-series confirmation in the table that it is there on an earlier chip. So the boundary is now bracketed from both sides rather than only asserted on one.

The other two look architecture-wide, not per-generation

Both match the M5 Pro:

Worth noting the second one against history: when I probed the integer reduce by hand on this same machine (#115, 2026-07-31) it looked exact past 2048 and I reported it as not reproducing. The suite disagrees, and the suite is right. My hand probe kept the addends small enough that the sum stayed on the exact fp16 grid, so it never actually crossed the boundary the metric measures. The harness picks the boundary case properly. Retracting that half of my earlier report; the per-generation split there was my measurement artifact, not silicon.

Perf half (added)

Ran --perf with sudo from a clean tree. Measured ANE peaks:

Peak fp16 GEMM Peak perf/W Streaming bandwidth
3.26 TF/s 1379 GFLOP/s/W 1.0 GB/s

Two table cells stay empty, both for reasons worth stating rather than hiding.

Ridge, and the table's GEMM/bandwidth cells, are blank because of a harness bug I hit and filed as #146. aggregate_rooflines reads those three from roofline_analysis.py, and that step raised KeyError: 'ane'. Cause: layer_norm failed to compile on the ANE at these shapes, so the bandwidth script correctly recorded ane_gbps: None and that archetype's peak block has no ane key, but load_ceilings iterates a hardcoded ("CPU","GPU","ANE") per archetype and raises. Not specific to this machine: any run where one archetype loses one engine loses the whole synthesis. The measured numbers above are in this report's perf_rooflines regardless, so nothing is lost, only unsynthesized. Once #146 lands, re-running aggregate_rooflines.py fills those cells with no new measurement.

Decode is blank for a genuinely different reason, and it is a datapoint. On M2 the decode model's [1, 32000] vocab projection exceeds ANE family 3's 16384 max dimension, so both batch rows return:

NotImplementedError: aneforge: tensor (1, 32000) (op 'matmul') exceeds ANE family 3's
max dimension 16384; tile the graph or target a higher chip.

That is a real per-generation capability limit, not a harness failure. The same model measures fine on your M5 (117 tok/s in the table), so bench/decode_measurement.py currently cannot produce a decode number on family-3 silicon at all without tiling the projection. Worth deciding whether the harness should tile it, or whether the table should distinguish "not measured" from "cannot run on this family".

Not included

Not included

Nothing further. Both halves are in.

Files

  • bench/results/rooflines/roofline-apple-m2-pro-Mac14_12-723396ad9091-1c1aa174.json (new)
  • bench/results/ROOFLINES.md (regenerated with bench/aggregate_rooflines.py, now 2 machines)

Numeric-cliffs run on a Mac14,12 Mac mini, macOS 26.5.2 (25F84), on AC at
automatic energy mode, from a clean checkout of 263e02f.

The slice crop-DMA clamp is present here: |value| > 4094 goes to inf, where the
M5 Pro is exact. That is the first confirmation of the pre-A16 clamp from an
M-series chip in this table, and it brackets when the clamp disappears.

matmul inf-cliff and reduce exactness both match the M5 Pro (~32759 across
K in {4,8,32,64,128}, and integer row-sums exact through 2048, first wrong at
2049 -> 2050), so those two look architecture-wide rather than per-generation.

Perf rooflines not included: --perf needs an interactive sudo for powermetrics.
Add yours: `PYTHONPATH=. python3 bench/roofline_suite.py --contributor <your-gh-handle>`, commit the JSON it writes under `bench/results/rooflines/`, regenerate this file with `python3 bench/aggregate_rooflines.py`, and open a PR. See [`rooflines/README.md`](rooflines/README.md).

Thanks to [@sbryngelson](https://github.com/sbryngelson) for contributing datapoints.
Thanks to [@axiom-of-choice](https://github.com/axiom-of-choice), [@sbryngelson](https://github.com/sbryngelson) for contributing datapoints.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbryngelson Feel free to edit this contribution sections

Replaces the cliffs-only submission with a --perf run (sudo granted) from a clean
checkout of 263e02f. Measured ANE peaks: 3.26 TF/s fp16 GEMM, 1379 GFLOP/s/W,
1.0 GB/s streaming bandwidth.

Two columns stay empty, for reasons worth recording rather than hiding:

Ridge and the table's GEMM/bandwidth cells come only from roofline_analysis.py,
which fails on any --perf run (filed as sbryngelson#146): PERF_FAST passes --quick, --quick
omits GPU from the sweeps, and load_ceilings iterates a hardcoded CPU/GPU/ANE.
The underlying numbers are in this report's perf_rooflines regardless.

Decode is empty for a different and more interesting reason: on M2 the decode
model's [1,32000] vocab projection exceeds ANE family 3's 16384 dimension cap, so
both batch rows return NotImplementedError. That is a real per-generation limit,
not a harness failure; the same model fits on M5.
@axiom-of-choice axiom-of-choice changed the title bench: roofline datapoint for Apple M2 Pro (Mac mini) bench: roofline datapoint for Apple M2 Pro (Mac mini, cliffs + perf) Aug 1, 2026
The previous commit message blamed --quick for omitting GPU from the sweeps.
That was wrong: GPU is present throughout this run. roofline_analysis fails
because layer_norm did not compile on the ANE, so that one archetype's peak
block has no 'ane' key while load_ceilings iterates a hardcoded CPU/GPU/ANE
per archetype. Filed and corrected in sbryngelson#146; the measured numbers are unaffected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants