Skip to content

M6: drop mlx::core::compile wrapping after Phase-1 de-risk - #13

Merged
ausimian merged 1 commit into
mainfrom
feat/m6-compile-derisk
Apr 14, 2026
Merged

M6: drop mlx::core::compile wrapping after Phase-1 de-risk#13
ausimian merged 1 commit into
mainfrom
feat/m6-compile-derisk

Conversation

@ausimian

Copy link
Copy Markdown
Owner

Summary

  • Phase-1 de-risk microbench (pure C++, MLX 0.25.1, Apple Silicon) shows the fusion win on a Qwen3-0.6B-shaped transformer block is 1.04–1.07× on GPU and a regression on CPU (0.82–0.88×) — below the PLAN's 1.20× gate. M6 dropped per the PLAN's own exit criterion.
  • Retains the bench harness (mix bench.native, bench/native/compile_microbench.cpp, bench/compile_microbench.md) as a permanent fixture so the decision can be re-measured against future MLX releases without rebuilding the harness.
  • Updates PLAN.md, RELEASE.md, and Emily.Compiler's moduledoc to record the drop and reasoning.

Why 1.04× and not more

Transformer inference is matmul-dominated, and MLX's mx::compile does not fuse matmul kernels with surrounding elementwise ops. Fusion is confined to RMSNorm chains, the softmax neighbourhood, and SwiGLU's silu×up — all small fractions of block runtime.

A sanity workload (pure 8-op elementwise chain) in the same harness shows 2.78× GPU / 1.47× CPU, confirming the measurement is sound and the harness wiring is correct.

Test plan

  • mix precommit — compile --warnings-as-errors, format, credo --strict, test. Clean (0 credo issues, 183 tests + 56 properties pass, 0 failures).
  • mix bench.native — produces the full results table (GPU + CPU, transformer + sanity). Committed to bench/compile_microbench.md.
  • mix bench.native -- --seq 512 --iters 500 — longer-sequence variant confirms result is not shape-dependent.

Artefacts retained for future re-measurement

  • bench/native/compile_microbench.cpp
  • lib/mix/tasks/bench.native.ex
  • bench-native target in Makefile
  • bench/compile_microbench.md

A pure-C++ microbenchmark on MLX 0.25.1 / Apple Silicon GPU shows the
fusion win on a Qwen3-0.6B-shaped transformer block is 1.04x-1.07x
(GPU) and a regression on CPU (0.82x-0.88x) — well below the PLAN's
1.20x gate. A sanity workload (pure 8-op elementwise chain) in the
same harness shows 2.78x GPU / 1.47x CPU, so the measurement is
trustworthy — the limiting factor is that MLX compile doesn't fuse
matmul with surrounding elementwise ops, and transformer inference is
matmul-dominated. Fusion wins are confined to RMSNorm / softmax /
SwiGLU neighbourhoods, a small fraction of block runtime.

The BEAM-integrated compile path could not exceed this C++ ceiling,
so Phase 2 (approach review) and Phase 3 (implementation) were not
built.

Retained as permanent fixtures so the decision can be re-measured
against future MLX releases without rebuilding the harness:

  - bench/native/compile_microbench.cpp — transformer block + sanity
    elementwise chain, both timed compiled vs uncompiled.
  - lib/mix/tasks/bench.native.ex — `mix bench.native` invokes the
    new `bench-native` Makefile target with the same env elixir_make
    sets, reusing the project's pinned MLX without a second fetch.
    Supports --seq / --warmup / --iters via `mix bench.native -- ...`.
  - Makefile: `bench-native` target, produces
    $(BUILD_DIR)/compile_microbench and runs it.
  - bench/compile_microbench.md — results table + reproduction.

PLAN.md: M6 section rewritten to record the drop with the measurement;
core design decision #1 and the M5 footnote updated to match.
Emily.Compiler moduledoc note reframed.
@ausimian
ausimian merged commit b0907b8 into main Apr 14, 2026
1 check passed
@ausimian
ausimian deleted the feat/m6-compile-derisk branch April 14, 2026 11:45
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.

1 participant