ci(jax): run JAX tests on the multi-GPU runner - #6853
Conversation
✅ All Checks Passed — Ready for Review
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🎉 All checks passed! This PR is ready for review. |
erman-gurses
left a comment
There was a problem hiding this comment.
Would be good if you share the test details - how did you test it and what is the output.
please see the PR description @erman-gurses |
|
Requested review from @geomin12 and @amd-shiraz for capacity planning. 8 GPU runners are generally more expensive and in shorter supply than 1 GPU runners. |
20a9d67 to
6373b5e
Compare
| # JAX tests use the multi-GPU runner for the family. | ||
| runner_label = configure_target_run.get_runner_label("gfx94X-dcgpu", "linux") | ||
| self.assertEqual(runner_label, "linux-gfx942-1gpu-ccs-csp-ossci-rocm") | ||
| self.assertEqual(runner_label, "linux-gfx942-8gpu-ossci-rocm") |
There was a problem hiding this comment.
@gulsumgudukbay how many builds is JAX tests going to add on a daily basis ? including nightlies, PRs etc. this is a multi GPU runner and we only have 10 nodes and the capacity on these are already maxed out.
There was a problem hiding this comment.
For PR CI 1 JAX version (0.11.0) will be present and for nightly we have 4 versions (0.10.0, 0.10.1, 0.10.2 and 0.11.0).
|
More context... for PyTorch we run standard tests on 1-GPU runners then "full" tests on a mix of 1-GPU and multi-GPU runners at lower frequency. See
We should probably do something similar for JAX. Would need to see the data for how much runner time is needed for each subset of the tests. |
|
Working with @amd-shiraz offline for capacity numbers. |
|
Also @ScottTodd Agreed on following the PyTorch model and the JAX equivalent of that split already exists upstream, in ci/run_pytest_rocm.sh in ROCm/jax (the script #6558 switches us to). It splits the suite by the multiaccelerator pytest marker into two separate invocations: So the "distributed vs everything else" classification is already done for us by the marker, and per-test durations are already written to the JSON/JUnit reports on every run, they're just not uploaded as artifacts today. Two things worth noting for the capacity discussion (cc @amd-shiraz): On a 1-GPU runner the multi-accelerator subset is skipped entirely (Skipping multi-accelerator tests (only 1 GPU detected)). So the multi-GPU runner isn't about speed, without it we get zero multi-device coverage. On this PR specifically: you and @amd-shiraz are right that it's too blunt as written. It was a fast PR to get other PRs unblocked and routes the whole JAX test job to the 8-GPU runner, including tests that only need 1 GPU. I'll rework it to match the PyTorch shape (default 1-GPU runner plus a separate multi-GPU runner input, with only the multiaccelerator subset routed there) so our 8-GPU footprint is limited to what genuinely requires it. |
|
thanks @gulsumgudukbay sharing some capacity backlogs we are seeing already hence we are being caution before taking more.
|
@amd-shiraz I started two jobs (1 and 8-GPU runner) 1-GPU: https://github.com/ROCm/TheRock/actions/runs/30325982453 These runs are ran using the following commands: on branch users/gulsumgudukbay/jax-timing-probe |
There was a problem hiding this comment.
as noted by Shiraz, let's calculate velocity so we don't run into queue issues with this machine. please work with @amd-shiraz about this
|
Also posting my results here @geomin12 @amd-shiraz @erman-gurses
Details worth noting:
The entire JAX suite finishes in about 18 minutes of 8-GPU node time, 14:49 for the single-accelerator tests plus 3:13 for the multi-accelerator ones. So this is a bounded, sub-half-hour nightly ask rather than a standing allocation. |
## Summary JAX test jobs were discarding the GPU isolation supplied by the runner, letting a job on a 1-GPU runner use every GPU on the host. This removes the two `unset` calls responsible. ## Problem `test_linux_jax_wheels_partial.yml` unset `HIP_VISIBLE_DEVICES` and `ROCR_VISIBLE_DEVICES` before running tests. Those are exactly the variables the runner provides through `--env-file /etc/podinfo/gha-gpu-isolation-settings`, and since the container is given `/dev/kfd` and `/dev/dri` outright, that env file is the only isolation mechanism in play. So a job scheduled on `linux-gfx942-1gpu-ccs-csp-ossci-rocm` enumerates all 8 GPUs and allocates across them. ## Impact In [run 30032481350](https://github.com/ROCm/TheRock/actions/runs/30032481350) all 15 test jobs saw 8 devices, and three failed with `RESOURCE_EXHAUSTED` on GPUs they were never assigned, all in `multi_device_test.py::MultiDeviceTest::test_lax_full_like_efficient`: | Job | Allocation | Allocator | |---|---|---| | [py3.14 / v0.10.2](https://github.com/ROCm/TheRock/actions/runs/30032481350/job/89307813608) | 12 GiB | `GPU_5_bfc` | | [py3.11 / v0.10.2](https://github.com/ROCm/TheRock/actions/runs/30032481350/job/89308971448) | 12 GiB | `GPU_7_bfc` | | [py3.13 / v0.10.1](https://github.com/ROCm/TheRock/actions/runs/30032481350/job/89308509210) | 16 GiB | `XLA_backend_5_bfc` | A 12 GiB allocation is trivial for a 192 GiB MI300X, so those GPUs were occupied by other tenants. This produces flaky failures that look like JAX or ROCm bugs, and our jobs can equally OOM other workloads on the same host. ## Why this fix Five workflows mount the isolation env file `test_pytorch_wheels.yml`, `test_pytorch_wheels_full.yml`, `test_rocm_wheels.yml`, `test_linux_jax_wheels.yml`, and this one. Only this one unsets the masks; removing them restores parity. The remaining unsets (`ROCM_ROOT`, `HIP_DEVICE_LIB_PATH`, `JAX_ROCM_PLUGIN_INTERNAL_*`) are unrelated to GPU visibility, they exist because the image is deliberately `/opt/rocm`-less and are left in place. No test logic, runner selection, or matrix configuration is touched. ## Note on multi-device coverage With isolation respected, jobs on 1-GPU runners see one GPU, so `run_pytest_rocm.sh` will skip the `multiaccelerator` subset (it gates on `gpu_count > 1`). Those tests need a properly labeled multi-GPU runner, tracked separately in #6853. Measured cost of that subset is 3:13 for 855 tests. ## Tests **Mechanism confirmed.** To show the masks were the cause rather than a correlation, I re-applied them explicitly after the unsets on a 1-GPU runner ([run 30325982453](https://github.com/ROCm/TheRock/actions/runs/30325982453)): ``` Number of GPUs detected: 1 [RocmDevice(id=0)] ``` `rocminfo` and JAX both reported one device, versus 8 in every unmasked run on the same runner label. **Verification of this branch.** [Run 30375175749](https://github.com/ROCm/TheRock/actions/runs/30375175749) on `linux-gfx942-1gpu-ccs-csp-ossci-rocm`, covering `multi_device_test.py` (the test that OOM'd above), `core_test.py`, `util_test.py` and `scipy_stats_test.py`. | Check | Expected | Result | |---|---|---| | Devices visible to JAX | `[RocmDevice(id=0)]` | `[RocmDevice(id=0)]` - 1 device | | Cross-tenant OOM | none | none | | Overall conclusion | success | success | Per-file results: | Test file | Result | |---|---| | `multi_device_test.py` | 2 passed, 18 skipped (3.87s) | | `core_test.py` | 480 passed (40.04s) | | `util_test.py` | 19 passed, 6 subtests passed (0.87s) | | `scipy_stats_test.py` | 982 passed (282.69s) | The `multi_device_test.py` numbers are the expected consequence of restoring isolation. On the same file **before** the fix, [job 89307813608](https://github.com/ROCm/TheRock/actions/runs/30032481350/job/89307813608) ran 19 passed / 1 failed, the failure being the cross-tenant OOM because the job could see 8 GPUs. With one GPU visible, 18 of those 20 tests correctly skip as requiring multiple devices, and `test_lax_full_like_efficient` no longer OOMs. That skipped coverage is real and is what #6853 exists to restore, on a runner where multiple GPUs are actually allocated to us rather than borrowed from neighbours. ## Submission Checklist - [x] Look over the contributing guidelines at https://github.com/ROCm/TheRock/blob/main/CONTRIBUTING.md.
ScottTodd
left a comment
There was a problem hiding this comment.
Okay, it sounds like we don't have enough capacity to always require multi-GPU for all JAX tests, and there are related PRs that are moving JAX tests up from nightly builds to also CI builds.
I think we should have a script like https://github.com/ROCm/TheRock/blob/main/build_tools/github_actions/configure_pytorch_test_matrix.py for JAX that decides which jobs to run with which runners, choosing 1 GPU runners for "not multiaccelerator" tests when short testing is requested (e.g. on a pull request) and choosing multi-GPU runners for "multiaccelerator" tests when full testing is requested (e.g. once a week for the "nightly" trigger" or more often, always for the "prerelease" release type, etc.).
I don't think we should always use multi-GPU runners whenever they are available, that's going to put heavy pressure on runner queues without giving sufficient control over when such jobs are run.
| # SPDX-License-Identifier: MIT | ||
|
|
||
| """This file looks up the test-runs-on runner label for a given GPU family. | ||
| """This file looks up the runner label to run JAX tests on for a GPU family. |
There was a problem hiding this comment.
If this script is only used for JAX, it should be renamed. See what we have for PyTorch:
and JAX:
configure_jax_release_matrix.py- this file -->
configure_jax_test_matrix.py(ideally, following the same structure) orconfigure_jax_target_run.py(minimal change without refactoring the workflows)
There was a problem hiding this comment.
Both done. configure_target_run.py is now configure_jax_test_matrix.py, modelled on configure_pytorch_test_matrix.py: it pairs the not multiaccelerator tests with the family's 1-GPU runner and the multiaccelerator ones with its multi-GPU runner, and it decides how often (prerelease every time, nightly one day a week), --test-scope to override.
A family with no multi-GPU runner drops that job instead of sending it to a 1-GPU machine, where every test in it would skip and still report a pass.
9c05238 to
687bd9e
Compare
ed88f03 to
b87760f
Compare
|
@amd-shiraz the nightly JAX matrix is 15 cells (4 refs x 4 Python versions, minus 3.11 on 0.11.0); cc: @ScottTodd, @jayfurmanek |
ScottTodd
left a comment
There was a problem hiding this comment.
I don't expect I'll have time to serve as primary reviewer on these PRs. Will defer to Erman who can tag me in as needed.
|
https://github.com/ROCm/TheRock/actions/runs/31568065672 is the test for this PR |
There was a problem hiding this comment.
Please see my comments for initial review:
In general, I think it worth to add small flow/design diagram to the PR description that shows how release_type / test_scope map to the generated matrix, runners, and test_subset. I believe this will make much easier to understand and review.
This PR also needs to be reviewed by @amd-shiraz and/or @geomin12 for the final review.
| SCOPE_SHORT = "short" | ||
| SCOPE_FULL = "full" | ||
| SCOPE_AUTO = "auto" |
There was a problem hiding this comment.
We can add TEST prefix in here to give more information for the future as well as specific comment for like what do SHORT / FULL / AUTO mean?
There was a problem hiding this comment.
Done: they are TEST_SCOPE_SHORT / TEST_SCOPE_FULL / TEST_SCOPE_AUTO now, commented with what each selects. "short" runs the whole single-accelerator suite on the 1-GPU runner, "full" adds the multi-accelerator tests on the multi-GPU runner, and "auto" reads the release type. The comment also says the part that was easy to misread: a scope decides which runners a run takes, not which tests each one runs.
| SUBSET_ALL = "all" | ||
| SUBSET_MULTI = "multi" |
There was a problem hiding this comment.
Same here to add meaningful prefix. What do all vs multi mean?
There was a problem hiding this comment.
Done: TEST_SUBSET_ALL / TEST_SUBSET_MULTI, commented with the script behind each. "all" is ci/run_pytest_rocm.sh, which is the whole suite if there are multiple GPUs on a host, but is only the single-GPU test suite if there is only 1 GPU on the host, and "multi" is ci/run_pytest_rocm_multi.sh, the multi-accelerator tests alone.
run_jax_tests.py uses the same two names, so the workflow input, the matrix and the runner all read alike.
| include.append({"test_subset": SUBSET_ALL, "test_runs_on": single_runner}) | ||
| else: | ||
| print(f"No {platform} test runner for {target}, so no tests will run") | ||
|
|
There was a problem hiding this comment.
What if we missed single_runner in here? Both short and full appear to require the single-GPU all job, but currently short would disable testing entirely and full could run only the multi subset if a multi-GPU runner exists. This could make a missing/changed runner configuration silently reduce the test coverage. Shouldn't we raise an error in here instead of printing?
There was a problem hiding this comment.
An empty test-runs-on is a real configuration rather than a mistake. gfx90a on Windows has a build and no test hardware. So raising would fail the build job for every such family.
It is a ::warning:: annotation now instead of a bare print, so it lands in the run summary, and a new test covers the case: the matrix comes back empty and annotated rather than quietly multi-only.
| @@ -122,13 +129,19 @@ on: | |||
| description: Runner label to use. The selected runner should have a GPU supported by test_amdgpu_family | |||
| type: string | |||
| default: "linux-gfx942-1gpu-ccs-csp-ossci-rocm" | |||
There was a problem hiding this comment.
Should we guard against test_subset=multi being used with a single-GPU test_runs_on? Since inputs can be changed independently in workflow_dispatch, so selecting multi while leaving the default 1-GPU runner might result in the multi-accelerator tests being skipped while the job still passes.
There was a problem hiding this comment.
It is enforced already in ci/run_pytest_rocm_multi.sh exits non-zero when gpu_count <= 1 ("Multi-accelerator tests need more than one GPU"), so dispatching multi at a 1-GPU runner fails the job instead of skipping every test and passing.
On this side the input is now a choice of all / multi and its description says it fails unless test_runs_on is a multi-GPU runner.
| def today_utc() -> date: | ||
| """The day the run is happening, which the weekly rule below reads.""" | ||
| return datetime.now(timezone.utc).date() |
There was a problem hiding this comment.
From agent:
The PR defines Sunday UTC as the weekly multi-GPU day. But today is evaluated when configure_jax_test_matrix.py actually runs.
That means the same nightly workflow can produce a different matrix when rerun on a different day:
Original Sunday nightly:
auto + nightly + Sunday
→ full
→ all + multi
Rerun Monday:
auto + nightly + Monday
→ short
→ all only
The unit tests verify Sunday versus Tuesday, but they don't address reruns preserving the original scheduled cadence.
There was a problem hiding this comment.
Fixed in 854ae9a: the configure job reads the run's created_at from the API and passes it as --run-date, so the weekly rule reads the day the run was created instead of the day it happens to be evaluated. A re-run keeps created_at at the first attempt while run_started_at moves to the new one, so re-running a Sunday nightly on Monday now repeats the matrix it had, which is the case that matters when a job failed due to for example infrastructure issues. It needs actions: read, granted in this workflow and in the calling release workflow, and falls back to today if the token cannot read the run; a unit test covers a nightly with --run-date on a Sunday producing both jobs while the clock says Tuesday.
There was a problem hiding this comment.
This seems fairly complicated, see my other comments (#6753 (review)). Simpler would be to match pytorch:
TheRock/.github/workflows/multi_arch_build_portable_linux_pytorch_wheels.yml
Lines 561 to 570 in 35ed46c
| test_scope: | ||
| description: >- | ||
| "short" runs the suite on the 1-GPU runner, which is the | ||
| single-accelerator tests, "full" adds the multi-accelerator tests on | ||
| the multi-GPU runner, and "auto" picks from release_type. | ||
| type: string | ||
| default: "auto" |
There was a problem hiding this comment.
Minor naming question - short still runs the full single-GPU suite and only skips the multi-GPU subset, right? Would something like single / multi (or similar) make the distinction clearer? I initially read short as a reduced test selection.
There was a problem hiding this comment.
yes, short runs the whole single-accelerator suite and only drops the multi-GPU job, so the input description and the constants now say that a scope picks runners rather than narrowing the suite. The stacked #6753 removes the ambiguity entirely by replacing test_scope with test_size (small / medium / large), where only small is a reduced selection.
|
@erman-gurses thanks! all seven comments are addressed in Summary of the changes: the constants are |
|
@erman-gurses test run is below: |
|
The previous job failed due to setup and network speed timing out the whole job. https://github.com/ROCm/TheRock/actions/runs/31817753726 this is the new job |
erman-gurses
left a comment
There was a problem hiding this comment.
LGTM - Thanks addressing all the comments
b153cf6 to
00860be
Compare
|
newest build workflow: https://github.com/ROCm/TheRock/actions/runs/31985867454 |
## What breaks today Every JAX nightly test job fails before it runs a single test: Error: ci/run_pytest_rocm.sh has no section between '# Set up the generic test environment variables' and '# Run tests'. `run_jax_tests.py` evaluates the suite's environment so that the serial retry pass runs under the same settings as the run it is checking. It read that environment out of a marked section of `ci/run_pytest_rocm.sh`. ROCm/jax has since moved it into `ci/utilities/rocm_test_env.sh`, and every release branch from `rocm-jaxlib-v0.10.0` through `rocm-jaxlib-v0.11.0` now ships the file with no section left behind, so the lookup fails on all of them. ## The change Source `ci/utilities/rocm_test_env.sh` when the checkout has it, and fall back to the section when it does not, since an older `--jax-ref` is still valid. The file only exports, echoes and queries devices, so sourcing it runs nothing. Split out of #6853 so the nightly is unblocked without waiting on that stack. Solves #7320 ## Test plan - [x] `pytest build_tools/github_actions/tests/run_jax_tests_test.py` (77 passed) - [x] New coverage for the split layout, and the error now names both places to fix - [x] Nightly JAX test job gets past the environment step
The suite script runs the single-accelerator tests and then the multiaccelerator ones, so a job cannot take just the subset its runner has the GPUs for. Pass JAXCI_ROCM_TEST_SUBSET through as --test-subset. A jax ref from before that variable ignores it and runs everything, which would look like the subset had been covered, so asking for a subset such a ref does not read stops the run.
The suite splits in two by the "multiaccelerator" marker, and only that subset needs more than one GPU. Picking a multi-GPU runner whenever one exists therefore spent a scarce 8-GPU slot to run ~29k tests that fit on one GPU. Replace the runner lookup with a matrix that pairs each subset with the runner it needs: the single-accelerator tests on the family's 1-GPU runner, and, when full testing is asked for, the multi-accelerator tests on its multi-GPU runner. Release types that run per change get the first job alone, so a pull request no longer queues for 8 GPUs, and --test-scope lets a workflow put the full pair on its own cadence. A family with no multi-GPU runner drops that job rather than sending it to a 1-GPU runner, which would skip every test in it and still pass. The script is named for what it produces now, rather than after the generic configure_target_run.py it started from.
ROCm/jax split the multi-accelerator tests into ci/run_pytest_rocm_multi.sh rather than adding a variable that picks a subset, so --test-subset now says which script to run. A ref without that script cannot run the subset on its own, and saying so beats falling back to the whole suite on a runner that was taken for the subset. The environment the two scripts share moved to ci/utilities/rocm_test_env.sh, which is sourced when it is there. A ref from before the split is still read from the marked section of its one script, since the release branches take this one at a time.
The nightly JAX matrix is 15 build cells, so a multi-GPU job per cell is 105 jobs a week against a pool of 10 nodes whose queues are already full. The multi-accelerator subset does not change fast enough to be worth that. Let the matrix script decide how often, not only what: a prerelease takes that runner every time, a nightly takes it one day a week, and --test-scope still overrides both for anything that wants the pair on another cadence.
…mpty Review follow-up: prefix the constants, spell out that a scope picks runners rather than narrowing the suite, annotate a family with no test runner instead of printing past it, and offer the subset as a choice.
A rerun of a Sunday nightly on Monday configured itself for Monday and dropped the multi-accelerator job, so a run that failed on infrastructure could not be repeated as it was. The API keeps created_at at the first attempt while run_started_at moves, so the configure job reads that.
Installing the ROCm packages has taken over an hour on its own, so a 120 minute job budget cut the single-accelerator suite off mid-run. Give the job 240 and hold each subset to its own step budget instead.
00860be to
56dee38
Compare
|
Rebased onto main (which now carries #7387) and re-validated on the nightly packages the HUD runs against (10.1.0a20260818): https://github.com/ROCm/TheRock/actions/runs/32202408475 Where this stack overlapped #7387, the merged version of the environment lookup wins: Note that a dispatched run is |
|
Full-scope run on the same nightly packages, for the leg a dev/nightly dispatch does not take: https://github.com/ROCm/TheRock/actions/runs/32208281220 ( Its configure job selected both subsets, |
ScottTodd
left a comment
There was a problem hiding this comment.
No major concerns from me on this.
| run: | | ||
| # created_at stays at the first attempt while run_started_at moves, so | ||
| # a rerun the next day still gets the day it was scheduled for. Falling | ||
| # back to today keeps the run going if the token cannot read it. | ||
| created_at=$(gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" --jq .created_at || date -u +%FT%TZ) | ||
| python ./build_tools/github_actions/configure_jax_test_matrix.py \ | ||
| --target "${{ inputs.test_amdgpu_family }}" \ | ||
| --platform linux \ | ||
| --test-scope "${{ inputs.test_scope }}" \ | ||
| --release-type "${{ inputs.release_type }}" \ | ||
| --run-date "${created_at%%T*}" |
There was a problem hiding this comment.
Another pattern we could use here would be #1236 - have a single "schedule release" job run on schedule and freeze all dynamic, time-related inputs in that job, then have all other jobs spawned from that one use fixed values. Here we could even have multi_arch_release_linux.yml do the freeze, without needing a new "schedule release" job.
There was a problem hiding this comment.
I'd actually prefer to follow what PyTorch does for consistency/simplicity. The retriggering behavior isn't going to come up too often and we could solve for pytorch too:
TheRock/.github/workflows/multi_arch_build_portable_linux_pytorch_wheels.yml
Lines 561 to 570 in 35ed46c
There was a problem hiding this comment.
Done in 94b87db. i drropped the created_at lookup, the token, --run-date and the actions: read grant on this workflow and the release caller; the weekly day is the wall clock now, same as the PyTorch pipeline.
the rule and its Sunday/Tuesday tests stay in wants_multi_gpu(), so the workflow still only reads the matrix.
this does mean a nightly re-run onto another day loses that week's multi-accelerator run, so the configure job prints a ::notice:: naming the day and the test_size: large dispatch that runs those tests on demand, rather than skipping them quietly.
Review follow-up: reading the run creation date from the API cost a token, an actions: read grant on this workflow and its caller, and a fallback, to keep one case honest: re-running a whole Sunday nightly on a later day. Drop it and read the clock, which is how the PyTorch pipeline picks its weekly day. That case now loses the week of multi-accelerator coverage, so the configure job annotates a nightly that is off the day and names the dispatch that runs those tests anyway.
amd-shiraz
left a comment
There was a problem hiding this comment.
discussed offline on capacity side. lg to proceed for single + multi gpu gfx942 wise.
|
Validation on the nightly packages the HUD runs against (10.1.0a20260819): https://github.com/ROCm/TheRock/actions/runs/32307755867 It runs the configure job without the API call, the token or the |

Motivation
multiacceleratorpytest marker, and only that subset needs more than one GPU: roughly 855 tests against 29k. Sending the whole run to a multi-GPU runner spends a scarce 8-GPU slot on tests that fit on one.Technical Details
configure_target_run.pybecomesconfigure_jax_test_matrix.py, named for what it produces and modelled onconfigure_pytorch_test_matrix.py. It pairs the single-accelerator tests with the family'stest-runs-onand the multi-accelerator ones with itstest-runs-on-multi-gpu.--test-scope short|fulloverrides either, so a workflow or a person can ask for the pair on any day. The rule is unit-tested against fixed dates rather than the clock.test_scope: fulldispatch that runs the multi-accelerator tests anyway.run_jax_tests.py --test-subset all|multirunsci/run_pytest_rocm.shorci/run_pytest_rocm_multi.sh(ROCm/jax PRs [ROCm] Split the multi-accelerator tests into their own script jax#832, [ROCm] Split the multi-accelerator tests into their own script jax#833, [ROCm] Split the multi-accelerator tests into their own script jax#834, [ROCm] Split the multi-accelerator tests into their own script jax#835). Asking formultiagainst a checkout that has no such script is an error, on a dry run too, rather than a job that quietly runs everything on an 8-GPU machine.ci/utilities/rocm_test_env.sh, falling back to the marked section of the older single script, so both layouts work while the release branches move.How a run reaches its jobs
A scope decides which runners a run takes, not how many tests each one runs:
shortandfullboth run the whole single-accelerator suite.flowchart TD A["release_type + test_scope"] --> B{"test_scope"} B -->|short| S["scope = short"] B -->|full| F["scope = full"] B -->|auto| C{"release_type"} C -->|prerelease| F C -->|nightly| D{"Sunday, UTC?"} C -->|"ci, dev"| S D -->|yes| F D -->|no| S S --> J1["test_subset=all<br/>test-runs-on, 1 GPU<br/>ci/run_pytest_rocm.sh"] F --> J1 F --> J2["test_subset=multi<br/>test-runs-on-multi-gpu<br/>ci/run_pytest_rocm_multi.sh"]A family with no
test-runs-on-multi-gpudrops the second job, and one with neither label runs nothing; both are::warning::annotations on the configure job rather than silent.Test Plan
pre-commit, including actionlint on the workflows.build_tools/github_actions/tests.ROCm/jaxcheckout.Test Result
stage_reuse_decision_testx2,configure_multi_arch_ci_test,post_stage_upload_test) fail identically onmain.cigives one job onlinux-gfx942-1gpu-ccs-csp-ossci-rocm;nightlygives the same on a Tuesday and addslinux-gfx942-8gpu-ossci-rocmon a Sunday;prereleasegives both whatever day it is;--test-subset allexecsci/run_pytest_rocm.shand--test-subset multiexecsci/run_pytest_rocm_multi.sh.#6753 builds on this to add test sizes, so the single-GPU job can run a PR-sized selection.
Submission Checklist