[Mlir-commits] [mlir] [MLIR][ROCm] Build mlir_rocm_runtime STANDALONE (PR #205651)
Umang Yadav
llvmlistbot at llvm.org
Thu Jun 25 06:14:17 PDT 2026
https://github.com/umangyadav updated https://github.com/llvm/llvm-project/pull/205651
>From 76e36b3692661f11ca0bbb3d2beef075e8c91d4d Mon Sep 17 00:00:00 2001
From: Umang Yadav <umayadav at amd.com>
Date: Wed, 24 Jun 2026 19:15:48 +0000
Subject: [PATCH 1/3] [mlir] Build mlir_rocm_runtime STANDALONE
Mark mlir_rocm_runtime STANDALONE so it no longer links LLVMSupport,
mirroring mlir_cuda_runtime, and drop the SmallVector/ArrayRef use in
mgpuMemHostRegisterMemRef in favor of std equivalents. This removes the
DISABLE_PCH_REUSE workaround, which a STANDALONE library no longer needs.
Linking LLVMSupport exported ~1300 default-visibility llvm::* symbols.
When the runtime is dlopen-ed into a process that also reaches ROCm's
libLLVM.so (via the libamdhip64 -> libamd_comgr -> libLLVM.so DT_NEEDED
chain), the dynamic linker interposed these data symbols, causing the two
LLVM instances to share cl::opt / pass-registry / ManagedStatic singletons
and abort during dynamic init (SmallPtrSet.h: Assertion `Bucket < End').
Co-authored-by: Cursor <cursoragent at cursor.com>
---
mlir/lib/ExecutionEngine/CMakeLists.txt | 13 +++---
.../ExecutionEngine/RocmRuntimeWrappers.cpp | 41 +++++++++++--------
2 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/mlir/lib/ExecutionEngine/CMakeLists.txt b/mlir/lib/ExecutionEngine/CMakeLists.txt
index 87af4724f159a..3199c88313087 100644
--- a/mlir/lib/ExecutionEngine/CMakeLists.txt
+++ b/mlir/lib/ExecutionEngine/CMakeLists.txt
@@ -403,12 +403,13 @@ if(LLVM_ENABLE_PIC)
EXCLUDE_FROM_LIBMLIR
- # TODO: this is merely a workaround. If this library depends on LLVMSupport,
- # it should suppress symbols, or if it doesn't, it shouldn't link against
- # it. This workaround prevents the library from defining the symbol
- # llvm::EnableABIBreakingChecks, which would cause ODR-violations when
- # dlopen-ed.
- DISABLE_PCH_REUSE
+ # This library is dlopen-ed (e.g. by mlir-runner via --shared-libs),
+ # frequently into a process that already hosts another LLVM (ROCm's own
+ # libLLVM.so is reachable through the libamdhip64 -> libamd_comgr
+ # DT_NEEDED chain). Linking LLVMSupport here would duplicate LLVM's
+ # cl::opt / pass-registry / ManagedStatic singletons and abort during
+ # dynamic init. The wrappers don't need LLVMSupport, so build STANDALONE.
+ STANDALONE
)
# Supress compiler warnings from HIP headers
diff --git a/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp b/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
index 251245106c56e..86090f410c897 100644
--- a/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
+++ b/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
@@ -13,13 +13,17 @@
//===----------------------------------------------------------------------===//
#include <cassert>
-#include <numeric>
+#include <cstdint>
+#include <cstdio>
#include "mlir/ExecutionEngine/CRunnerUtils.h"
-#include "llvm/ADT/ArrayRef.h"
#include "hip/hip_runtime.h"
+#ifdef _WIN32
+#include <malloc.h>
+#endif // _WIN32
+
#define HIP_REPORT_IF_ERROR(expr) \
[](hipError_t result) { \
if (!result) \
@@ -167,22 +171,25 @@ extern "C" void mgpuMemHostRegister(void *ptr, uint64_t sizeBytes) {
extern "C" void
mgpuMemHostRegisterMemRef(int64_t rank, StridedMemRefType<char, 1> *descriptor,
int64_t elementSizeBytes) {
-
- llvm::SmallVector<int64_t, 4> denseStrides(rank);
- llvm::ArrayRef<int64_t> sizes(descriptor->sizes, rank);
- llvm::ArrayRef<int64_t> strides(sizes.end(), rank);
-
- std::partial_sum(sizes.rbegin(), sizes.rend(), denseStrides.rbegin(),
- std::multiplies<int64_t>());
- auto sizeBytes = denseStrides.front() * elementSizeBytes;
-
// Only densely packed tensors are currently supported.
- std::rotate(denseStrides.begin(), denseStrides.begin() + 1,
- denseStrides.end());
- denseStrides.back() = 1;
- assert(strides == llvm::ArrayRef(denseStrides));
-
- auto ptr = descriptor->data + descriptor->offset * elementSizeBytes;
+#ifdef _WIN32
+ int64_t *denseStrides = (int64_t *)_alloca(rank * sizeof(int64_t));
+#else
+ int64_t *denseStrides = (int64_t *)alloca(rank * sizeof(int64_t));
+#endif // _WIN32
+ int64_t *sizes = descriptor->sizes;
+ for (int64_t i = rank - 1, runningStride = 1; i >= 0; i--) {
+ denseStrides[i] = runningStride;
+ runningStride *= sizes[i];
+ }
+ uint64_t sizeBytes = sizes[0] * denseStrides[0] * elementSizeBytes;
+ int64_t *strides = &sizes[rank];
+ (void)strides;
+ for (unsigned i = 0; i < rank; ++i)
+ assert(strides[i] == denseStrides[i] &&
+ "Mismatch in computed dense strides");
+
+ auto *ptr = descriptor->data + descriptor->offset * elementSizeBytes;
mgpuMemHostRegister(ptr, sizeBytes);
}
>From 38f97f1b196707f0838d64fce958b5fbbb057919 Mon Sep 17 00:00:00 2001
From: Umang Yadav <umayadav at amd.com>
Date: Thu, 25 Jun 2026 13:07:28 +0000
Subject: [PATCH 2/3] make implementation withotu alloca, we only need to check
for dense memref, we can keep runningStrides
---
.../ExecutionEngine/RocmRuntimeWrappers.cpp | 25 ++++++-------------
1 file changed, 7 insertions(+), 18 deletions(-)
diff --git a/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp b/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
index 86090f410c897..47977a246f0bf 100644
--- a/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
+++ b/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
@@ -20,10 +20,6 @@
#include "hip/hip_runtime.h"
-#ifdef _WIN32
-#include <malloc.h>
-#endif // _WIN32
-
#define HIP_REPORT_IF_ERROR(expr) \
[](hipError_t result) { \
if (!result) \
@@ -171,23 +167,16 @@ extern "C" void mgpuMemHostRegister(void *ptr, uint64_t sizeBytes) {
extern "C" void
mgpuMemHostRegisterMemRef(int64_t rank, StridedMemRefType<char, 1> *descriptor,
int64_t elementSizeBytes) {
- // Only densely packed tensors are currently supported.
-#ifdef _WIN32
- int64_t *denseStrides = (int64_t *)_alloca(rank * sizeof(int64_t));
-#else
- int64_t *denseStrides = (int64_t *)alloca(rank * sizeof(int64_t));
-#endif // _WIN32
int64_t *sizes = descriptor->sizes;
- for (int64_t i = rank - 1, runningStride = 1; i >= 0; i--) {
- denseStrides[i] = runningStride;
- runningStride *= sizes[i];
- }
- uint64_t sizeBytes = sizes[0] * denseStrides[0] * elementSizeBytes;
int64_t *strides = &sizes[rank];
- (void)strides;
- for (unsigned i = 0; i < rank; ++i)
- assert(strides[i] == denseStrides[i] &&
+ int64_t runningStride = 1;
+ // Only densely packed tensors are currently supported.
+ for (int64_t i = rank - 1; i >= 0; --i) {
+ assert(strides[i] == runningStride &&
"Mismatch in computed dense strides");
+ runningStride *= sizes[i];
+ }
+ uint64_t sizeBytes = runningStride * elementSizeBytes;
auto *ptr = descriptor->data + descriptor->offset * elementSizeBytes;
mgpuMemHostRegister(ptr, sizeBytes);
>From dad140bca0801860f7c35aa60a66d35591893706 Mon Sep 17 00:00:00 2001
From: Umang Yadav <umayadav at amd.com>
Date: Thu, 25 Jun 2026 13:13:27 +0000
Subject: [PATCH 3/3] Formatting
---
mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp b/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
index 47977a246f0bf..445518111a244 100644
--- a/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
+++ b/mlir/lib/ExecutionEngine/RocmRuntimeWrappers.cpp
@@ -172,8 +172,7 @@ mgpuMemHostRegisterMemRef(int64_t rank, StridedMemRefType<char, 1> *descriptor,
int64_t runningStride = 1;
// Only densely packed tensors are currently supported.
for (int64_t i = rank - 1; i >= 0; --i) {
- assert(strides[i] == runningStride &&
- "Mismatch in computed dense strides");
+ assert(strides[i] == runningStride && "Mismatch in computed dense strides");
runningStride *= sizes[i];
}
uint64_t sizeBytes = runningStride * elementSizeBytes;
More information about the Mlir-commits
mailing list