Skip to content

Add RFC0014 for code coverage infrastructure in TheRock - #6967

Merged
endurthiabhilash merged 30 commits into
ROCm:mainfrom
reboss:users/jorobbin/code-cov-rfc
Sep 21, 2026
Merged

endurthiabhilash merged 30 commits into
ROCm:mainfrom
reboss:users/jorobbin/code-cov-rfc

Conversation

@reboss

@reboss reboss commented Jul 29, 2026 •

Copy link
Copy Markdown
Member

Proposes per-project coverage builds with isolation to prevent profraw contamination from upstream dependencies, maintaining separate coverage pipeline from pre-checkin testing.

#6572

@therock-pr-bot

therock-pr-bot Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass PR does not contain code files — Unit Test auto-passed
🔎 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 added the Not ready to Review PR has unresolved policy failures — reviews blocked label Jul 29, 2026
@therock-pr-bot

therock-pr-bot Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

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

@reboss
reboss force-pushed the users/jorobbin/code-cov-rfc branch from 9b63d52 to 805a2e8 Compare July 29, 2026 17:00
@ScottTodd
ScottTodd self-requested a review July 29, 2026 17:28

@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.

My main reservations here are about what the CI job graph and uploaded artifacts will look like if we need to rebuild each component project with different flags. Some metrics from experiments and graphs/diagrams of the proposed architecture could help in discussing that.

@malcolmroberts malcolmroberts 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.

There are some dangerous assumptions in this document.

@ScottTodd
ScottTodd self-requested a review August 11, 2026 17:19

@malcolmroberts malcolmroberts 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.

Some discussion left on this.

@reboss
reboss force-pushed the users/jorobbin/code-cov-rfc branch from 69ea204 to 5e395bd Compare August 20, 2026 18:02
@malcolmroberts
malcolmroberts self-requested a review August 20, 2026 21:09

@malcolmroberts malcolmroberts 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 for the edits!

I think that this is workable now. I do feel like we need phased implementation to demonstrate that we have the infrastructure available (eg multi-gpu, multi-arch, mocked upstream dependencies) before things are gating.

@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.

Generally LGTM, but I'd like to see more focus in the implementation/rollout plan on the standard ordering from low frequency to high frequency workflow runs:

  1. on-demand (workflow_dispatch)
  2. nightly (schedule)
  3. push
  4. pull_request

Until we have concrete data on how long these jobs take to run it's hard to commit to running them on every pull request.

@reboss
reboss force-pushed the users/jorobbin/code-cov-rfc branch from 8da4ee1 to 13c218e Compare August 26, 2026 18:05
@jainprad jainprad mentioned this pull request Sep 4, 2026
1 task done
@therock-pr-bot

Copy link
Copy Markdown

Pre-commit check failed

⛔ pre-commit failed

Please run locally:

  • python -m pip install pre-commit
  • pre-commit install
  • pre-commit run --all-files --show-diff-on-failure

This repo uses .pre-commit-config.yaml.

@reboss reboss mentioned this pull request Sep 14, 2026
1 task done
Proposes per-project coverage builds with isolation to prevent profraw
contamination from upstream dependencies, maintaining separate coverage
pipeline from pre-checkin testing.
Emphasize that coverage in one component doesn't affect coverage in
downstream components, balancing the upstream contamination argument.
Add detail that -object flag doesn't accept wildcards (test_*), requiring
explicit expansion. Propose declarative approach with standard test naming
convention as an open discussion topic.
Focus RFC on design description rather than step-by-step process.
Conform to existing RFC format in repo.
Explain how script detects changed projects, handles multi-component PRs,
uses whitelist, and outputs per-project coverage metadata with pinned builds.
Explain schema fields (llvm_profile_file, ignore-filename-regex, test_names),
how they can be calculated declaratively, mixed library type handling, and
error handling when profraw files are missing.
Note that codecov.io is already configured in Math CI, and specific
provider choice/configuration is outside scope of this RFC.
Note single-architecture scope, per-project node allocation, and that
specific sizing/timing metrics are open discussion topics.
Coverage test failures block PRs like any other test failure.
Component owners can disable flaky tests.
Consolidated all detail additions from today's work session.
Address PR feedback about architecture-specific code coverage needs.
Define 5-phase rollout from single default arch to intelligent multi-arch
testing with change detection and report aggregation.
Separate three distinct specialized coverage scenarios:
- Multi-architecture: different GPU architectures (gfx90a vs gfx942)
- Multi-GPU: code requiring multiple GPUs
- Mock-based: error handling paths needing upstream error injection

Mock coverage can integrate with default arch; multi-GPU requires
separate detection and node allocation.
Explain four approaches for passing coverage flags from TheRock to
subprojects. Recommend list-based options (3/4) for CI integration
since they accept case-insensitive project names and TheRock handles
conversion internally, removing formatting burden from callers.
The old script has been replaced by post_stage_upload.py for multi-arch CI.
Add -coverage suffix to coverage artifacts to prevent confusion with
regular builds, similar to -asan suffix for ASAN builds.
- Add coverage aggregation job that merges profraw from all test shards
- Test shards upload profraw artifacts, final node aggregates and reports
- Update node allocation to reflect multi-stage builds and test sharding
- Coverage builds can leverage multi-arch CI pipeline with staged builds
Code coverage depends on amd-llvm's profiling implementation. A change
in 7.14 broke coverage generation across all projects. Require smoke
tests to gatekeep amd-llvm changes before merge.
Use consistent matrix.shard variable reference instead of SHARD_INDEX placeholder
in artifact naming documentation.
Nightly runs follow phased approach:
- Phase 1: Full coverage on default architecture
- Phase 2: Change-based component selection
- Phase 3: Multi-architecture expansion

Nightly uses hybrid artifacts:
- Single instrumented stack build (all components)
- Separate test jobs per component
- Each test pulls: instrumented-under-test + non-instrumented-dependencies
- Maintains per-project isolation while amortizing build cost

Added coverage-for-all flags:
- THEROCK_COVERAGE_ROCM_LIBRARIES_ALL
- THEROCK_COVERAGE_ROCM_SYSTEMS_ALL
- THEROCK_COVERAGE_ALL

PR coverage remains unchanged: only instrument changed projects.
Nightly coverage builds instrument entire stack but test components separately.
Each test job fetches:
- Instrumented component from coverage build (-coverage suffix)
- Non-instrumented dependencies from regular nightly build

Uses artifact_manager.py with:
- Target family suffix: gfx942-coverage vs gfx942
- --artifact-names / --exclude-artifact-names for selective fetch

PR coverage doesn't need this - dependencies naturally non-instrumented.
… questions

BuildTopology defines grouped artifacts (blas, prim) but coverage requires
per-project isolation (rocblas, hipblaslt, hiprand, rocrand, etc.).

Options: per-project artifacts, component filtering, or parallel system.

Removed answered questions:
- Nightly frequency (addressed: phased rollout)
- Coverage thresholds (component-level decision)
- Test naming (declarative discovery handles this)
- Artifact retention (standard ops concern)
- Report aggregation dashboard (out of scope)
- Multi-arch nightly cadence (addressed in Phase 3)
Two viable nightly coverage architectures:

Option A: Extend regular nightly (same run-id)
- Both regular + coverage builds in single nightly run
- Suffix REQUIRED for same-directory artifact differentiation
- Pros: guaranteed consistency, simpler coordination, no baseline tracking
- Cons: longer runtime, resource contention, coupled execution

Option B: Separate workflow (different run-id)
- Independent coverage workflow references regular nightly baseline
- Suffix recommended but technically optional (different S3 dirs)
- Pros: independent execution, flexible scheduling, isolated failures
- Cons: baseline coordination needed, potential inconsistency

Phased roadmap:
- Phase 1: Option B1 (manual baseline_run_id input)
- Phase 2: Option B2/B3 (automated via GitHub API or orchestrator)
- Phase 3: Option A (merge with regular nightly if beneficial)

PR coverage: Follows ASAN pattern (separate workflow, no suffix needed)

Addresses PR comment about why ASAN doesn't use artifact suffixes.
Added detailed workflow structure showing how downstream trigger passes
baseline_run_id automatically. Documents adaptation to nightly instability
(coverage runs even when regular nightly tests fail) and trade-offs vs
Options A and B.
…tegy

Nightly coverage no longer needs -coverage suffix since Option C uses
downstream trigger with separate run IDs. Documented multi-step extraction:
fetch all non-instrumented artifacts, then fetch grouped instrumented
component, extract only specific project files (lib/dev/test), overwrite
non-instrumented version. Works with BUILD_TOPOLOGY grouped artifacts while
achieving per-project instrumentation isolation.
Flag has been default-enabled for months and is now retired. Removed from
amd-llvm requirements and coverage build example.
Status: draft → accepted
Discussion: in progress → complete
@reboss
reboss force-pushed the users/jorobbin/code-cov-rfc branch from 0aff662 to cb2f58e Compare September 14, 2026 17:11
@therock-pr-bot therock-pr-bot Bot removed the Not ready to Review PR has unresolved policy failures — reviews blocked label Sep 14, 2026
@reboss reboss changed the title Add RFC0013 for code coverage infrastructure in TheRock Add RFC0014 for code coverage infrastructure in TheRock Sep 21, 2026

### Problematic: Header-Only Static Libraries

Some components are header-only static libraries (e.g., rocPRIM, hipCUB) and do not produce a simple `.so` file for `llvm-cov show -object <lib>.so`.

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.

Suggested change
Some components are header-only static libraries (e.g., rocPRIM, hipCUB) and do not produce a simple `.so` file for `llvm-cov show -object <lib>.so`.
Some components are header-only libraries (e.g., rocPRIM, hipCUB) and do not produce a simple `.so` file for `llvm-cov show -object <lib>.so`.

not sure if static is needed here

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think the use of static is appropriate. It suggests that they are .a static headers, and not .so dynamically linked headers

@reboss reboss Sep 21, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Suggested change
Some components are header-only static libraries (e.g., rocPRIM, hipCUB) and do not produce a simple `.so` file for `llvm-cov show -object <lib>.so`.
Some components are header-only static libraries (e.g., rocPRIM, hipCUB) that produce `.a` files, and do not produce a simple `.so` file for `llvm-cov show -object <lib>.so`.

Would that be more clear?

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.

I don't think there is even .a files? Maybe just ask @stanleytsang-amd

@endurthiabhilash
endurthiabhilash merged commit 073282b into ROCm:main Sep 21, 2026
21 checks passed
@github-project-automation github-project-automation Bot moved this from TODO to Done in TheRock Triage Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants