Skip to content

[PGO][HIP] Linux HSA-introspection device drain on the profile_rocm reland - #2808

Closed
lfmeadow wants to merge 4 commits into
amd-stagingfrom
device-pgo-hsa-drain-v3
Closed

[PGO][HIP] Linux HSA-introspection device drain on the profile_rocm reland#2808
lfmeadow wants to merge 4 commits into
amd-stagingfrom
device-pgo-hsa-drain-v3

Conversation

@lfmeadow

@lfmeadow lfmeadow commented Jun 7, 2026

Copy link
Copy Markdown

Summary

Restarts the HIP device profile-drain work cleanly on top of the current amd-staging, which now carries the relanded opt-in clang_rt.profile_rocm runtime (llvm#201606). Supersedes #2743 (closed).

End-to-end chain for clang -x hip -fprofile-instr-generate -fcoverage-mapping:

  1. Device code instrumented (__llvm_profile_instrument_gpu + __llvm_profile_sections) -- already in amd-staging.
  2. Device link pulls in the amdgcn libclang_rt.profile.a -- added here (Clang.cpp new-offload-driver path + HIPAMD.cpp traditional path).
  3. Host emits __llvm_profile_offload_register_shadow_variable -- already in amd-staging (CGCUDANV).
  4. Host link pulls in clang_rt.profile_rocm -- added here (Linux.cpp/MSVC.cpp, the net-new part of Reland HIP offload PGO compiler support and link the device-profile runtime llvm/llvm-project#201607).
  5. Exit drain: HSA introspection (Linux) / host-shadow (Windows) -- added here.
  6. Build recipe for host + device runtimes -- added here.

Details

  • Drain runtime, split by platform (mutually exclusive guards):
    • InstrProfilingPlatformROCm.cpp -> Linux HSA introspection: walks every GPU agent's loaded code objects at exit, draining device counters even for device modules with no host-side shadow (RCCL-style synthesized kernels) and for kernels left on a non-current device.
    • InstrProfilingPlatformROCmWindows.cpp (new) -> the reland host-shadow drain, unchanged, guarded _WIN32.
    • compiler-rt/lib/profile/CMakeLists.txt wires both into clang_rt.profile_rocm.
  • Device-runtime link (__llvm_profile_instrument_gpu): Clang.cpp LinkerWrapper::ConstructJob (Linux/new-offload-driver) and HIPAMD.cpp constructLldCommand (Windows/traditional). Without it the device link fails undefined symbol: __llvm_profile_instrument_gpu.
  • Host-runtime link: Linux.cpp/MSVC.cpp link clang_rt.profile_rocm ahead of the base profile for HIP host links when profiling is requested; clang/test/Driver/hip-profile-rocm-runtime.hip covers ordering.
  • Standalone (non-TheRock) build + test recipe under compiler-rt/test/profile/device-pgo/ (toolchain-cache.cmake, build.sh, README.md): toolchain + clang_rt.profile_rocm + amdgcn device runtime in one configure (LLVM_RUNTIME_TARGETS=default;amdgcn-amd-amdhsa).
  • GPU test runner: run_gpu_tests.py (lit-lite) derives multi-device from the runtime-visible GPU count via amdgpu-arch; GPU/+AMDGPU/ .hip tests use Linux HSA CHECK strings and mark agent-walk-only cases UNSUPPORTED: windows.

Validation

Built and run end-to-end on a 4x gfx90a host via the standalone recipe:

  • build.sh produced the toolchain + host libclang_rt.profile_rocm.a (contains the HSA drain: drainDevices, __llvm_profile_hip_collect_device_data; the Windows TU compiled empty, no duplicate symbols) + amdgcn libclang_rt.profile.a.
  • run_gpu_tests.py over GPU/ + AMDGPU/: 11 passed, 0 failed, with multi-device auto-detected (so the multi-GPU and non-default-device agent-walk tests actually ran).
  • Driver host-link order verified: HIP+PGO emits libclang_rt.profile_rocm.a before libclang_rt.profile.a; non-HIP PGO links neither profile_rocm.
  • The clang-linker-wrapper device link receives --device-linker=amdgcn-amd-amdhsa=.../libclang_rt.profile.a (the Clang.cpp change), confirming the device-runtime link.

Remaining: Windows host-shadow path not built/run here (no Windows box); CI wiring is out of scope for this PR.

lfmeadow and others added 3 commits June 9, 2026 15:15
…eland

amd-staging now carries the relanded HIP offload PGO runtime as the opt-in
clang_rt.profile_rocm library (llvm#201606), but lacks the host-link wiring
(llvm#201607, still open upstream), so a HIP+PGO host link leaves the
__llvm_profile_offload_* symbols unresolved. This restarts the device-drain
work cleanly on top of that reland instead of rebasing the prior branch.

Drain runtime (split by platform, mutually exclusive guards so exactly one
provides the __llvm_profile_offload_* / __llvm_profile_hip_collect_device_data
symbols):
- InstrProfilingPlatformROCm.cpp: Linux HSA introspection. Walks every GPU
  agent's loaded code objects at exit, so it drains device counters even for
  device modules with no host-side shadow (RCCL-style synthesized kernels) and
  for kernels on a non-current device.
- InstrProfilingPlatformROCmWindows.cpp: the reland host-shadow drain,
  unchanged, guarded to _WIN32 (Windows has no HSA introspection).
- CMakeLists.txt wires both into clang_rt.profile_rocm.

Driver host-link wiring (net-new part of llvm#201607, adapted to amd-staging):
- Linux.cpp / MSVC.cpp link clang_rt.profile_rocm ahead of the base profile
  for HIP host links when profiling is requested.
- hip-profile-rocm-runtime.hip covers the link ordering.

Standalone (non-TheRock) build + test recipe:
- compiler-rt/test/profile/device-pgo/{toolchain-cache.cmake,build.sh,README.md}
  build the toolchain + clang_rt.profile_rocm + the amdgcn device profile
  runtime in one cmake configure (LLVM_RUNTIME_TARGETS=default;amdgcn-amd-amdhsa).
- run_gpu_tests.py (lit-lite runner) derives the multi-device feature from the
  runtime-visible GPU count via amdgpu-arch; GPU/ and AMDGPU/ .hip tests use
  Linux HSA CHECK strings and mark agent-walk-only cases UNSUPPORTED: windows.

Co-authored-by: Cursor <cursoragent@cursor.com>
Instrumented HIP device code references the amdgcn device profile runtime
(__llvm_profile_instrument_gpu and the __llvm_profile_sections bounds table
emitted by InstrProfilingPlatformGPU). Nothing on the offload device link
pulls it in, so a plain `clang -x hip -fprofile-instr-generate
-fcoverage-mapping` link fails with `undefined symbol:
__llvm_profile_instrument_gpu` on both Linux and Windows.

Forward the arch-suffixed static device profile runtime to the GPU device
linker, in both device-link paths:
- Clang.cpp LinkerWrapper::ConstructJob, next to -lompdevice, for the
  --offload-new-driver path HIP uses on Linux.
- HIPAMD.cpp constructLldCommand, after --no-whole-archive, for the
  traditional offload path (e.g. Windows, which does not route device linking
  through clang-linker-wrapper).

The VFS/fs exists() guard keeps this a no-op when the device profile runtime
is not installed.

Co-authored-by: Cursor <cursoragent@cursor.com>
Validated the standalone recipe end-to-end on a 4x gfx90a host (built the
toolchain + clang_rt.profile_rocm + amdgcn libclang_rt.profile.a, then ran the
GPU/ and AMDGPU/ suites: 11 passed, 0 failed, with multi-device autodetected).
Fixes found while validating:

- Build the offload toolchain tools the HIP compile/link actually exec's:
  clang-offload-bundler, clang-linker-wrapper, llvm-link, llvm-offload-binary,
  and offload-arch (also installed as amdgpu-arch, used for --offload-arch=native
  and the multi-device feature). Drop the non-existent clang++ ninja target (the
  clang target produces the clang++ symlink).
- Runner invocation docs: the flag is --hip-lib-path (not --hip-path), and
  --toolchain-bin must be absolute because RUN lines execute from a temp dir.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lfmeadow
lfmeadow force-pushed the device-pgo-hsa-drain-v3 branch from 0a4bdac to 5de6939 Compare June 9, 2026 20:15
@lfmeadow
lfmeadow requested a review from Copilot June 9, 2026 20:18
@lfmeadow
lfmeadow requested a review from ronlieb June 9, 2026 20:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR relands HIP device PGO / coverage support on top of current amd-staging by ensuring both the device profile runtime and the host ROCm drain runtime (clang_rt.profile_rocm) are linked appropriately, and by adding a Linux HSA-introspection-based exit drain (with a Windows-only legacy host-shadow implementation). It also adds a standalone build-and-run recipe plus targeted tests for the end-to-end workflow.

Changes:

  • Add/adjust driver logic to forward the AMDGPU device profile runtime into the offload device link, and link clang_rt.profile_rocm for HIP host links when profiling is enabled.
  • Implement Linux HSA-introspection device draining in InstrProfilingPlatformROCm.cpp and add a Windows-specific legacy drain TU.
  • Add a standalone “lit-lite” GPU test runner plus new/updated HIP tests and a CMake/Ninja recipe to build the required toolchain + runtimes.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
compiler-rt/test/profile/run_gpu_tests.py New minimal lit-style runner to execute HIP .hip tests without llvm-lit/FileCheck installed.
compiler-rt/test/profile/GPU/instrprof-hip-nondefault-device.hip Update expectations for Linux HSA agent-walk drain; gate off Windows.
compiler-rt/test/profile/GPU/instrprof-hip-multiple-kernels.hip Fix expected mangled names for kernels.
compiler-rt/test/profile/GPU/instrprof-hip-multi-gpu.hip Update expectations for multi-GPU drain via HSA agent walk; gate off Windows.
compiler-rt/test/profile/GPU/instrprof-hip-coverage.hip Tighten FileCheck pattern to avoid false matches on “80.00%” etc.
compiler-rt/test/profile/device-pgo/toolchain-cache.cmake New cache file to build host toolchain + profile_rocm + amdgcn device profile runtime in one configure.
compiler-rt/test/profile/device-pgo/README.md New documentation for standalone build and GPU test execution.
compiler-rt/test/profile/device-pgo/build.sh New convenience script to build required tools and runtimes for device-PGO tests.
compiler-rt/test/profile/AMDGPU/lit.local.cfg.py New local lit config gating AMDGPU drain tests on amdgpu feature.
compiler-rt/test/profile/AMDGPU/device-symbols.hip New test asserting __llvm_profile_sections is present in device ELF dynsym.
compiler-rt/test/profile/AMDGPU/device-no-kernel.hip New robustness test for no-kernel-launch scenario (no crash / appropriate no-op).
compiler-rt/test/profile/AMDGPU/device-early-collect.hip New regression test for early explicit collection not poisoning later atexit drain.
compiler-rt/test/profile/AMDGPU/device-basic.hip New end-to-end test covering host+device profraw merge and llvm-cov reporting.
compiler-rt/lib/profile/InstrProfilingPlatformROCmWindows.cpp New Windows-only legacy host-shadow + hipMemcpy drain implementation.
compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp Linux/Unix HSA-introspection drain implementation + refactor and safety checks.
compiler-rt/lib/profile/CMakeLists.txt Wire both ROCm platform TUs into clang_rt.profile_rocm and adjust removal logic.
clang/lib/Driver/ToolChains/HIPAMD.cpp Forward device profile runtime archive into traditional device link path.
clang/lib/Driver/ToolChains/Clang.cpp Forward device profile runtime archive into linker-wrapper offload device link.

Comment thread compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp Outdated
Comment thread compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp Outdated
Comment thread compiler-rt/lib/profile/InstrProfilingPlatformROCm.cpp Outdated
Comment thread clang/lib/Driver/ToolChains/HIPAMD.cpp
Comment thread compiler-rt/test/profile/run_gpu_tests.py Outdated
- ROCm drain: split alreadySeenBounds() into a pure seenBounds() check and a
  separate recordBounds(); record a bounds tuple only after a successful drain
  (>0) or a confirmed-empty section (0). A transient drain failure (<0) is left
  unrecorded so a later agent or a subsequent collect call can retry instead of
  silently dropping device profiling data.
- ROCm drain: fix the DrainCompleted latch comment to match the code (latch only
  when data was actually drained, never on the "no instrumented code object"
  walk, which would otherwise suppress a real atexit drain after a later launch).
- HIPAMD.cpp: probe the device profile runtime via TC.getVFS().exists() (matching
  the new-offload-driver path in Clang.cpp) so overlay/virtual filesystems are
  honored instead of bypassing them with llvm::sys::fs::exists().
- run_gpu_tests.py: add a per-RUN-line timeout (default 600s, <=0 disables) so a
  hung GPU/compiler invocation can no longer wedge the whole run.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lfmeadow

Copy link
Copy Markdown
Author

Superseded by the upstream llvm#203056, which landed the additive Strategy-B device-profile drain (supplemental HSA-introspection pass with content-dedup on top of upstream's host-shadow drain from llvm#202095) and is now merged down into amd-staging.

This PR's Strategy-A (HSA-sole on Linux) design plus its driver hunks were superseded during upstream review (the new-offload-driver path links the device RT without the HIPAMD.cpp/Clang.cpp changes). Closing in favor of the upstream solution. Fork-side test coverage is tracked in #2895.

@lfmeadow lfmeadow closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants