Repository navigation
Move the remaining GPU workflows onto the per-task GPU queue - #578
Conversation
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
4 open findings
from_spec()no longer validates thatranks` is present and numeric before building the task name,… · New from_spec()no longer validates thatranks` is present and numeric before building the task name,… · New This script downloads and executes a remote test file. Since it is now centralized in a reusable… · New The--task ... "COMMAND"values embed long, multi-line shell strings with continuation… · New
What changed in this PR
Moves the remaining GPU-heavy CI workflows off the per-job bash GPU allocator and onto the per-task gpu_task_queue.py, adding support for queueing arbitrary GPU commands (not just test directories) to reduce runner-slot blocking and improve fairness via reservations.
Changes:
- Add
--task RANKS NAME COMMANDtogpu_task_queue.pyand allow mixing--taskwith existingTEST_DIR:RANKStasks. - Migrate performance regression, external validation, nightly Triton, and CCL benchmark workflows to use the queue instead of
acquire_gpus.sh. - Add
run_external_validation.sh, update container/image handling (CONTAINER_IMAGE) inrun_tests.sh, and removeacquire_gpus.sh.
| File | Description |
|---|---|
| .github/workflows/iris-performance-regression-test.yml | Consolidates perf benchmarks into one queued job using --task for node reservation + reduced slot blocking. |
| .github/workflows/iris-nightly-triton-test.yml | Switches nightly Triton tests to queued per-directory tasks (1/2/4/8 ranks) using CONTAINER_IMAGE. |
| .github/workflows/iris-external-validation-test.yml | Runs Triton + Gluon external validations as two queued tasks in one job; passes repo/sha via env. |
| .github/workflows/iris-ccl-benchmark.yml | Runs CCL sweep via a queued task and copies results out of the task’s private checkout. |
| .github/scripts/run_tests.sh | Adds CONTAINER_IMAGE override and prints Triton version inside the container. |
| .github/scripts/run_new_examples.sh | Updates comment to reflect GPU_DEVICES now coming from gpu_task_queue.py. |
| .github/scripts/run_external_validation.sh | New script to run external validation via queued GPU tasks with correct --gpus propagation. |
| .github/scripts/release_gpus.sh | Updates comment to describe releasing GPUs held by gpu_task_queue.py after abnormal termination. |
| .github/scripts/gpu_task_queue.py | Adds --task, relaxes --install requirement to only positional tasks, and supports shell-command tasks. |
| .github/scripts/acquire_gpus.sh | Removed (no longer used after workflow migrations). |
🧠 Review effort: Lite
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
The anti-starvation clock restarted whenever the head task launched, so in a job with several large tasks each one waited RESERVE_AFTER again before it could reserve the node, though it had been pending since the job started. On ROCm#578's perf run that added ~5 min per benchmark. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
There was a problem hiding this comment.
Looks good. Thanks Nirvedh.
We initially had these actions that test multiple things however it was a pain to debug issues that came up in CI so we broke them down into smaller tasks. We can try again though.
Please confirm all CI is passing before merging. CI is backed up at the moment.
|
@mawad-amd yes the CI is passing, but looks like we should change the required labels before landing, I think you did that for the previous PR with admin access. |
external validation, nightly Triton and the CCL benchmark on the per-job bash allocator. Those jobs still hold a runner slot while they wait for GPUs, and since the bash allocator never posts a reservation, its 8-GPU requests can be starved by the queue's backfill: perf benchmarks that run for ~75 s have waited up to 2.4 h. gpu_task_queue.py gains --task RANKS NAME COMMAND for work that is not a test directory. With it: - perf regression: the four 8-GPU benchmarks run back to back in one job - external validation: Triton and Gluon run side by side in one job, on 2 GPUs each. The Triton test never passed --gpus to the container, so it could see all 8 GPUs; run_external_validation.sh always passes them. - nightly Triton: one job per test directory, as in iris-tests.yml, using run_tests.sh with a new CONTAINER_IMAGE override for the nightly image - CCL benchmark: one task; results are copied out of the task's private checkout so the publish and upload steps still find them acquire_gpus.sh has no callers left and is removed. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The anti-starvation clock restarted whenever the head task launched, so in a job with several large tasks each one waited RESERVE_AFTER again before it could reserve the node, though it had been pending since the job started. On ROCm#578's perf run that added ~5 min per benchmark. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
eae7101 to
ddfac95
Compare
|
I was able to change the status checks so merging this so other PRs dont block on it. |

Follow-up to #571, addressing this comment. #571 moved only
iris-tests.ymlontogpu_task_queue.py. Perf regression, external validation, nightly Triton and the CCL benchmark still used the per-job bash allocator.Why it matters
A job on the bash allocator holds one of the runner's 4 slots while it waits for GPUs. The bash allocator also never posts a reservation, so its 8-GPU requests lose out to the queue's backfill of smaller tasks. From the last 6 successful runs of each workflow:
Before/after #571
The runner is a single 8-GPU host with 4 job slots (
iris-mi350x-0to-3). At most 4 jobs ever ran at once across the four names. Comparison of every GPU workflow run since Sep 20; after #571 there are only ~1.5 days of data (9 Iris Tests runs, 49 perf jobs), so read these as indicative.So #571 halved the slot time Iris Tests uses and raised GPU utilization. It also made the jobs left on the bash allocator wait longer:
Change
gpu_task_queue.pygains--task RANKS NAME COMMAND, for GPU work that isn't a test directory. Each task still gets a private copy of the checkout, withGPU_DEVICESset to its GPUs. The existingTEST_DIR:RANKSform is unchanged.iris-tests.ymlDetails:
--gpusto the container, so it saw all 8 and could land on GPUs another job held. The newrun_external_validation.shalways passes them.run_tests.shtakes aCONTAINER_IMAGEoverride, so the nightly Triton image goes through the same runner as everything else. The Triton version line moved intorun_tests.sh.ccl_results/out of its private checkout, so the publish and upload steps still find it, even on failure.acquire_gpus.shis removed: nothing calls it any more. New GPU workflows should go through the queue.Trade-off: perf results are now one check, not four. Each benchmark is still reported separately in the job log, the
::error::annotations and the step summary table, the same way #571 handled test directories. Running them back to back costs no parallelism: on a single 8-GPU host, two 8-GPU benchmarks could never run at the same time anyway.Testing
9,8;id) and a missing--installare rejected.run_tests.shandrun_external_validation.shwere run with a stubcontainer_exec.shto check the--imageand--gpusthey pass.ruffandzizmorare clean.Not yet run on GPUs. Perf and external validation run on this PR. Nightly and the CCL benchmark need a manual run from a branch in ROCm/iris.
🤖 Generated with Claude Code