Skip to content

feat(compiler): Enable LLVM_ENABLE_PER_TARGET_RUNTIME_DIR - #7082

Merged
estewart08 merged 16 commits into
mainfrom
users/estewart/enable-per-target-runtime-dir-reland
Aug 28, 2026
Merged

estewart08 merged 16 commits into
mainfrom
users/estewart/enable-per-target-runtime-dir-reland

Conversation

@estewart08

@estewart08 estewart08 commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Add support to use LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON. This option is currently disabled by default in ROCm. There is talk upstream of keeping this ON by default and removing the option entirely. This also is a prequel step to using multlib build variants for debug/asan libraries for openmp/offload.

The layout change has broad ripple effects:

  • Host runtimes such as libomp.so move from lib/llvm/lib/ into lib/llvm/lib/<host-triple>/.
  • Clang sanitizer runtimes may report a per-target directory that contains only flang_rt, while compiler-rt remains under lib/linux.
  • CI scripts, test harnesses, and Python wheel RPATH logic that assumed the flat layout need updating.
  • Downstream consumers (hipBLASLt, rocprofiler sidecars, RPP tests, etc.) must resolve libomp.so from the new location.
Area Change
Compiler build LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON; amd-llvm provides openmp package
Sanitizer / ASAN CI Runtime dir derived dynamically from clang; hard fail on unresolvable launcher
Test harnesses rocprofiler-systems, rocprofiler-sdk, and RPP tests updated for host-triple runtime paths
Build deps / graph mxDataGenerator wired to amd-llvm in BUILD_DEPS and consumer graph
Python wheels Host-triple dir included in wheel RPATH

Test Plan

Inspect current CI tests with my PR's modifications, which should not show any issues loading libraries found in lib/llvm/lib/x86_64-unknown-linux-gnu or lib/clang/23/lib/x86_64-unknown-linux-gnu. This needs to include asan builds.

ROCmValidationSuite (RVS) needs updated as well as the rvs binary uses libomp.so:
ROCm/ROCmValidationSuite#1301

Fixes:
ISSUE ID: #6801

Partially AI Assisted

@estewart08

Copy link
Copy Markdown
Contributor Author

The patch files here will be removed later once they trickle into TheRock. I just need to test everything together.

@therock-pr-bot

therock-pr-bot Bot commented Aug 3, 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 added the Not ready to Review PR has unresolved policy failures — reviews blocked label Aug 3, 2026
@therock-pr-bot

therock-pr-bot Bot commented Aug 3, 2026 •

Copy link
Copy Markdown

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

@estewart08 estewart08 added the ci:asan Opt-in to building ASAN label Aug 4, 2026
@estewart08
estewart08 force-pushed the users/estewart/enable-per-target-runtime-dir-reland branch from 2456917 to 9072888 Compare August 4, 2026 14:40
newling added a commit to ROCm/rocm-libraries that referenced this pull request Aug 9, 2026
…0522)

I've been monitoring the rocjitsu race-detection sidecar that landed in
[PR #9969](#9969). The first
sidecars to run after the merge were triggered on [PR
#9631](#9631), and both
failed before reaching either detector workload:

```text
OpenMP runtime not found:
.../lib/llvm/lib/x86_64-unknown-linux-gnu/libomp.so
```

This looked familiar because a missing `libomp.so` was one of the
reasons the original sidecar was temporarily reverted in [PR
#9938](#9938).

The original failure and the current failure have the same underlying
dependency, but the compiler artifact layout changed:

- PR #9969's green CI proof used a compiler artifact with `libomp.so`
under:

  ```text
  lib/llvm/lib/x86_64-unknown-linux-gnu/libomp.so
  ```

- Current `develop` uses a newer TheRock revision that includes [TheRock
PR #6802](ROCm/TheRock#6802), which reverted
host per-target runtime directories. Its compiler artifact places the
runtime at:

  ```text
  lib/llvm/lib/libomp.so
  ```

[TheRock PR #7082](ROCm/TheRock#7082) is now
re-enabling `LLVM_ENABLE_PER_TARGET_RUNTIME_DIR`. Changing the
hard-coded path to the current flat location would therefore regress
when the nested layout returns. This PR instead supports both expected
layouts explicitly.

The sidecar script added the historical host-triple directory to
`LD_LIBRARY_PATH`, but it also required `libomp.so` to exist at that
exact path. With the current artifact, the parent LLVM library directory
is already in `LD_LIBRARY_PATH`, but the hard-coded preflight check
exits before the workload can run.

This PR replaces that exact-path assumption with a deterministic ordered
lookup:

1. `lib/llvm/lib/libomp.so`
2. `lib/llvm/lib/<machine>-unknown-linux-gnu/libomp.so`

If neither expected path contains `libomp.so`, the script still fails
early and prints both attempted locations.

## Validation

Focused validation invoked the real script against temporary ROCm roots
while stubbing the later compiler invocation. The observed results were:

```text
flat:    LIBOMP_PATH=.../lib/llvm/lib/libomp.so
         lib/llvm/lib appears once in LD_LIBRARY_PATH
nested:  LIBOMP_PATH=.../lib/llvm/lib/x86_64-unknown-linux-gnu/libomp.so
         both the root and host-triple directories appear in LD_LIBRARY_PATH
missing: OpenMP runtime not found at either expected path:
           .../lib/llvm/lib/libomp.so
           .../lib/llvm/lib/x86_64-unknown-linux-gnu/libomp.so
layout validation passed: flat, nested, missing
```


## Issue Tracking

Related: AIHPBLAS-3605
@estewart08
estewart08 force-pushed the users/estewart/enable-per-target-runtime-dir-reland branch 2 times, most recently from 7101087 to e4cb2e4 Compare August 19, 2026 06:17
@estewart08
estewart08 force-pushed the users/estewart/enable-per-target-runtime-dir-reland branch from e4cb2e4 to 7cc4543 Compare August 24, 2026 16:14
@estewart08
estewart08 force-pushed the users/estewart/enable-per-target-runtime-dir-reland branch from c79c047 to 5a46503 Compare August 27, 2026 01:33
@estewart08
estewart08 marked this pull request as ready for review August 27, 2026 16:56
@estewart08

Copy link
Copy Markdown
Contributor Author

Failing checks seem to be unrelated (Tests for: rocgdb-corefile, rocgdb-gpu, rocprofiler-sdk, rocr-debug-agent). Will retrigger failing checks.

@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. I'm a bit worried that downstream consumers of ROCm may be depending on the current directory so they may need similar extensions to LD_LIBRARY_PATH to pick up the host triple path though...

Comment on lines 83 to 101
def setup_env():
environ_vars["ROCM_PATH"] = str(THEROCK_PATH)
environ_vars["ROCPROFSYS_INSTALL_DIR"] = str(THEROCK_PATH)
environ_vars["ROCPROFSYS_MAX_THREADS"] = "64"

old_path = os.getenv("PATH", "")
rocm_bin = str(THEROCK_BIN_PATH)
environ_vars["PATH"] = f"{rocm_bin}:{old_path}" if old_path else rocm_bin

ld_paths = [
str(THEROCK_PATH / "share" / "rocprofiler-systems" / "examples" / "lib"),
]
if host_triple and THEROCK_LLVM_LIB_HOST_TRIPLE_PATH.exists():
ld_paths += [f"{THEROCK_LLVM_LIB_HOST_TRIPLE_PATH}"]
ld_paths_str = ":".join(ld_paths)
old_ld_path = os.getenv("LD_LIBRARY_PATH", "")
environ_vars["LD_LIBRARY_PATH"] = (
f"{ld_paths_str}:{old_ld_path}" if old_ld_path else ld_paths_str
)

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.

Not needed as part of this PR, but we could extract some of the common LD_LIBRARY_PATH environment setup to a shared script handled as part of initializing the test artifacts. I've been wanting something like that for ASan setup too (a script that sets LD_LIBRARY_PATH and LD_PRELOAD by following the instructions at https://github.com/ROCm/TheRock/blob/main/docs/development/sanitizers.md#using-asan-instrumented-libraries)

See also:

(That's more user-facing for building/running applications after installing ROCm, while this would be for running ROCm tests)

Comment on lines 17 to 19
BUILD_DEPS
amd-llvm
therock-googletest

@ScottTodd ScottTodd Aug 27, 2026 •

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.

Is this new build dep on amd-llvm (and the corresponding change to test_tools/therock_consumer_graph.json) for mxDataGenerator really needed? Most projects just need to depend on the COMPILER_TOOLCHAIN.

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.

mxDataGenerator (interface library) has target_link_libraries(mxDataGenerator INTERFACE OpenMP::OpenMP_CXX). mxDataGenerator-config.cmake then uses the openmp target for INTERFACE_LINK_LIBRARIES:

set_target_properties(mxDataGenerator PROPERTIES INTERFACE_LINK_LIBRARIES "OpenMP::OpenMP_CXX" ...

The amd-hip toolchain is not enough to resolve this openmp target in the superproject provided packages. amd-llvm subproject is updated in this patch to provide openmp via therock_cmake_subproject_provide_package(amd-llvm OpenMP lib/llvm/lib/cmake/openmp).

@estewart08

Copy link
Copy Markdown
Contributor Author

Generally LGTM. I'm a bit worried that downstream consumers of ROCm may be depending on the current directory so they may need similar extensions to LD_LIBRARY_PATH to pick up the host triple path though...

At least locally, the changes to test_rocprofiler_systems.py to detect the new path may be a duplication now that my patch landed in rocm-systems: https://github.com/ROCm/rocm-systems/pull/7334/changes#diff-b05a7bb20c2b572f98ad07f39f62c5d6a110a3636a83b2603939c89b49ec266aR81. It bakes the path detection into config.py.

The change to rocprofiler-systems is not the same solution needed for rpp or rocprofiler-sdk. That's a possible follow up to this patch.

This is needed to detect the openmp-config.cmake from amd-llvm.
@estewart08 estewart08 added the ci:host-asan Opt-in to running multi-arch host-asan CI on a pull request label Aug 28, 2026
estewart08 and others added 7 commits August 28, 2026 09:36
…profiler_systems.py

This resolves libomp.so not found when LLVM_ENABLE_PER_TARGET_DIR=ON.
This will be committed directly to rocm-libraries.
This will be promoted in a SMP update, I just need to test this
with everything combined.
…inux

* The sanitizer RPATH directories hardcoded lib/linux, so every ASAN
  instrumented executable got a dead BUILD_RPATH entry. Since clang links
  the shared runtime by absolute path without adding an -rpath, an
  instrumented build time host tool has no way to find libclang_rt.asan.so
  and dies with "error while loading shared libraries", stopping the build.

* THEROCK_SANITIZER_LAUNCHER resolved the runtime by querying the
  arch suffixed libclang_rt.asan-x86_64.so. clang echoes an unfound query
  back verbatim, so the launcher became LD_PRELOAD=libclang_rt.asan-x86_64.so,
  which ld.so reports and then ignores, silently running build time tools
  with no sanitizer at all.

Both now derive the runtime location from clang and only accept a location
that actually holds the runtime. The reported runtime dir is used only when
it really contains shared sanitizer runtimes, since a toolchain can report a
per-target dir holding only flang_rt while compiler-rt stays in lib/linux;
otherwise the RPATH derivation falls back to the previous lib/linux behavior
with a diagnostic instead of emitting a dead entry.

Failing to resolve the launcher runtime is a hard error rather than a
warning: an unresolvable LD_PRELOAD is ignored by the loader, so continuing
would run build time tools completely unsanitized while appearing to work,
which is the exact failure mode this is meant to eliminate. A sanitized
build should either be sanitized or fail. The error names the sanitizer,
compiler, resource dir, runtime dir and every soname probed with its raw
--print-file-name output so it can be diagnosed from the message alone.
This will be applied to rocm-systems. Test only.
This reverts commit 8007faa.
Patch landed in amd-llvm.
This reverts commit e4078b9.
Patch landed in rocm-libraries.
The rpp tests are built with a separate cmake invocation in test_rpp.py
and do not inherit the RPATH set after each subproject is configured.
LLVM_ENABLE_PER_TARGET_DIR=ON moves the location of libomp.so down
one level, which causes tests to fail.
Initialize host_triple for error checking.
Ensure THEROCK_LLVM_LIB_HOST_TRIPLE_PATH exists.
mxdatagenerator uses the openmp config from amd-llvm.
@estewart08
estewart08 force-pushed the users/estewart/enable-per-target-runtime-dir-reland branch from 5a46503 to 221086b Compare August 28, 2026 14:37
@estewart08

Copy link
Copy Markdown
Contributor Author

Had to rebase and fix conflict in compiler/CMakeLists.txt.

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

@therock-pr-bot therock-pr-bot Bot removed the Not ready to Review PR has unresolved policy failures — reviews blocked label Aug 28, 2026
@estewart08
estewart08 merged commit a84a743 into main Aug 28, 2026
204 of 216 checks passed
@estewart08
estewart08 deleted the users/estewart/enable-per-target-runtime-dir-reland branch August 28, 2026 21:41
@github-project-automation github-project-automation Bot moved this from TODO to Done in TheRock Triage Aug 28, 2026
ronlieb pushed a commit to ROCm/llvm-project that referenced this pull request Aug 30, 2026
…rride (#4179)

## Downstream delta removed

`amd-staging` carries a one-line AMD-local override that clobbers
upstream's platform default immediately after it is computed:

```cmake
if(CMAKE_SYSTEM_NAME MATCHES "BSD|Linux|OS390|AIX")
  set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default ON)
else()
  set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default OFF)
endif()
set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default OFF)   # <-- removed
```

After this change `llvm/CMakeLists.txt` has **zero**
`LLVM_ENABLE_PER_TARGET_RUNTIME_DIR` divergence from `upstream/main`.
Upstream is moving toward keeping this ON by default and dropping the
option entirely, so carrying the override moves us further from upstream
over time.

## Why it existed

ROCm consumers assumed the flat `lib/llvm/lib` layout. With the
per-target directory on, `libomp.so` moves to
`lib/llvm/lib/<host-triple>/` while consumer RUNPATHs still point at
`lib/llvm/lib` — the library ships but cannot be loaded.

## Why TheRock is unaffected

TheRock passes `-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR` explicitly
(ROCm/TheRock#7559; ROCm/TheRock#7082 moves it to `ON` and fixes the
consumers). A command-line `-D` beats a `set(... CACHE ...)` without
`FORCE`, so TheRock's value wins regardless of the default here.
estewart08 added a commit that referenced this pull request Sep 8, 2026
This breaks backwards compatibility with binaries/libraries built with 10.0.
Original PR: #7082

This is a limited revert that restores the old library layout of lib/llvm/lib
while keeping other infrastructure patches in place for a future reland.
estewart08 added a commit that referenced this pull request Sep 9, 2026
This breaks backwards compatibility with binaries/libraries built with
10.0. Original PR: #7082

This is a limited revert that restores the old library layout of
lib/llvm/lib while keeping other infrastructure patches in place for a
future reland.

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

Labels

ci:asan Opt-in to building ASAN ci:host-asan Opt-in to running multi-arch host-asan CI on a pull request platform: Linux

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants