Skip to content

ci(hrr): add the HRR CI workflow - #13256

Open
danielbolsson wants to merge 116 commits into
developfrom
users/danielbolsson/hrr-ci-workflow
Open

danielbolsson wants to merge 116 commits into
developfrom
users/danielbolsson/hrr-ci-workflow

Conversation

@danielbolsson

@danielbolsson danielbolsson commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

HRR CI checks the HIP Record and Replay code generator, its host-only unit tests on Linux and Windows, and its capture/replay integration suite. The suite policy stays in projects/hrr. By default the integration suite runs under rocJitsu (emulation/rocjitsu) on a CPU runner. Real GPU runners are a manual choice.

Technical Details

  • .github/workflows/hrr-ci.yml is the entry point. Triggers: pull requests, pushes to develop, a nightly schedule, and workflow_dispatch (families, backend, ignore_test_config). backend is simulator or gpu and defaults to simulator.
    • Pull requests and pushes go through a paths filter: the union of the ci.yaml paths.cpu, paths.capture and paths.suite lists, less paths.excluded. A pull request that touches no HRR path starts no run. test_hrr_ci_configure.py fails when the filter and ci.yaml disagree. So HRR CI Summary must not become a required check while the filter is in place.
    • configure runs hrr_ci_configure.py, which applies projects/hrr/tests/config/ci.yaml to the changed files (renames included) and the labels:
      • the CPU checks when HRR paths change;
      • the capture/replay suite when a capture path or paths.suite changes, the PR has the ci:hrr-capture label (and touches an HRR path), nightly, and on dispatch. Fork PRs, and PRs whose head repository is gone, get the CPU checks and the rocJitsu jobs, not the real-GPU backend (the build job runs for them too). Adding any other label cancels nothing and runs no HRR job;
      • workflow_dispatch uses its backend input. Any other event uses backend.default (simulator), unless the event is listed in backend.gpu.triggers (empty on develop);
      • the simulator jobs are simulator.default_families: seven rocJitsu families (gfx90a, gfx94x, gfx950, gfx110x, gfx1151, gfx120x, gfx125x), each with its emulation/rocjitsu/configs/*.json, on ubuntu-24.04 inside TheRock's no_rocm test image, in local mode (rocjitsu --launcher). gfx103x, gfx1150 and gfx1153 have no rocJitsu config. The dispatch families input replaces the list. ci:gfx... labels are TheRock's and do not select an HRR family. A simulator family with no config fails configure. gfx125x stays enabled: false for real GPUs; the simulator list does not consult that flag;
      • the GPU backend runs the enabled families on TheRock runner labels. Only gfx94x is enabled. gfx950 takes the 8-GPU runner only on schedule. A draft that should hit hardware on every push sets backend.gpu.triggers: [pull_request] and families.<key>.enabled: true in that branch's ci.yaml;
      • configure fails unless targets.arch of integration.yaml covers every GPU target of every family in ci.yaml.
    • api-checks ("API IDs and workloads") runs hrr_check_sources.py: API-ID compatibility with the base commit, and the API matrix.
    • scripts lints the suite configs, which must agree on targets.arch, and runs the HRR helper-script tests.
    • unit builds and runs the host-only unit suite on Ubuntu and Windows against the ROCm SDK version pinned in ci.yaml, with this tree's HIP headers. Those binaries do not run under rocJitsu.
    • gpu calls hrr-gpu.yml.
    • HRR CI Summary writes one table of every platform and every ci.yaml family, with the reason for each family that did not run (hrr_ci_report.py). The verdict comes from toJSON(needs) and the JUnit files, not from the jobs API. It fails when configure fails, when a needed job is failure or cancelled, when a job configure selected was skipped, when a listed job is still running, or when a JUnit file has a failed case. In a label run that runs no HRR job it reports the newest other run on the PR head that has a verdict, and fails unless that run passed, so a label cannot turn a failing HRR CI green.
  • .github/workflows/hrr-gpu.yml (workflow_call):
  • TheRock refs in the HRR workflows match the pin in therock-multi-arch-ci.yml.
  • .github/skip-ci-config.toml lists the HRR workflows and projects/hrr/tests, tools and skills, which TheRock never reads, so a pull request that changes only those skips TheRock CI without ci:skip. Any other projects/hrr change builds every TheRock stage until the TheRock pin includes TheRock #8965, which builds hrr-playback in compiler-runtime on Linux. This PR itself still needs ci:skip: it changes skip-ci-config.toml, which TheRock does not classify.
  • The local Docker runner (hrr_dev.py and projects/hrr/tests/docker/Dockerfile) is not in this pull request. It is on users/danielbolsson/hrr-local-dev-20c1, which changes only projects/hrr.

The build job and hrr_capture_build.py are still interim. ROCm/TheRock#8965 adds a HIP_HRR_CAPTURE flag and an hrr-capture build variant. The test matrix stays in projects/hrr.

Issue Tracking

JIRA ID: AIRUNTIME-2871

Test Plan

  • python3 -m unittest for test_hrr_ci_configure.py, test_hrr_capture_build.py, and test_run_catch2.py. These do not start Docker or use a GPU.
  • pytest projects/hrr/tests/scripts projects/hrr/tools/tests at every commit of this branch.
  • The new skip-ci-config.toml patterns, checked with TheRock's load_skip_ci_patterns_for_external_repo at the pinned ref.
  • HRR CI on this pull request: configure selects the seven rocJitsu families, the capture build compiles, and the simulator jobs run in the test image with no symlink step. The summary fails if any of those jobs or cases fail.
  • A workflow_dispatch with backend=gpu and a chosen families list, for a real GPU run.

Test Result

The HRR CI run on the head of this branch is the test. Local unit tests: python3 -m unittest for test_hrr_ci_configure, test_hrr_ci_report, test_hrr_ci_schedule and test_hrr_capture_build pass. The Docker helper tests live on users/danielbolsson/hrr-local-dev-20c1.

Other local results:

  • pytest: 336 passed at the head.
  • Skip patterns: the HRR workflows and tests, tools and skills files are skippable. playback/, include/, CMakeLists.txt, CLR's HRR sources and therock-multi-arch-ci.yml are not.

Not run here: a real GPU job. An earlier revision of this PR ran the integration suite on real GPUs (gfx90a, gfx94x, gfx950, gfx110x, gfx1151, gfx120x). That run predates the simulator default.

Submission Checklist

@danielbolsson
danielbolsson requested a review from a team as a code owner October 12, 2026 07:42
@github-actions github-actions Bot added the github actions Pull requests that update GitHub Actions code label Oct 12, 2026
Copilot AI balanced review requested due to automatic review settings October 12, 2026 08:35
@therock-pr-bot

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

Copy link
Copy Markdown

✅ All Policy Checks Passed

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —

🎉 All policy checks passed!

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

🙋 Wish to Override Policy?

This comment was marked as resolved.

@danielbolsson danielbolsson self-assigned this Oct 12, 2026

@andraghetti andraghetti left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks Daniel. Splitting this out of #12778 makes sense.

I went through the diff against the version I reviewed there (447a92e). The ROCr build looks right to me. CLR picks up the in-tree install, rocr-install/lib is in the artifact, and it sits before the SDK on LD_LIBRARY_PATH. I checked the artifact: amdhip64 and the test binary both resolve one libhsa-runtime64.so.1, so we never end up with two copies. The step costs about 10 s cold.

The run on this head is green: 6 families ran the suite, including both containers, and 3 timed out in the queue as designed. The fixes for Copilot's points look good.

Could you update the description? It says the workflow is unchanged from #12778 and that CI cannot run before #12778 merges. CI already ran here (run 38233722764), and the ROCr build plus the review fixes are new since my review.

One question inline, not blocking for me. Approving. My approval does not cover .github/ as code owner, so this still needs someone from rocm-systems-reviewers.

Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Base automatically changed from users/danielbolsson/hrr-ci to develop October 12, 2026 10:52
danielbolsson and others added 2 commits October 12, 2026 12:52
Split out of the HRR test/tooling PR so CODEOWNERS routes .github/ and
projects/hrr to their own reviewers. Restores the workflow byte-for-byte.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Daniel Olsson <daniel.olsson@amd.com>
- Gate: list previous_filename for renamed files so moving a file out of an
  HRR path still counts as an HRR change.
- Dispatcher: select the dispatched job by its real name, "Integration GPU",
  so job status and conclusion are read instead of falling back to the run.
- GPU probe: skip only for hipErrorNoDevice (100) or a zero device count; any
  other hipGetDeviceCount status continues to the suite and fails visibly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Daniel Olsson <daniel.olsson@amd.com>
danielbolsson added a commit that referenced this pull request Oct 12, 2026
JIRA ID : AIRUNTIME-2871

The workflow (`.github/workflows/hrr-ci.yml`) moved to #13256.

## Motivation

HRR has no CI on `develop`. This adds the test and tooling support under
`projects/hrr` that HRR CI runs: the config, the suite runners, and the
playback and generated-source changes they cover. The workflow itself is
in #13256.

## Technical Details

- The HRR CI workflow (#13256) runs a host-only unit suite (Ubuntu and
Windows), one multi-arch build of CLR with the capture shims plus
`projects/hrr`, and an integration job per GPU family that has a runner.
`gfx1250` is in the fat binary; its job stays disabled until that runner
is healthy. Pull requests always start the workflow. The gate job skips
the suites when no HRR path changed (`projects/hrr/**` except `skills/`,
`projects/clr/hipamd/src/hrr/**`, the HIP API trace and runtime headers,
this workflow, and the runner-config action), so `HRR CI Summary` still
reports and can be a required check. Pushes to `develop` that touch
those paths also run, which seeds the ccache pull requests restore; only
`develop` saves it.
- One fat binary covers every `HRR_ARCHS` entry. Which cases run is
`projects/hrr/tests/config/integration.yaml` and `unit.yaml`: each file
lists every case the binary registers, and the integration selector is
`[hrr]~[direct]`. `hrr_test_config.py` checks that listing in CI.
`run_catch2.py` and `summarize_junit.py` run the suites and publish the
table.
- Integration jobs install the SDK version the build used. The CLR build
passes `-DHIP_HRR_CAPTURE_ENABLED`, which compiles capture into
`amdhip64`. The integration binary defines `HRR_HAVE_HSA`.
- A family whose runner has no visible ROCm device skips the suite and
stays green. A family whose GPU job is still queued after 30 minutes
does the same. A failing test still fails the job. The GPU work is its
own workflow run, so that queue can be cancelled without cancelling the
pull request. `timeout-minutes` starts when a runner picks the job up.
- Spawned workloads re-exec `/proc/self/exe`, and `hrr-playback` is
resolved beside that binary. The path CMake bakes in sits on a `noexec`
mount in the container jobs, so executing it returns EACCES and the
suite reports exit 127.
- Regenerates the checked-in HRR API sources (`hrr_api_args.h`,
`hip_capture_generated.cpp`, `hip_playback_generated.cpp`) so the
codegen check matches this tree. The only `projects/clr` change is the
generated capture file.
- Ships the playback and test changes those suites cover: the API
playback matrix, no-op replay of an opaque handle that has no
translation, the archive-version bump for shifted compiler IDs, and HSA
access limited to CPU and GPU agents.

`Multi-Arch CI Summary` belongs to `therock-multi-arch-ci.yml` and is
unaffected. That workflow already builds HRR through the `hrr` entry in
`therock_matrix.py`.

## Test Plan

- `hrr_test_config.py lint` and the Python unittests for the config,
runner, summary, and schedule helper.
- HRR CI runs on #13256, which is stacked on this pull request.

## Test Result

This branch no longer carries the workflow, so HRR CI does not run on
this pull request; see #13256.

## Submission Checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/rocm-systems/blob/develop/CONTRIBUTING.md#pull-requests.

[AIRUNTIME-2871]:
https://amd-hub.atlassian.net/browse/AIRUNTIME-2871?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
@danielbolsson
danielbolsson force-pushed the users/danielbolsson/hrr-ci-workflow branch from 0f10bb1 to c9a77de Compare October 12, 2026 10:53
danielbolsson and others added 2 commits October 12, 2026 13:42
CLR returns hipErrorNoDevice when hsa_init fails, so probing through the
in-tree ROCr made a broken ROCr look like a runner without a GPU and skip
the suite green. Probe with the SDK's amdhip64 and ROCr; the suite still
runs against the in-tree ones and now fails if they do not initialise.
Also reword the SDK pin comment: it no longer protects ROCr.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Daniel Olsson <daniel.olsson@amd.com>
…n/hrr-ci-workflow

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Daniel Olsson <daniel.olsson@amd.com>

@marbre marbre left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's discuss offline if we should rather integrate into TheRock CI. Overall I feel, even if it is not integrated into TheRock, this needs to be split into separate workflows.

As you asked for DevOps feedback, allow me to point you to https://github.com/ROCm/TheRock/blob/main/docs/development/style_guides/github_actions_style_guide.md. The current PR does not follow best practices, especially as it does inline several scripts and has way to much logic embedded into the workflows.

Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved

@ScottTodd ScottTodd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Added a few high level comments. This generally looks difficult to maintain, overlaps with what some other workflows provide, and is would benefit from following github actions best practices.

I do think component-specific CI (in addition to TheRock CI) could be appropriate for HRR, but it would be easier to start from a thinner workflow (200 LOC) and add on features incrementally instead of doing this all as a single 1100+ LOC PR.

Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
Comment thread .github/workflows/hrr-ci.yml Resolved
The HRR workflow carried its path gate, generated-source checks, GPU
dispatch and summary as inline shell. Move each into a script under
.github/scripts with pytest tests, as the other rocm-systems CI scripts do:

- hrr_ci_configure.py decides whether the CPU checks and the GPU suite
  run, and on which GPU families. Families follow TheRock's trigger policy
  (amdgpu_family_matrix.py) and its ci:gfx... labels; ci:hrr-capture asks
  for the GPU suite on any pull request.
- hrr_check_sources.py checks the generated HRR sources, API-ID
  compatibility with the base commit, and the API-matrix expectations.
- hrr_capture_build.py builds an amdhip64 with HRR capture compiled in on
  top of the ROCm artifacts that rocm-systems' TheRock CI built for a recent
  develop commit, then builds the HRR suite against it. This is interim
  until TheRock offers a capture-enabled build variant.
- hrr_ci_report.py writes one summary of every HRR job and the
  per-platform, per-family results table.

Signed-off-by: Daniel Olsson <Daniel.Olsson@amd.com>
hrr-ci.yml now runs a configure job (hrr_ci_configure.py), the
generated-source, script and host unit jobs, calls hrr-gpu.yml with
workflow_call when the GPU suite should run, and ends with one HRR CI
Summary table across platforms and GPU families. It also runs nightly.

hrr-gpu.yml builds the capture-enabled amdhip64 and the HRR suite in
TheRock's build image from TheRock CI artifacts, then runs the suite per
GPU family in TheRock's test image with TheRock's container options. That
removes the self-dispatch and polling, the nightly-wheel and apt -dev
build dependencies, the ccache in the Actions cache, and the path
symlinks and LD_LIBRARY_PATH overrides on the GPU machines.

The unit job installs one pinned ROCm SDK version, and every checkout
disables persist-credentials.

Signed-off-by: Daniel Olsson <Daniel.Olsson@amd.com>
gen_hrr_api_args.py reads the Windows export list when it is imported,
so pytest stopped at collection without it.

Signed-off-by: Daniel Olsson <Daniel.Olsson@amd.com>
Git Bash's ${PWD} is an MSYS path that a native cmake cannot resolve, so
the Windows unit build fell back to the pinned SDK's older HIP headers.

Signed-off-by: Daniel Olsson <Daniel.Olsson@amd.com>
@danielbolsson

Copy link
Copy Markdown
Contributor Author

@andraghetti, thanks. 2e9cd5d moves the hipArray block (block 19) out of Unit_HRR_AllApis_Direct into Unit_HRR_AllApisArrays_Direct, with its own Unit_HRR_AllApisArraysRoundtrip (skipped where the device has no image support). The rocJitsu skip for #14612 now applies only to that case, so Unit_HRR_AllApisRoundtrip runs again on gfx90a, gfx110x, gfx1151 and gfx120x. I could not build or run the GPU suite in this environment; the HRR script tests (config validation) pass, so the new case needs CI to confirm.

@andraghetti andraghetti left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Gated on MI350 at 2e9cd5d: integration and hidden cases green; the CPU stage fails only on the stale header below.

The generated expectations header was stale after the hipArray block moved
into its own workload.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@andraghetti andraghetti left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Gated on MI350 at bf6d8ce: GREEN.

@amd-shiraz

Copy link
Copy Markdown
Contributor

@danielbolsson how much time is the new checks add to a ci run ?

@danielbolsson

Copy link
Copy Markdown
Contributor Author

@danielbolsson how much time is the new checks add to a ci run ?

From last run; the continuous time it took to run HRR CI was 29 minutes, but the total accumulated run time on CPU runners was 1h 3 min. We are not using any GPU runners.

The most expensive part is compiling of the rocjitsu emulator itself that takes 20 min. We currently need to do this because TheRock build does not provide it with the launcher we need. It is coming, and when it does we can remove this step from our CI. We currently also need to build CLR with HRR enabled which takes 7 minutes. When HRR is enabled again then we can use TheRock build of CLR.

…E-2871)

Drop the emulator skips for ExtMemcpyBatchRoundtrip, FailedBlobWrite_LeavesCaptureIncomplete,
Fork_ChildArchiveCompleteAfterParentFailure, Fork_ChildListsOnlyItsOwnUnreplayableApis,
MemcpyExtraRoundtrip and PinnedHostFork. Each passes under rocJitsu (origin/develop b96bbff)
on every arch its skip named, and natively on gfx950. ApiMatrix_T4 (gfx11*/gfx120*, gfx90a),
AllApisArraysRoundtrip, ApiMatrix_T1, CaptureCapabilities and VaPlacement_StoredPointer still fail
and keep their skips.
…ift (AIRUNTIME-2871)

