Repository navigation
ci(rocm): self-hosted gfx1151 runner that builds, links and smoke-tests ROCm changes #1811
Description
Part of #1801. Phase 3. Depends on #1802 (closed, landed in PR #1818).
Status (2026-09-29)
Everything this issue can deliver without hardware has landed: the job, its path filter, the visible parked state (PR #1989), and a local gate that runs the same smoke (PR #2008). The one thing left is registering a self-hosted runner labelled rocm-gfx1151 and setting the repository variable ROCM_CI_ENABLED to true. That cannot happen now: there is no spare AMD machine to dedicate to it, and registration also needs org admin. Until then make verify-rocm on an AMD host is the ROCm gate, run by hand, and the three acceptance criteria that need a live job stay unchecked.
Context
No workflow has an AMD runner. (Outdated: PR #1989 added the rocm-build job, parked because no runner is registered.) Because the ROCm side of every MLX pin bump now lives in src/lib/mlx-cpp/patches-rocm/, a bump that breaks the ROCm build or runtime would go unnoticed without a job that links and runs it. The CUDA history shows the risk of green-but-hollow jobs: on the 81ba1c6a bump, CUDA checks were green while nothing linked (cargo check does not link, the sm_70 job skipped on a CUDA 13 runner, and the xla-link job had no path trigger for pin changes).
A Linux host with a Radeon 8060S (gfx1151) is available as a self-hosted runner. It also runs other GPU services, so jobs must account for shared GPU memory and load. (Update: no spare machine is available to register as that runner, so it has not been registered.)
Scope
A ROCm CI job on a self-hosted runner that builds with --features rocm, links, and runs a short generation, triggered by every change that can affect the ROCm build.
Implementation plan
- Register the runner with a dedicated label (for example
rocm-gfx1151) and document the host prerequisites (ROCm version, OpenBLAS/LAPACKE, Rust toolchain, disk fortarget/and_deps/). Open, blocked on hardware. The label is fixed asrocm-gfx1151(runs-on: [self-hosted, rocm-gfx1151],.github/workflows/ci.yml:1646). Host requirements live in the job's own comments next to it, as the GB10 runner's do (PR ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989):MLX_ROCM_ARCHITECTURES: gfx1151set explicitly, a persistentCARGO_TARGET_DIRunder$HOME/.cargo-target/mlxcel-rocm-ci, and a 180-minute timeout for a cold build. - Add a
rocmjob:cargo build --release --features rocm, thenmlxcel generate -n 10 --temp 0on theqwen3-0.6b-4bitCI fixture from the public releaseci-fixtures/qwen3-0.6b-4bit-v1, run withLD_LIBRARY_PATHunset, asserting a non-empty, non-garbage output and a GPU device in the diagnostics. Done in PR ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989, body shared by PR test(rocm): add a local verify-rocm gate with a shared build-and-generate smoke #2008. The job isrocm-build("ROCm build and generate",.github/workflows/ci.yml:1630-1714). It builds, downloads the same fixture, and runsscripts/ci/rocm_smoke.sh, which generates 32 tokens at--temp 0withLD_LIBRARY_PATHunset (scripts/ci/rocm_smoke.sh:87-92) and assertsRuntime device: GPU,custom kernel backend: rocm, aHIP architecture gfxline, no CUDA compute capability, at least 16 generated tokens and at least 8 word-like tokens of generated text (:105-126). - Add a
rocmpath filter in.github/workflows/ci.yml(filters are defined around lines 104-160)coveringsrc/lib/mlx-cpp/patches-rocm/**,src/lib/mlx-cpp/CMakeLists.txt,src/lib/mlxcel-core/build.rs,src/lib/mlxcel-core/build_support/**, the bridgecpp/sources andCargo.tomlfeature changes. The MLX pin line must trigger it. Done in PR ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989. The filter is at.github/workflows/ci.yml:189-203: all ofsrc/lib/mlx-cpp/**minus the Metal and CUDA overlays (sopatches-rocm/and the pin insrc/lib/mlx-cpp/CMakeLists.txtare both in), plusbuild.rs,build_support/**,src/lib/mlxcel-core/cpp/**, the rootbuild.rs,**/Cargo.tomlandCargo.lock. - Fail the job (not skip) if the runner is offline for a pin-bump PR, or make the skip visible in the PR checks. Done in PR ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989, the "visible" variant. A job whose runner does not exist is queued for up to 24 hours rather than skipped, which would hold every overlay PR's run open, so
rocm-buildis gated onvars.ROCM_CI_ENABLED == 'true'(.github/workflows/ci.yml:1642-1645). The hostedrocm-ci-statusjob (:1727-1752) runs on every change that matches the filter and emits a "ROCm gate parked" warning naming the two activation steps. It reports the variable only: querying runner registration needs anadministrationscope thatGITHUB_TOKENcannot carry in a workflow file, so that was dropped before merge. It never fails a PR. - Keep the job's GPU footprint small and document how it coexists with other GPU tenants on the host. Done in PRs ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989 and test(rocm): add a local verify-rocm gate with a shared build-and-generate smoke #2008. One small checkpoint, one 32-token generation, a persistent target directory, and a memory preflight in
scripts/ci/rocm_smoke.sh:55-72that reports available memory and names the largest resident processes before building (co-tenantllama-serverprocesses were measured holding 25.5 GiB of about 30 GiB). - (Added) Local substitute until a runner exists. Done in PR test(rocm): add a local verify-rocm gate with a shared build-and-generate smoke #2008.
make verify-rocm(Makefile:804) mirrorsmake verifyfor ROCm: crate versions, kernel dtype keys, kernel port dispatch, llama-compat manifest, fmt,verify-clippy-rocm, thenverify-rocm-smoke(Makefile:790, the samescripts/ci/rocm_smoke.shthe job runs, so the two cannot drift) andverify-test-rocm.
Acceptance criteria
- A PR touching
patches-rocm/or the MLX pin runs the ROCm job, which builds, links and generates. (Job and filter exist, PR ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989; blocked on a registered runner andROCM_CI_ENABLED.) - The job log shows the binary linked against the ROCm libraries and ran on the GPU. (The assertions exist in
scripts/ci/rocm_smoke.sh; blocked on a runner. Locally,make verify-rocm-smokeshowed this ongfx1151in PR test(rocm): add a local verify-rocm gate with a shared build-and-generate smoke #2008.) - A deliberately broken overlay file fails the job. (Blocked on a runner.)
- Unrelated PRs do not trigger it. (Path filter
.github/workflows/ci.yml:189-203plus theROCM_CI_ENABLEDgate, PR ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989.)
Activation, once hardware exists
- Register a self-hosted runner with the labels
self-hostedandrocm-gfx1151(org admin). - Set the repository variable
ROCM_CI_ENABLEDtotrue. - Open a PR that touches
src/lib/mlx-cpp/patches-rocm/and confirmROCm build and generateruns; then break one overlay file on a throwaway branch and confirm it fails. That closes the three open criteria.
References
.github/workflows/ci.yml(rocmfilter 189-203,rocm-build1630-1714,rocm-ci-status1727-1752)scripts/ci/rocm_smoke.sh,Makefile:790(verify-rocm-smoke),Makefile:804(verify-rocm)- CI fixture: public release
ci-fixtures/qwen3-0.6b-4bit-v1
Refresh log
2026-09-29
- Marked plan items 2 to 5 done with their landing PRs (ci(rocm): build, link and generate on a self-hosted gfx1151 runner #1989 for the job, filter and parked-state report; test(rocm): add a local verify-rocm gate with a shared build-and-generate smoke #2008 for the shared smoke script and memory preflight) and added item 6 for the local
make verify-rocmgate. - Checked off "unrelated PRs do not trigger it"; the other three criteria need a live runner and stay open.
- Stated plainly that the only remaining work is registering a
rocm-gfx1151runner and flippingROCM_CI_ENABLED, which is blocked because no spare AMD machine exists. - Replaced the stale filter location (104-160) with the verified
.github/workflows/ci.yml:189-203, and noted thatrocm-ci-statusreports only the variable, not runner registration.
Activity
ci(rocm): build, link and generate on a self-hosted gfx1151 runner
ci(rocm): build, link and generate on a self-hosted gfx1151 runner
ci(rocm): build, link and generate on a self-hosted gfx1151 runner (#…
fix(rocm): run the smoke before the test gate in verify-rocm
test(rocm): add a local verify-rocm gate with a shared build-and-gene…