gate(GATE-METAL-MLX-COMPILE): W2 — compile all four Metal TUs on the post-merge lane, against the real SDK (#1765) - #1792
Merged
Conversation
…nner that compiles them is post-merge (#1765) `§10` O3 recorded `metal_ops.mm`, `metal_backend.mm` and `metal_context.mm` as owed and owned by nobody, and O2 left the MLX API to release time. This wave takes both, on a `macos-15` job rather than a Linux one, and the spec section says why that was the only technique left. Measured at `be432e8e3`, before any of it: each of the three appears 0 times in `build.ninja` and 0 times in `compile_commands.json`, against 3 for the wave-1 provider target and 6 for `src/vt/op_provider.cpp` as a control. Broken all three at once with one seam rename each -- `RegisterBackend`, `VT_CHECK`, `RegisterOp`, 1/6/19 hunks -- the full CPU build returns rc 0 in 9m24s with zero `error:` lines and zero mentions of the three files, and `ctest` is green (593/595; the two reds pass on a serial re-run). A break in these files is invisible to everything that runs today. Wave 1's technique cannot be extended to them, and that is measured rather than argued: with the same `-x c++` recipe and stub include path they fail with 22, 46 and 166 errors, `metal_context.mm` on `stray '@' in program`. No stub fixes that. They need an Objective-C++ front end, which the development host does not have at all (`cannot execute 'cc1objplus'`, no clang anywhere). The section costs the three designs and records the developer's choice of C: a Linux clang gate would invent ~30 Apple selectors, 14 types and 5 constants and compile a different ObjC dialect than AppleClang, for 3 of 4 TUs; the same macOS job on every pull request buys pre-merge at ~10x a Linux runner on ~55 pushes a day; the post-merge lane buys the same 4-of-4 coverage for neither. What it gives up is stated as a limit rather than glossed -- it names a break a commit or two after it lands, not before. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…post-merge lane, against the real SDK (#1765) `src/vt/metal/metal_{context,backend,ops}.mm` are named in `CMakeLists.txt` and resolve into no build rule anywhere: 0 occurrences each in `build.ninja` and `compile_commands.json` on a configured Linux tree, against 6 for `src/vt/op_provider.cpp` as a control. Break all three with a seam rename and the full CPU build still returns rc 0 and `ctest` still passes. The only compiler that ever read them was `metal_arm64` in `release.yml`, which fires on a `v*` tag -- 955 commits after the last one, 2 of them editing these files and 28 editing seam headers they include. `macos-metal-mlx` is `release.yml`'s proven `metal_arm64`/`mlx_arm64` shape with the release-only parts removed: `macos-15`, checkout, the same `mlx==0.32.0` install and `MLX_ROOT` resolution, `build-macos-release.sh`'s configure flags, and `--target vllm`. It compiles; it does not package or execute. MLX is ON because run 31466516224 measured the difference at ten seconds (5m59s vs 6m09s) and it buys the fourth TU against the real headers, which the wave-1 stubs are blind to by construction. POST-MERGE deliberately. No `pull_request`: a macOS runner is roughly 10x a Linux one and this repository takes ~55 pushes/day. On `push` to `main` plus the 4-hourly baseline the exposure window is the commits since the last completed run instead of "until somebody cuts a release". The wave-1 Linux syntax check stays -- it is the only Metal signal a pull request gets, and it is free. Two things the job asserts about itself. The last step requires all four `.mm.o` objects to exist and names a missing one, because a green build proves nothing if `VLLM_CPP_METAL` resolved OFF or a TU left `target_sources`; that is absence wearing success's face, the #274/#503 shape. And the job joins `baseline-summary`'s `needs:` and `main-baseline.py`'s `EXPECTED_JOBS` (count pin 11 -> 12), because a compiling gate the baseline never grades is #503 exactly. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
… own file, one green compiling all four (#1765) The gate cannot be run from a Linux host, so its two halves are dispatched runs of `ci.yml` on one probe branch per file, each carrying the shipped job and exactly one mutated file. Green: run 32647402016 on this branch, `macos-metal-mlx` success in 5m03s, with `compiled .../{metal_context,metal_backend,metal_ops,metal_mlx_provider}.mm.o` for all four and `MLX GEMM provider enabled` against the installed `mlx-0.32.0`. Red: 32647406515 `metal_backend.mm:141:5`, 32650354752 `metal_context.mm:44:5`, 32650358209 `metal_ops.mm:1092:5`, each `use of undeclared identifier` on the renamed seam symbol, each `FAILED: [code=1]` on its own object. Every red stops at the compile step and SKIPS the object-existence step, so the compiler produced it rather than the assertion. Two things the runs measured that were not asked for. The expected first red did not happen: 955 commits after the last macOS build, all four TUs still compile, so the drift was exposure that had not yet become a break. And a `macos-15` runner took 45 and 50 minutes to allocate, which prices design B -- the same job pre-merge -- in wall time on every contributor's pull request rather than only in dollars. `§11 Outcome` is recorded with the rejected designs and the reason each default has its value. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
Routine integration before landing the macOS compile gate. No conflicts. FOLLOWING_AGENTS_PROTOCOL Issue: #1765 Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
src/vt/metal/metal_{context,backend,ops}.mmare named inCMakeLists.txtandresolve into no build rule anywhere. On a configured Linux tree at
be432e8e3each appears 0 times in
build.ninjaand 0 times incompile_commands.json, against 3 for the wave-1 provider target and 6 forsrc/vt/op_provider.cppas a control.The break goes undetected today, measured rather than argued
One #1584-class seam rename per file, all three at once:
RegisterBackend(frominclude/vt/backend.h(1 hunk),VT_CHECK(frominclude/vt/dtype.h(6),RegisterOp(frominclude/vt/ops.h(19).cmake --build build -j 12returns rc 0 in 9m24.65s over 1667 edges, withzero
error:lines. The build log mentionsmetal_backend0 times,metal_context0 andmetal_ops0, andmetal_mlx_provideronce, which isthe wave-1 control proving the instrument works.
ctest --test-dir build -j 4: 593/595 passed, 3 skipped. The two reds(
test_serve_low_tools,test_async_llm) pass on a serial re-run, so they are-jstarvation underverification.md, and neither could be caused by a filein no build rule anyway.
git checkout --plustouch;sha256sum -cOK on all three.Wave 1's technique cannot be stretched over them, and that is measured too: with
the same
-x c++recipe and stub include path they fail with 22 / 46 / 166errors,
metal_context.mmonstray '@' in program. No stub fixes that. Theyneed an Objective-C++ front end, which the development host does not have
(
cannot execute 'cc1objplus', no clang anywhere under/,/opt,/usr/localor$HOME).What lands
macos-metal-mlxinci.ymlisrelease.yml's provenmetal_arm64/mlx_arm64shape with the release-only parts removed:macos-15, checkout, thesame
pip install 'mlx==0.32.0'andimportlib.metadataresolution ofMLX_ROOT,scripts/build-macos-release.sh's configure flags, and--target vllm. It compiles; it does not package or execute.MLX is ON because the difference is ten seconds. On release run
31466516224,metal_arm64took 5m59s andmlx_arm646m09s. That buys thefourth TU compiled against the real
mlxheaders, which the wave-1 stubs areblind to by construction, so O2 is discharged as well. A pip failure reds the
job under its own step name and can never read as a verdict on the code.
Post-merge deliberately. No
pull_request: a macOS runner is roughly 10x aLinux one and this repository takes ~55 pushes/day. On
pushtomainplus the4-hourly baseline, the exposure window falls from "until somebody cuts a
release" — 955 commits since
7020de936(v0.0.2, 2026-08-11), 2 of them editingthese TUs and 28 editing seam headers they include — to the commits since the
last completed run. What it gives up is stated as a limit: it names a break a
commit or two after it lands, not before. The wave-1 Linux syntax check stays,
because it is the only Metal signal a pull request gets and it is free.
Two things the job asserts about itself. The last step requires all four
.mm.oobjects to exist and names the missing one, because a green build provesnothing if
VLLM_CPP_METALresolved OFF or a TU lefttarget_sources— absencewearing success's face, the #274 / #503 shape. And the job joins
baseline-summary'sneeds:andmain-baseline.py'sEXPECTED_JOBS(count pin11 → 12), because a compiling gate the published baseline never grades is #503
exactly. Dropping it from
needs:redstest_expected_jobs_is_pinned_against_the_workflow_needs_list, mutation-checked.Measured on the lane itself
No Linux host can run this job, so its two halves are dispatched runs of
ci.yml, one probe branch per file, each carrying the shipped job and exactlyone mutated file.
macos-metal-mlx32647402016compiled .../{metal_context,metal_backend,metal_ops,metal_mlx_provider}.mm.o, all four, afterSuccessfully installed mlx-0.32.0and-- MLX GEMM provider enabled: .../libmlx.dylib32647406515probe/metal-w2-red-backendRegisterBackend(, 1 hunkmetal_backend.mm:141:5: error: use of undeclared identifier32650354752probe/metal-w2-red-contextVT_CHECK(, 6 hunksmetal_context.mm:44:5: error: use of undeclared identifier32650358209probe/metal-w2-red-opsRegisterOp(, 19 hunksmetal_ops.mm:1092:5: error: use of undeclared identifierEvery red fails at the compile step and skips the object-existence step, so
the compiler produced it and not the assertion. The same three breaks leave the
full Linux build and
ctestgreen. On the pull-request run of this very change(
32647478561) the job iscompleted/skippedin 0 s withrunner_name: null,which is the post-merge design priced at zero.
The expected first red did not happen: 955 commits after the last macOS build,
mainplus this change compiles all four TUs on the first attempt. The drift wasreal exposure that had not yet become a break.
Nothing is stubbed here, so nothing is claimed that is not built
src/vt/metal/stubs/README.mdis untouched and still exactly right about thewave-1 Linux target. This job builds against the real Apple SDK, the real
Foundation and Metal headers, AppleClang's ObjC++ front end and the real
mlxwheel.
#1765's two owed items, O2 and O3, are discharged: all four TUs are compiledagainst the real SDK and the real
mlxwheel. It is deliberately NOT closed by akeyword here, because what it buys is post-merge coverage rather than the
pre-merge lane its title asks for — that trade is the developer's recorded
decision C, and whoever merges this should close it knowingly.
Still owed, and unchanged by this: the runtime arms —
test_metal_backendon areal Metal device and
test_ops_attention_crosson CUDA — which are #1692's andstay open there.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]