develop's #14341 moved hipEventElapsedTime from the generated to the manual
replay class (GENERATED 205->204, MANUAL 102->103). Its observable class stays
REAL, so api_matrix.yaml and hrr_api_matrix_expectations.h do not change; only
the recorded baseline is refreshed.

develop's #14343 and #14346 added six hrr-handler-tests cases (HostUnregister
FailedCallKeepsBuffer and five SnapshotOrder cases); handler.yaml lists them
(43 -> 49, matching the binary). The case names come from the TEST_CASE
registrations, not a built binary; listing needs no GPU.
@danielbolsson
danielbolsson requested review from ScottTodd, amd-shiraz, geomin12 and marbre and removed request for ScottTodd, amd-shiraz, mangupta and marbre November 4, 2026 08:31
danielbolsson and others added 10 commits November 5, 2026 23:18
develop's #14350 added three hrr-handler-tests cases (52 compiled vs 49
listed), so the compiled-case-list check failed. The case set was checked
against the TEST_CASE names in the handler sources, not a built binary.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
hrr_test_config.py check on the merged tree reported 52 expected, 56 found.
The cases come from hrr_host_budget_test.cc and hrr_unregister_fail_test.cc.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Under the rocJitsu emulator on gfx125x, the parent process hangs in the
crash path. The watchdog kills it, so the test sees exit 137 instead of
139. Disable the case there until
#15217 is fixed.

The case list is unchanged, and the _Direct variant is not touched.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The merge with develop brings the six new Unit_HRR_HostBudget_* cases from
hrr_host_budget_test.cc, so hrr-handler-tests registers 62 cases against 56 in
handler.yaml. List the six, in sorted order. The case set was derived from the
TEST_CASE sources, not from a built binary.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The Build rocJitsu job compiled everything cold on every run, about 16
minutes. Install ccache, set it as the C and C++ compiler launcher, and
restore and save its directory with actions/cache (the SHA already used
in amdsmi-dme-ci.yml).

The cache holds only rocJitsu compile objects, in a directory under
RUNNER_TEMP. The ROCm install in the build job stays uncached because of
the librocm_kpack.so.0 failure. The key has the runner OS and arch, a
hash of the c++ and cc versions, and a hash of emulation/rocjitsu,
runtimes/api-headers and shared/machine-readable-isa; restore-keys fall
back to the compiler prefix. ccache hashes preprocessed source, so a
partial restore cannot give a stale object. The size limit is 500M and
the job prints ccache statistics at the end.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The host budget roundtrip tests hardcoded caps of 1, 3 and 5 MiB. Replay
charges every blob it loads, including the registered fat binary, and that
grows with the arch list the test binary is built for. The CI build for all
14 archs holds about 1.4 MB, so the 1 MiB cap was refused by the blob cache
before the allocation under test, and the 3 and 5 MiB caps left too little room.
Caps are now the archive's blob and code object bytes plus the allocation budget.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The CI hang on gfx125x (#15217) is the watchdog killing the parent while
Linux writes a 12.8 GiB core. PR_SET_DUMPABLE 0 avoids the dump and the
SIGSEGV is still raised, so the test's exit-code checks hold. Re-enable
Unit_HRR_CaptureCrashDuringFork on gfx125x.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:skip Skip all CI builds/tests for this PR github actions Pull requests that update GitHub Actions code organization: ROCm project: hrr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants