Skip to content

ci(hipblaslt): detect GEMM races in a nightly job - #14123

Merged
newling merged 54 commits into
ROCm:developfrom
newling:users/newling/AIHPBLAS-3605-random-gemm-nightly
Nov 5, 2026
Merged

newling merged 54 commits into
ROCm:developfrom
newling:users/newling/AIHPBLAS-3605-random-gemm-nightly

Conversation

@newling

@newling newling commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

hipBLASLt selects GEMM kernels according to matrix dimensions, numerical types, and operation options. The existing rocjitsu race checks run two small fixed workloads. This PR adds a nightly job that checks kernels reached through a repeatable distribution of GEMM inputs.

The workload samples inputs and lets hipBLASLt select a kernel normally. It complements the approaches that construct several inputs for a selected kernel in #13412 or one input per selected kernel in #13687; it does not force a solution index.

Technical Details

The job runs hipblaslt-bench through CPU emulation with rocjitsu's race detector enabled, so it requires no physical GPU. The detector reports races within one workgroup, such as a register or LDS value read before the required s_waitcnt or s_barrier; it does not see races between workgroups through global memory, such as in stream-K fixups or split-K reductions. See rocjitsu's race detector documentation for details.

A separate sampler draws M, N, and K independently from the multiples of 32 between 32 and 480, with one GEMM per input. It varies six numerical families (FP32, FP16, BF16, FP8, MXFP8, and MXFP4), supported transposes, alpha and beta, bias, and ReLU/GELU output operations. All use FP32 computation. A fixed seed makes the input sequence reproducible across worker counts and builds; normal library selection determines which kernels execute.

Each case must pass the benchmark's CPU-reference numerical checks and show the selected GEMM in the race detector's dispatch log. Races, numerical failures, emulator diagnostics, timeouts, and missing heuristic solutions fail the run. Cases are never replaced. Per-case inputs, commands, selected kernels, logs, and outcomes are retained for diagnosis and replay. The hipBLASLt guide records the sampling policy and local commands.

rocjitsu emulates one GPU target per run, and each target has its own kernels, so the nightly Multi-Arch workflow runs one job per entry in a target matrix. gfx950 (MI350 family) is the only entry for now; adding a target is a matrix entry plus a sampling profile for its number formats. Each job runs 100 sampled GEMMs with seed 0 and eight concurrent cases, using the library and benchmark artifacts from the same nightly run. With a fixed seed, every night checks the same inputs against the latest library, so this is a smoke test rather than a growing search. The existing reusable race-check workflow gains a workload input: smoke (the default) keeps the per-PR check exactly as before, through its unchanged driver and settings, and random-gemms runs this workload through a new driver that builds the same pinned rocjitsu revision, times each stage and records the detector revision. The workflow can also be dispatched manually against a completed run with any count and seed. Each emulated GEMM command is bounded at 900 seconds, so a hang is reported as a timeout while the remaining cases still run. Like the per-PR smoke check, the job is advisory while it settles in: a failure shows on the job and its reports are uploaded, but the nightly run still succeeds, and the job is not part of the required Multi-Arch summary. Nothing notifies on failure, so the guide names an owner who checks the nightly results.

The longer-term plan is a nightly sweep that runs every solution index in the library, with constructed problems instead of random samples. This PR is shaped so that sweep can be added rather than replace it: the sampled-GEMM runner lives in projects/hipblaslt/clients/scripts/rocjitsu, where the sweep runner is planned, shares its option names (--client, --reports, --workers, --library-dir, --target, --continue-on-failure, --rocjitsu-revision) and writes the same kind of summary.md and summary.json report. A new workload then needs a new value of the workload input and a branch in the GEMM driver, while the nightly job, artifact retrieval, rocjitsu build, timings, job summary and Component CI lane stay as they are.

The last hosted run of these 100 inputs, on an earlier revision of this PR, took 66 seconds on an AWS medium runner (5 seconds median and 14 seconds maximum per case). That run also spent about 5 minutes building rocjitsu with limited parallelism; the build now uses all runner cores, which brought it to about 30 seconds. The nightly job should take a few minutes in total.

Each run reports its timings so that changes are easy to follow from day to day. The job summary shows the duration and exit status of each stage (rocjitsu configure and build, the workload), the timeouts in force, and the run totals: cases passed, failed and without a solution, elapsed time, per-case minimum, median and maximum seconds, the five slowest cases, the number of distinct kernels reached, and a table of any failing cases with their reasons. The log prints each case's outcome with its total, conversion and bench seconds. The uploaded reports keep summary.json, cases.md, kernels.json (each kernel and the cases that ran it) and per-case inputs, commands, logs and results.

The runner's unit tests (eight tests, a few seconds) use a stand-in benchmark and emulator. A new Component CI lane, hipBLASLt rocjitsu scripts, runs every test in projects/hipblaslt/clients/scripts/rocjitsu on ubuntu-24.04 when that directory changes, following the existing component-ci-<name>.yml pattern. It rolls up to the required Component CI Summary, so a change that breaks these scripts cannot merge; other PRs skip the lane. The hipBLASLt TESTING.md gate table lists the lane, and its sanitizer table now lists the race detector and its scope.

Test Plan

Run the runner tests for deterministic sampling, concurrent execution, replay, result validation, and failure handling. Run the sampled workload locally under CPU emulation with the pinned rocjitsu revision, and replay deliberately faulty code objects to check failure reporting. Validate the scripts, workflows, and documentation links.

Test Result

The nightly job's driver ran end to end locally with the job's settings, on the gfx950 BLAS artifacts of the November 1 develop nightly fetched by TheRock's artifact script as the job does, with rocjitsu built from the pinned revision: all 100 cases passed with no missing solutions, reaching 56 distinct kernels in 45 seconds with eight workers (3.3 seconds median and 8.4 seconds maximum per case). All eight runner tests pass, including checks of the per-case timings, timeout reporting, distinct-kernel count and summary report, and the new Component CI lane passes on this PR. Earlier local runs of 1,000 inputs also passed every input and reached 149 kernels, and deliberately faulty code objects confirmed that races and numerical errors fail the run. Before per-PR race checks were disabled by #14683 (TheRock-Infra#1160), a hosted run of the 100-input workload on an earlier revision of this PR also passed. The component path check, formatting, workflow lint, and documentation checks pass. The scheduled nightly job will first execute after merge.

Submission Checklist

Risk level

Low (2/5): adds artifact retrieval, an emulator build, and a short recurring nightly CPU workload to CI. Product code and numerical tolerances are unchanged. The nightly job is advisory and gates nothing. On pull requests, only those that change projects/hipblaslt/clients/scripts/rocjitsu gain a short unit-test lane, which gates Component CI Summary. The per-PR smoke check is unchanged.

JIRA ID : AIHPBLAS-3605

@therock-pr-bot

therock-pr-bot Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

therock-pr-bot Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

@newling newling changed the title docs(hipblaslt): design a nightly random GEMM race test test(hipblaslt): add a CPU rocjitsu GEMM runner Oct 21, 2026

@newling newling left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments

@newling newling changed the title test(hipblaslt): add a CPU rocjitsu GEMM runner test(hipblaslt): add a CPU rocjitsu random GEMM runner Oct 21, 2026
@newling
newling force-pushed the users/newling/AIHPBLAS-3605-random-gemm-nightly branch from 102841a to 482f559 Compare October 21, 2026 19:52
@newling newling changed the title test(hipblaslt): add a CPU rocjitsu random GEMM runner test(hipblaslt): run CPU gfx950 random GEMMs per PR and nightly Oct 21, 2026

@newling newling left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments

@newling newling changed the title test(hipblaslt): run CPU gfx950 random GEMMs per PR and nightly test(hipblaslt): check random matrix multiplications without a GPU Oct 21, 2026

@newling newling left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments

@newling newling changed the title test(hipblaslt): check random matrix multiplications without a GPU ci(hipblaslt): detect GEMM races in a nightly job Oct 22, 2026
@newling newling removed the ci:docs-only Docs only changes label Oct 22, 2026
@newling
newling force-pushed the users/newling/AIHPBLAS-3605-random-gemm-nightly branch from 6e050bc to 01cc965 Compare October 26, 2026 15:30
@codecov

codecov Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

❌ Your project check has failed because the head coverage (70.08%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##           develop   #14123       +/-   ##
============================================
- Coverage    77.71%   70.08%    -7.63%     
============================================
  Files         2904       67     -2837     
  Lines       491016    22641   -468375     
  Branches     74425     3541    -70884     
============================================
- Hits        381556    15866   -365690     
+ Misses       84467     5276    -79191     
+ Partials     24993     1499    -23494     
Flag Coverage Δ
TensileLite-CPP ?
TensileLite-Unit ?
hipBLAS ?
hipBLASLt 70.08% <ø> (+0.03%) ⬆️
hipCUB ?
hipDNN ?
hipFFT ?
hipRAND ?
hipSOLVER ?
hipSPARSE ?
rocBLAS ?
rocFFT ?
rocRAND ?
rocSOLVER ?
rocSPARSE ?
rocThrust ?
see 2839 files with indirect coverage changes
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@newling
newling force-pushed the users/newling/AIHPBLAS-3605-random-gemm-nightly branch 2 times, most recently from fb8f7d6 to 7f4a6b7 Compare October 29, 2026 21:51
@newling
newling marked this pull request as ready for review October 30, 2026 04:43
@newling
newling requested a review from tony-davis October 30, 2026 04:43
@newling
newling requested review from a team as code owners October 30, 2026 04:43
newling and others added 25 commits November 4, 2026 15:18
The smoke and random GEMM race checks used different rocm-systems revisions. Use the newer 6f5d9658a4b1 revision for both and keep the pin in the reusable workflow so callers cannot diverge.
Raise RACE_TIMEOUT_SECONDS to 10000 so slow emulated GEMMs are not cut off. The 75-minute step timeout still bounds the workload and leaves time to upload reports.
TheRock's configure step reports run_all_tests for any unclassified change, such as an unrelated .github edit, and the race checks also ran for shared components whose changes cannot alter the checked kernels. Select the PR race checks from the changed files instead: hipBLASLt and the race-check scripts and workflow, excluding documentation. The test:hipblaslt label still forces a run.
Limiting the rocjitsu build to the GEMM worker count made it take 280 seconds instead of about 32 on the race-check runners. Restore Ninja's default parallelism; the workload still uses RANDOM_GEMM_THREADS concurrent GEMMs.
Per-PR race checks are disabled on develop until artifact setup is
reliable (ROCm/TheRock-Infra#1160). Drop the per-PR 100-case workload, its
changed-file trigger and the smoke-job runner change, leaving develop's
per-PR smoke job as it is. The 1,000-case nightly job and the per-PR runner
unit tests remain.
The runner unit tests ran on every pull request before Multi-Arch CI
decided whether to run, and gated its required summary. Remove the job
so this PR adds no per-PR work, and document running the tests locally.
Run the runner unit tests in the reusable race-check workflow, before
building rocjitsu, so the nightly job tests the runner and the per-PR
smoke check will too once it is re-enabled. Describe the workflow in
terms of the build under test rather than a pull request.
Record conversion, bench and total seconds for every sampled GEMM in
result.json and the log, and name timeouts as timeouts instead of exit
status 124. summary.json adds per-case min/median/max/total seconds,
the five slowest cases, the per-command timeout and the number of
distinct kernels; kernels.json maps each kernel to its cases. The runner
writes summary.md, which the workflow adds to the job summary together
with the driver stage timings and timeouts.
Run 100 fixed-seed cases as a nightly smoke test instead of 1,000. The
same inputs are checked against the latest library every night.
Run the sampler and runner unit tests in a Component CI lane on
ubuntu-24.04 when those scripts or their tests change, so a break is
caught before merge instead of first appearing in the advisory nightly.
The lane rolls up to the required Component CI Summary. Remove the
duplicate step from the race-check job, and document the lane in the
guide and TESTING.md.
A 10000 s bound let one hung command consume the whole 75-minute step:
a hung smoke bench prevented the TensileLite check, and a hung sampled
GEMM left no result. Hosted cases take seconds, so 900 s still only
catches hangs, which are now reported as timeouts.
List the detector in the sanitizer table and in the nightly bullet: it
reports races within one workgroup (register or LDS reads before the
required s_waitcnt or s_barrier), not races between workgroups through
global memory. Narrow the TSAN row to host-side races.
Prepare the nightly GEMM race check for the planned sweep of every
solution index while keeping the sampled workload self-contained:

- Move the sampler, runner and tests to
  projects/hipblaslt/clients/scripts/rocjitsu, next to the planned sweep
  runner, and give shared runner options the sweep runner's names
  (--client, --reports, --workers, --library-dir, --target,
  --continue-on-failure, --rocjitsu-revision).
- Select the workload with a workflow input (smoke or random-gemms) and
  run GEMM workloads through a new driver that builds rocjitsu, times
  each stage and records the detector revision. Leave the per-PR smoke
  driver and its settings as on develop, since that check is disabled.
- Name the Component CI lane after the scripts directory, so it covers
  any runner added there.
rocjitsu emulates one GPU target per run, and each target has its own
kernels, so the nightly check runs once per target. Structure it that
way, with gfx950 as the only target for now:

- The nightly caller is a matrix over artifact families and targets.
- The GEMM driver takes the target from AMDGPU_TARGETS and selects that
  target's emulator profile.
- The sampler has a profile per target, holding its number formats,
  sampling-policy version and emulator target ID; the runner requires
  --target and accepts targets that have a profile.
- Manual dispatch takes the artifact family and target as inputs, so the
  workflow no longer falls back to gfx950.
Keep continue-on-error only for the per-PR smoke check. The nightly and
manually dispatched GEMM workloads gate nothing, so a race, numerical
failure or timeout should fail that run instead of appearing green.

Also drop --run-github-repo from the artifact fetch; TheRock defaults it
to GITHUB_REPOSITORY, which is this repository for every caller. Move the
timeout comment next to the setting it describes.
Restore continue-on-error for every workload, as on develop. A GEMM race-check failure shows on its job but does not fail the nightly run while the check settles in; the existing TODO marks where to make it a hard failure once it is reliably green.
@newling
newling force-pushed the users/newling/AIHPBLAS-3605-random-gemm-nightly branch from 06f071b to 3c68baf Compare November 4, 2026 23:31
@newling
newling merged commit c66ce75 into ROCm:develop Nov 5, 2026
624 of 631 checks passed
newling added a commit that referenced this pull request Nov 7, 2026
## Motivation

The nightly hipBLASLt race job builds rocjitsu from source before
running sampled GEMMs under CPU emulation. The first scheduled run after
#14123 merged stopped at compiler lookup, before executing any GEMM. The
compiler artifacts were downloaded, but the new driver never added their
directories to its environment. See the [failed nightly
job](https://github.com/ROCm/rocm-libraries/actions/runs/42178825172/job/127816500047).

## Technical Details

Add the fetched ROCm compiler directories to `PATH` and its runtime
directories to `LD_LIBRARY_PATH`, preserving inherited entries. Include
both flat and host-specific LLVM runtime layouts so the build and
benchmark can find their shared libraries. Export the ROCm root for
child processes.

Add a driver regression to the existing CPU component lane and trigger
that lane when the shell driver changes. Its sparse checkout now
includes the driver.

## Test Plan

Run the component's runner and driver tests, reproduce compiler lookup
failure with the unpatched driver, and replay the nightly driver against
matching gfx950 artifacts. Check shell syntax, workflow lint and root
formatting checks.

## Test Result

All nine unit tests pass. Both runtime-layout regression cases fail at
compiler lookup without the fix. With a restricted initial environment,
the fixed driver builds rocjitsu and validates all 100 seed-0 gfx950
GEMMs from retained run-41962738798 artifacts, reaching 56 kernels
without races or numerical failures in 45.0 seconds. Shell, workflow,
formatting and Python lint checks pass. Hosted validation of this change
remains to be run.

## Submission Checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/TheRock/blob/main/GOVERNANCE.md#pull-requests.

## Risk level

Low (2/5): repairs the nightly driver's toolchain and runtime lookup and
adds CPU regression coverage.

JIRA ID : AIHPBLAS-3605
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants