Skip to content

perf(hipdnn): speed up superbuild CI with parallel ctest and compiled reference executors - #14680

Merged
adickin-amd merged 20 commits into
developfrom
users/addickin/ref_executor_compile_once
Nov 3, 2026
Merged

adickin-amd merged 20 commits into
developfrom
users/addickin/ref_executor_compile_once

Conversation

@adickin-amd

@adickin-amd adickin-amd commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Shortens the hipDNN superbuild CI. Two changes: both lanes run ctest --parallel 16 (the larger saving), and the integration-tests / hip-kernel-provider test code stops instantiating the CPU/GPU reference executors in every test file (the smaller one). No product code changes; nothing under projects/hipdnn becomes compiled (the one edit there is a header-only equality fix).

JIRA ID : ALMIOPEN-3113

Risk Assessment

Risk 2. CI workflow plus test-support code only. The residual risk is a test that is not safe to run in parallel; I audited the registrations (temp dirs use tmp_path/unique names, shared-state tests are RUN_SERIAL/fixture-ordered) but only one parallel run exists so far (see Testing).

ASIC Coverage

Architecture-independent: host-side test code and a CI workflow. Passing PR CI is sufficient; no multi-arch sweep needed. Built and tested locally on gfx90a (MI250). GPU cases for SDPA/flash2 skip on gfx90a as on base.

Testing Summary

  • Parallel ctest and tier selection: this PR's own superbuild CI, run 41136095325 (head 0528e30, with current develop merged in), both lanes green. Linux: -L '^full$' 166/166 passed, second call 31/31. Windows: 249/249 and 31/31 (Windows runs 78 more tests than before because develop added the FlyDSL entries). hipdnn_golden_data_tests now runs only as its tier suites in the first call. Earlier runs of plain --parallel 16 (experiment PR ci(hipdnn): [DO NOT MERGE] superbuild timing experiment #14563 and earlier heads of this PR) also passed, so no parallel flakes in any run.
  • ctest filtering (review comment): the superbuild checkout did not include shared/ctest, whose TestCategories.cmake registers the YAML tier suites (*_quick_suite, *_full_suite, ...), so CI ran 183 / 189 plain unlabeled tests and -L '^full$' alone selected nothing ("No tests were found"). This PR now checks out shared/ctest: CI registers 238 (Linux) / 244 (Windows) entries, where the tiers repeat one gtest filter (for example miopen_plugin_tests and hip_kernel_provider_tests four times each), and hipdnn_golden_data_tests ran twice, as its tier suites and as an unlabeled raw test (fixed below). -L '^full$' runs each binary once (full is a superset); -LE '^(quick|standard|comprehensive|ffm-quick|full)$' runs the entries with no tier label (rocke_*, hkp-probe-*, shared_ctest_* and the gpu_ref entries). Both calls always run and the step fails if either does. All of the 171 entries that were registered before and are still registered run; the 12 plain provider/plugin entries that shared/ctest replaces are covered by their *_full_suite. Enabling it also registers the two shared_ctest_* tests, which configure a nested CMake project; they needed CMAKE_GENERATOR=Ninja (Linux; the runner has no make) and Python3_ROOT_DIR set to the superbuild venv (actions/setup-python exports its own Python3_ROOT_DIR, whose Python has no PyYAML).
  • Executor refactor: MI250 (gfx90a) Linux machine, preset hipdnn-providers-all + HIPDNN_ENABLE_SDPA, BUILD_CPP_GRAPH_TESTS, HIPDNN_ENABLE_KERNEL_INGESTOR, ENABLE_HIP_FLASH2_ENGINE. Per-suite pass/skip/fail base vs head:
    • hipdnn_test_sdk_tests: 2420/4/0 -> 2420/4/0
    • hipdnn_integration_tests_unit_tests: 1115/2/0 -> 1120/2/0 (only additions)
    • hip_kernel_provider_integration_tests: 36/72/0 -> 36/72/0
  • The new compiled hip-kernel-provider function ran 35 times during those 36 passing tests (gdb breakpoint count).
  • New TestGpuPlanRegistrySignatureKey fails when equality is mutated to compare only the variant index.
  • clang-tidy 20.1.0 on all 23 changed .cpp files: 0 findings. The build container has no clang-tidy, so the build ran with tidy off and tidy was a separate pass.
  • Test-name validation: hipdnn, hipdnn-integration-tests, miopen-provider clean. The hip-kernel-provider component reports 5 ...FP16... names in TestHipFlash2* that exist in develop (only visible with ENABLE_HIP_FLASH2_ENGINE=ON, default OFF); not touched here, not checked at base.

Testing Checklist

  • Build + test lanes on gfx90a - superbuild preset hipdnn-providers-all - Status: Passed
  • clang-tidy on changed files - wheel 20.1.0 - Status: Passed (0 findings)
  • Parallel ctest + full tier selection - this PR's superbuild CI (Linux and Windows) - Status: Passed
  • PR CI - remaining GitHub PR checks (2 multi-arch stage builds were still pending when this was written) - Status: Pending

Technical Changes

  • .github/workflows/hipdnn-superbuild-ci.yml: both lanes check out shared/ctest and run ctest --parallel 16 -L '^full$' followed by ctest --parallel 16 -LE '<tier labels>' (see Testing for why); the test step sets Python3_ROOT_DIR to the venv (both lanes) and CMAKE_GENERATOR=Ninja (Linux) for the nested shared_ctest_* configure.
  • dnn-providers/integration-tests/CMakeLists.txt: the YAML categorization block moves above the hipdnn_golden_data_tests registration. _add_test_target_internal() skips the raw add_test() only while DNN_PROVIDER_TEST_CATEGORY_YAMLS is already set, so the binary was also registered as an unlabeled raw test (about 2 s on Linux, 8 s on Windows). Without shared/ctest the raw test is still registered.
  • dnn-providers/hip-kernel-provider/src/CMakeLists.txt: hkp_reserve_census_shard(... FILES "${_toml}") for each FlyDSL engine and architecture. After fix(hip-kernel-provider): place shard test configs beside the build-tree census shard #14573 (shard TOML check) and feat(hip-kernel-provider): FlyDSL kernels: RMSNorm fwd/bwd + SDPA forward (RDNA, CDNA) #14111 (FlyDSL) merged, configure failed for any architecture with FlyDSL content ("the gfx1151 census shard names hipkernel_flydsl_rmsnorm_gfx1151.toml, but nothing places it beside the shard"); every superbuild Windows configure on develop failed from 21:15 UTC. Same call the gfx950 registration already makes. This PR carries the one-line fix because its CI runs against current develop.
  • PlanRegistrySignatureKey.hpp (test_sdk, stays header-only) and GpuPlanRegistrySignatureKey.hpp: equality compares index() then runs one std::visit (was a pairwise visit: 22x22 and 15x15 instantiations). Semantics unchanged.
  • ReferenceGraphExecutorFactory, CpuReferenceGraphExecutorAdapter and GpuReferenceGraphExecutor move from inline headers to pimpl + .cpp in dnn-providers/integration-tests; 12 plan tests and the chained SDPA test use the adapter instead of the raw test_sdk executor. ReferenceExecutorPool.cpp stays out of the unit-test target.
  • hip-kernel-provider harness: the single CPU-reference call goes through a compiled executeCpuReferenceGraph.
  • Tests: new TestGpuPlanRegistrySignatureKey; a real adapter case in TestErrorPaths (the old test never called the adapter and is renamed to say what it checks).

Measured effect

Before After
Linux ctest step 7.7-11.3 min 4.7 min (245 s + 37 s, two calls; this PR's CI, with more tests from develop)
Windows ctest step 14.1-19.7 min 7.4 min (349 s + 92 s, two calls; 249 tests incl. 56 FlyDSL entries added by develop)
Tidy of the 266 affected files, 64 jobs (MI250 Linux machine) 334.8 CPU-min, 539.7 s wall 285.6 CPU-min, 536.3 s wall

Be honest about the executor refactor: it cut tidy CPU on the files it touched by 28% (e.g. ReferenceExecutorPool.cpp 465 s -> 34 s) but only about 3% of the whole Linux tidy work, and wall time did not move because each of the three test executables compiles the new .cpp files. Expect roughly a minute or less on the Linux job from it. Plain compile time was not measured.

What else could save time (not in this PR)

Measured on the experiment PR and a Linux GPU machine unless marked estimate:

  1. Take clang-tidy out of the Linux build step (it is inline on every compile). Linux build 33 min -> 6.8 min, and the whole Linux superbuild went from 47 to 14 min together with parallel ctest (experiment PR, same EPYC 7763 runner class); tidy then runs as its own job (~25 min full, so scope it to changed files or per-component targets to avoid a new long pole). Caveat found: applying hipDNN's single .clang-tidy to every compile-database entry gives 338k false findings on rocKE; per-component configs are needed for parity.
  2. performance-unnecessary-value-param: 25% of a heavy file's check time, under 2% of a light one. Disabling it cut the 8 heaviest files by 33% (wall, -j8). Whole-run effect not measured; policy decision.
  3. Share the new .cpp files across the three test targets via one OBJECT library (estimate: ~23 CPU-min, ~0.4 min wall).
  4. Runner variance: the same Linux build took 26.5 / 32.9 / 37.4 min depending on the host CPU (EPYC 9V74 / 7763 / 7452).
  5. Long Python suites (hipdnn_ingestor_generator_pytest 153-230 s, descriptor_generator_pytest, hkp-pack) are the floor once ctest is parallel (~4 min).
  6. Frontend Graph.hpp is reached by 221 test files (~51 s of tidy each standalone) and is header-only by design; splitting it needs a design discussion.
  7. Not worth doing: include-only cleanup (87 files + 13 headers edited, 0.0 to -0.5% within noise).

Full write-up and raw data: reports/tidy_header_diet/REPORT.md (workspace, not in the repo).

PlanRegistrySignatureKeyEqual and GpuPlanRegistrySignatureKeyEqual used
std::visit(*this, a, b), which instantiates the visitor for every pair of
alternatives (22x22 = 484 and 15x15 = 225). Compare the active alternative
indices first, then visit only `a` and fetch the same alternative from `b`
(22 and 15 instantiations). Semantics are unchanged: keys of different
alternatives are unequal, keys of the same alternative compare with ==.

Add TestGpuPlanRegistrySignatureKey, pinning same-type equal and hash-equal,
same-type different-value unequal, cross-type unequal, and unordered_map
lookup with the key hash/equal functors.
@therock-pr-bot

therock-pr-bot Bot commented Oct 29, 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

Copy link
Copy Markdown

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

@adickin-amd
adickin-amd marked this pull request as ready for review October 29, 2026 20:49
@adickin-amd
adickin-amd requested a review from a team as a code owner October 29, 2026 20:49
@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #14680   +/-   ##
========================================
  Coverage    77.43%   77.43%           
========================================
  Files         2902     2902           
  Lines       489842   489841    -1     
  Branches     74142    74143    +1     
========================================
+ Hits        379301   379303    +2     
+ Misses       85573    85570    -3     
  Partials     24968    24968           
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 50.96% <ø> (ø) Carriedforward from 66dfe46
TensileLite-Unit 84.05% <ø> (ø) Carriedforward from 66dfe46
hipBLAS 90.62% <ø> (ø) Carriedforward from 66dfe46
hipBLASLt 68.41% <ø> (ø) Carriedforward from 66dfe46
hipCUB 82.68% <ø> (ø) Carriedforward from 66dfe46
hipDNN 87.20% <100.00%> (+<0.01%) ⬆️
hipFFT 42.47% <ø> (ø) Carriedforward from 66dfe46
hipRAND 76.12% <ø> (ø) Carriedforward from 66dfe46
hipSOLVER 69.67% <ø> (ø) Carriedforward from 66dfe46
hipSPARSE 87.03% <ø> (ø) Carriedforward from 66dfe46
rocBLAS 69.19% <ø> (ø) Carriedforward from 66dfe46
rocFFT 47.28% <ø> (ø) Carriedforward from 66dfe46
rocRAND 57.32% <ø> (ø) Carriedforward from 66dfe46
rocSOLVER 76.74% <ø> (ø) Carriedforward from 66dfe46
rocSPARSE 83.54% <ø> (ø) Carriedforward from 66dfe46
rocThrust 93.15% <ø> (ø) Carriedforward from 66dfe46

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...graph_executor/detail/PlanRegistrySignatureKey.hpp 100.00% <100.00%> (ø)

... and 2 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.

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

LGTM ty ty

…g hipdnn_golden_data_tests

The golden-data binary was registered before DNN_PROVIDER_TEST_CATEGORY_YAMLS was
set, so _add_test_target_internal() still added the raw, unlabeled
hipdnn_golden_data_tests test next to its tiered *_suite entries and the binary ran
twice. Move the categorization block above the registration.
…us shard

hkp_reserve_census_shard() was called for each FlyDSL engine and architecture
without the generated TOML, so the shard check added in #14573 failed configure
for any architecture with FlyDSL content (for example gfx1151: "the gfx1151
census shard names hipkernel_flydsl_rmsnorm_gfx1151.toml, but nothing places it
beside the shard"). Pass the file, as the gfx950 registration already does.
…_executor_compile_once

# Conflicts:
#	dnn-providers/hip-kernel-provider/src/CMakeLists.txt
#	dnn-providers/integration-tests/CMakeLists.txt
#	dnn-providers/integration-tests/src/harness/gpu-graph-executor/GpuReferenceGraphExecutor.hpp
…reference

The scalar CPU SdpaBackward reference needs seconds to tens of seconds per 256x128 bundle, and twelve of them in the quick tier exceeded the 600 s ctest timeout of hipdnn_golden_data_tests_quick_suite. referenceShapeIsAffordable now caps the CPU backward at 4M multiply-accumulates per Q*K^T pass (Q elements times Skv), in addition to the existing quick-tier limit. The 64-row padded and GQA bundles stay on CPU; the excluded bundles stay covered by the GPU lane.
@adickin-amd

Copy link
Copy Markdown
Contributor Author

Ci failure due to #13414, will override merge

@adickin-amd
adickin-amd merged commit bb650ac into develop Nov 3, 2026
318 of 324 checks passed
@adickin-amd
adickin-amd deleted the users/addickin/ref_executor_compile_once branch November 3, 2026 14:56
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

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.

2 participants