[llvm] [Offload] Add device UID (PR #164391)
Robert Imschweiler via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 24 09:53:16 PDT 2025
https://github.com/ro-i updated https://github.com/llvm/llvm-project/pull/164391
>From 1e3bb90cc2594e3434d0e99431fd19d6cdf8fd6b Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Mon, 20 Oct 2025 03:06:58 -0500
Subject: [PATCH 01/11] [Offload] Add device UID
Introduced in OpenMP 6.0, the device UID shall be a unique identifier of
a device on a given system. (Not necessarily a UUID.)
Since it is not guaranteed that the (U)UIDs defined by the device vendor
libraries, such as HSA, do not overlap with those of other vendors, the
device UIDs in offload are always combined with the offload plugin name.
In case the vendor library does not specify any device UID for a given
device, we fall back to the offload-internal device ID.
Note that the "fake" multiple host devices do *not* get different UIDs
because they are effectively the same device.
The device UID can be retrieved using the `llvm-offload-device-info`
tool.
---
offload/liboffload/API/Device.td | 1 +
offload/liboffload/src/OffloadImpl.cpp | 7 +++++--
.../amdgpu/dynamic_hsa/hsa_ext_amd.h | 1 +
offload/plugins-nextgen/amdgpu/src/rtl.cpp | 14 +++++++++++++
.../common/include/PluginInterface.h | 15 +++++++++++++-
.../common/src/PluginInterface.cpp | 14 +++++++++++--
offload/plugins-nextgen/host/src/rtl.cpp | 4 +++-
.../deviceinfo/llvm-offload-device-info.cpp | 1 +
.../OffloadAPI/device/olGetDeviceInfo.cpp | 20 +++++++++++++++++++
.../OffloadAPI/device/olGetDeviceInfoSize.cpp | 1 +
10 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/offload/liboffload/API/Device.td b/offload/liboffload/API/Device.td
index 5b54c79d83f9d..e9c154818c4a1 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -29,6 +29,7 @@ def ol_device_info_t : Enum {
TaggedEtor<"PLATFORM", "ol_platform_handle_t", "the platform associated with the device">,
TaggedEtor<"NAME", "char[]", "Device name">,
TaggedEtor<"PRODUCT_NAME", "char[]", "Device user-facing marketing name">,
+ TaggedEtor<"UID", "char[]", "Device UID">,
TaggedEtor<"VENDOR", "char[]", "Device vendor">,
TaggedEtor<"DRIVER_VERSION", "char[]", "Driver version">,
TaggedEtor<"MAX_WORK_GROUP_SIZE", "uint32_t", "Maximum total work group size in work items">,
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 6d22faeb0e57e..ed306470a0d76 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -147,8 +147,8 @@ llvm::Error ol_platform_impl_t::init() {
if (llvm::Error Err = Plugin->initDevice(Id))
return Err;
- auto Device = &Plugin->getDevice(Id);
- auto Info = Device->obtainInfoImpl();
+ GenericDeviceTy *Device = &Plugin->getDevice(Id);
+ llvm::Expected<InfoTreeNode> Info = Device->obtainInfo();
if (llvm::Error Err = Info.takeError())
return Err;
Devices.emplace_back(std::make_unique<ol_device_impl_t>(Id, Device, *this,
@@ -467,6 +467,7 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
switch (PropName) {
case OL_DEVICE_INFO_NAME:
case OL_DEVICE_INFO_PRODUCT_NAME:
+ case OL_DEVICE_INFO_UID:
case OL_DEVICE_INFO_VENDOR:
case OL_DEVICE_INFO_DRIVER_VERSION: {
// String values
@@ -544,6 +545,8 @@ Error olGetDeviceInfoImplDetailHost(ol_device_handle_t Device,
return Info.writeString("Virtual Host Device");
case OL_DEVICE_INFO_PRODUCT_NAME:
return Info.writeString("Virtual Host Device");
+ case OL_DEVICE_INFO_UID:
+ return Info.writeString(GenericDeviceTy::getHostDeviceUid());
case OL_DEVICE_INFO_VENDOR:
return Info.writeString("Liboffload");
case OL_DEVICE_INFO_DRIVER_VERSION:
diff --git a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h
index 29cfe78082dbb..ddfa65c76cf2d 100644
--- a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h
+++ b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h
@@ -72,6 +72,7 @@ typedef enum hsa_amd_agent_info_s {
HSA_AMD_AGENT_INFO_MAX_WAVES_PER_CU = 0xA00A,
HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU = 0xA00B,
HSA_AMD_AGENT_INFO_COOPERATIVE_QUEUES = 0xA010,
+ HSA_AMD_AGENT_INFO_UUID = 0xA011,
HSA_AMD_AGENT_INFO_TIMESTAMP_FREQUENCY = 0xA016,
} hsa_amd_agent_info_t;
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index 0b03ef534d273..0723e4bc5f035 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -2083,6 +2083,20 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
return Err;
ComputeUnitKind = GPUName;
+ // From the ROCm HSA documentation:
+ // Query the UUID of the agent. The value is an Ascii string with a maximum
+ // of 21 chars including NUL. The string value consists of two parts: header
+ // and body. The header identifies the device type (GPU, CPU, DSP) while the
+ // body encodes the UUID as a 16 digit hex string.
+ //
+ // Agents that do not support UUID will return the string "GPU-XX" or
+ // "CPU-XX" or "DSP-XX" depending on their device type.
+ char Uuid[24];
+ if (auto Err = getDeviceAttr(HSA_AMD_AGENT_INFO_UUID, Uuid))
+ return Err;
+ if (strcmp(Uuid + 3, "-XX") != 0)
+ DeviceUid = std::string(Plugin.getName()) + "-" + std::string(Uuid);
+
// Get the wavefront size.
uint32_t WavefrontSize = 0;
if (auto Err = getDeviceAttr(HSA_AGENT_INFO_WAVEFRONT_SIZE, WavefrontSize))
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index f9bff9abd903c..244f5cbdf9835 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -791,6 +791,10 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// this id is not unique between different plugins; they may overlap.
int32_t getDeviceId() const { return DeviceId; }
+ /// Get the unique identifier of the device.
+ const char *getDeviceUid() const { return DeviceUid.c_str(); }
+ static constexpr const char *getHostDeviceUid() { return "HOST"; }
+
/// Set the context of the device if needed, before calling device-specific
/// functions. Plugins may implement this function as a no-op if not needed.
virtual Error setContext() = 0;
@@ -989,9 +993,12 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
Error syncEvent(void *EventPtr);
virtual Error syncEventImpl(void *EventPtr) = 0;
+ /// Obtain information about the device.
+ Expected<InfoTreeNode> obtainInfo();
+ virtual Expected<InfoTreeNode> obtainInfoImpl() = 0;
+
/// Print information about the device.
Error printInfo();
- virtual Expected<InfoTreeNode> obtainInfoImpl() = 0;
/// Return true if the device has work that is either queued or currently
/// running
@@ -1204,6 +1211,12 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// global device id and is not the device id visible to the OpenMP user.
const int32_t DeviceId;
+ /// The unique identifier of the device.
+ /// Per default, the unique identifier of the device is set to the device id,
+ /// combined with the plugin name, since the offload device id may overlap
+ /// between different plugins.
+ std::string DeviceUid;
+
/// The default grid values used for this device.
llvm::omp::GV GridValues;
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 36d643b65922d..8d009948b6d46 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -715,6 +715,9 @@ GenericDeviceTy::GenericDeviceTy(GenericPluginTy &Plugin, int32_t DeviceId,
DeviceId(DeviceId), GridValues(OMPGridValues),
PeerAccesses(NumDevices, PeerAccessState::PENDING), PeerAccessesLock(),
PinnedAllocs(*this), RPCServer(nullptr) {
+ DeviceUid = std::string(Plugin.getName()) + "-" +
+ std::to_string(static_cast<uint64_t>(DeviceId));
+
#ifdef OMPT_SUPPORT
OmptInitialized.store(false);
// Bind the callbacks to this device's member functions
@@ -1524,11 +1527,18 @@ Error GenericDeviceTy::enqueueHostCall(void (*Callback)(void *), void *UserData,
return Err;
}
+Expected<InfoTreeNode> GenericDeviceTy::obtainInfo() {
+ Expected<InfoTreeNode> Info = obtainInfoImpl();
+ if (Info)
+ Info->add("UID", DeviceUid, "", DeviceInfo::UID);
+ return Info;
+}
+
Error GenericDeviceTy::printInfo() {
- auto Info = obtainInfoImpl();
+ Expected<InfoTreeNode> Info = obtainInfo();
// Get the vendor-specific info entries describing the device properties.
- if (auto Err = Info.takeError())
+ if (Error Err = Info.takeError())
return Err;
// Print all info entries.
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index eb4ecac9907a1..f75c9cd29b2ad 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -148,7 +148,9 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
/// Create the device with a specific id.
GenELF64DeviceTy(GenericPluginTy &Plugin, int32_t DeviceId,
int32_t NumDevices)
- : GenericDeviceTy(Plugin, DeviceId, NumDevices, GenELF64GridValues) {}
+ : GenericDeviceTy(Plugin, DeviceId, NumDevices, GenELF64GridValues) {
+ DeviceUid = getHostDeviceUid();
+ }
~GenELF64DeviceTy() {}
diff --git a/offload/tools/deviceinfo/llvm-offload-device-info.cpp b/offload/tools/deviceinfo/llvm-offload-device-info.cpp
index 9b58d67f017ca..42ffb97d6d77c 100644
--- a/offload/tools/deviceinfo/llvm-offload-device-info.cpp
+++ b/offload/tools/deviceinfo/llvm-offload-device-info.cpp
@@ -176,6 +176,7 @@ ol_result_t printDevice(std::ostream &S, ol_device_handle_t D) {
printDeviceValue<const char *>(S, D, OL_DEVICE_INFO_NAME, "Name"));
OFFLOAD_ERR(printDeviceValue<const char *>(S, D, OL_DEVICE_INFO_PRODUCT_NAME,
"Product Name"));
+ OFFLOAD_ERR(printDeviceValue<const char *>(S, D, OL_DEVICE_INFO_UID, "UID"));
OFFLOAD_ERR(
printDeviceValue<ol_device_type_t>(S, D, OL_DEVICE_INFO_TYPE, "Type"));
OFFLOAD_ERR(printDeviceValue<const char *>(
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
index 8cb0b8065c33e..30eafee026316 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
@@ -98,6 +98,16 @@ TEST_P(olGetDeviceInfoTest, SuccessProductName) {
ASSERT_EQ(std::strlen(Name.data()), Size - 1);
}
+TEST_P(olGetDeviceInfoTest, SuccessUID) {
+ size_t Size = 0;
+ ASSERT_SUCCESS(olGetDeviceInfoSize(Device, OL_DEVICE_INFO_UID, &Size));
+ ASSERT_GT(Size, 0ul);
+ std::vector<char> UID;
+ UID.resize(Size);
+ ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_UID, Size, UID.data()));
+ ASSERT_EQ(std::strlen(UID.data()), Size - 1);
+}
+
TEST_P(olGetDeviceInfoTest, HostProductName) {
size_t Size = 0;
ASSERT_SUCCESS(olGetDeviceInfoSize(Host, OL_DEVICE_INFO_PRODUCT_NAME, &Size));
@@ -109,6 +119,16 @@ TEST_P(olGetDeviceInfoTest, HostProductName) {
ASSERT_EQ(std::strlen(Name.data()), Size - 1);
}
+TEST_P(olGetDeviceInfoTest, HostUID) {
+ size_t Size = 0;
+ ASSERT_SUCCESS(olGetDeviceInfoSize(Host, OL_DEVICE_INFO_UID, &Size));
+ ASSERT_GT(Size, 0ul);
+ std::vector<char> UID;
+ UID.resize(Size);
+ ASSERT_SUCCESS(olGetDeviceInfo(Host, OL_DEVICE_INFO_UID, Size, UID.data()));
+ ASSERT_EQ(std::strlen(UID.data()), Size - 1);
+}
+
TEST_P(olGetDeviceInfoTest, SuccessVendor) {
size_t Size = 0;
ASSERT_SUCCESS(olGetDeviceInfoSize(Device, OL_DEVICE_INFO_VENDOR, &Size));
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
index c4a3c2d5e3c75..79a18c1d133dc 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
@@ -32,6 +32,7 @@ OL_DEVICE_INFO_SIZE_TEST_EQ(Platform, ol_platform_handle_t,
OL_DEVICE_INFO_PLATFORM);
OL_DEVICE_INFO_SIZE_TEST_NONZERO(Name, OL_DEVICE_INFO_NAME);
OL_DEVICE_INFO_SIZE_TEST_NONZERO(ProductName, OL_DEVICE_INFO_PRODUCT_NAME);
+OL_DEVICE_INFO_SIZE_TEST_NONZERO(UID, OL_DEVICE_INFO_UID);
OL_DEVICE_INFO_SIZE_TEST_NONZERO(Vendor, OL_DEVICE_INFO_VENDOR);
OL_DEVICE_INFO_SIZE_TEST_NONZERO(DriverVersion, OL_DEVICE_INFO_DRIVER_VERSION);
OL_DEVICE_INFO_SIZE_TEST_EQ(MaxWorkGroupSize, uint32_t,
>From 7f8d296a5e05b173fe4aa4ec809a045f763a4f25 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Tue, 21 Oct 2025 13:58:21 -0500
Subject: [PATCH 02/11] align use of auto to the file
---
.../plugins-nextgen/common/src/PluginInterface.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 8d009948b6d46..76498648ff06c 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1528,21 +1528,21 @@ Error GenericDeviceTy::enqueueHostCall(void (*Callback)(void *), void *UserData,
}
Expected<InfoTreeNode> GenericDeviceTy::obtainInfo() {
- Expected<InfoTreeNode> Info = obtainInfoImpl();
- if (Info)
- Info->add("UID", DeviceUid, "", DeviceInfo::UID);
- return Info;
+ auto InfoOrErr = obtainInfoImpl();
+ if (InfoOrErr)
+ InfoOrErr->add("UID", getDeviceUid(), "", DeviceInfo::UID);
+ return InfoOrErr;
}
Error GenericDeviceTy::printInfo() {
- Expected<InfoTreeNode> Info = obtainInfo();
+ auto InfoOrErr = obtainInfo();
// Get the vendor-specific info entries describing the device properties.
- if (Error Err = Info.takeError())
+ if (auto Err = InfoOrErr.takeError())
return Err;
// Print all info entries.
- Info->print();
+ InfoOrErr->print();
return Plugin::success();
}
>From 957ca31fda122a92b412e9a6e09967045e324aa5 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Tue, 21 Oct 2025 14:31:15 -0500
Subject: [PATCH 03/11] add cuda UID
---
offload/plugins-nextgen/amdgpu/src/rtl.cpp | 2 +-
offload/plugins-nextgen/common/include/PluginInterface.h | 2 ++
offload/plugins-nextgen/common/src/PluginInterface.cpp | 4 ++++
offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp | 1 +
offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h | 2 ++
offload/plugins-nextgen/cuda/src/rtl.cpp | 6 ++++++
6 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index 0723e4bc5f035..785dcdf9992b5 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -2095,7 +2095,7 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
if (auto Err = getDeviceAttr(HSA_AMD_AGENT_INFO_UUID, Uuid))
return Err;
if (strcmp(Uuid + 3, "-XX") != 0)
- DeviceUid = std::string(Plugin.getName()) + "-" + std::string(Uuid);
+ setDeviceUidFromVendorUid(Uuid);
// Get the wavefront size.
uint32_t WavefrontSize = 0;
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 244f5cbdf9835..11c4296acef54 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1216,6 +1216,8 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// combined with the plugin name, since the offload device id may overlap
/// between different plugins.
std::string DeviceUid;
+ /// Construct the device UID from the vendor (U)UID.
+ void setDeviceUidFromVendorUid(const char *VendorUid);
/// The default grid values used for this device.
llvm::omp::GV GridValues;
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 76498648ff06c..d5895bc6457df 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1613,6 +1613,10 @@ Expected<bool> GenericDeviceTy::isAccessiblePtr(const void *Ptr, size_t Size) {
return isAccessiblePtrImpl(Ptr, Size);
}
+void GenericDeviceTy::setDeviceUidFromVendorUid(const char *VendorUid) {
+ DeviceUid = std::string(Plugin.getName()) + "-" + std::string(VendorUid);
+}
+
Error GenericPluginTy::init() {
if (Initialized)
return Plugin::success();
diff --git a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp
index f5b2d074a47e7..e7a1ca38b3c13 100644
--- a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp
+++ b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp
@@ -35,6 +35,7 @@ DLWRAP(cuFuncSetAttribute, 3)
// Device info
DLWRAP(cuDeviceGetName, 3)
+DLWRAP(cuDeviceGetUuid, 2)
DLWRAP(cuDeviceTotalMem, 2)
DLWRAP(cuDriverGetVersion, 1)
diff --git a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
index dec4e33508c62..cc1ba4b577645 100644
--- a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
+++ b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
@@ -33,6 +33,7 @@ typedef struct CUfunc_st *CUfunction;
typedef void (*CUhostFn)(void *userData);
typedef struct CUstream_st *CUstream;
typedef struct CUevent_st *CUevent;
+typedef struct CUuuid_st *CUuuid;
#define CU_DEVICE_INVALID ((CUdevice)(-2))
@@ -301,6 +302,7 @@ CUresult cuFuncSetAttribute(CUfunction, CUfunction_attribute, int);
// Device info
CUresult cuDeviceGetName(char *, int, CUdevice);
+CUresult cuDeviceGetUuid(CUuuid *, CUdevice);
CUresult cuDeviceTotalMem(size_t *, CUdevice);
CUresult cuDriverGetVersion(int *);
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index db94f7f2dd995..468581d522f51 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -293,6 +293,12 @@ struct CUDADeviceTy : public GenericDeviceTy {
if (auto Err = Plugin::check(Res, "error in cuDeviceGet: %s"))
return Err;
+ char Uuid[16];
+ Res = cuDeviceGetUuid(Uuid, Device);
+ if (auto Err = Plugin::check(Res, "error in cuDeviceGetUuid: %s"))
+ return Err;
+ setDeviceUidFromVendorUid(Uuid);
+
// Query the current flags of the primary context and set its flags if
// it is inactive.
unsigned int FormerPrimaryCtxFlags = 0;
>From 29e5560bbb5b8327334c831fcac516d1ce8a7795 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Tue, 21 Oct 2025 15:10:34 -0500
Subject: [PATCH 04/11] add device UID getter to plugin
---
offload/liboffload/src/OffloadImpl.cpp | 2 +-
.../plugins-nextgen/common/include/PluginInterface.h | 12 +++++++++++-
offload/plugins-nextgen/host/src/rtl.cpp | 2 +-
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index ed306470a0d76..84bc414396811 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -546,7 +546,7 @@ Error olGetDeviceInfoImplDetailHost(ol_device_handle_t Device,
case OL_DEVICE_INFO_PRODUCT_NAME:
return Info.writeString("Virtual Host Device");
case OL_DEVICE_INFO_UID:
- return Info.writeString(GenericDeviceTy::getHostDeviceUid());
+ return Info.writeString(GenericPluginTy::getHostDeviceUid());
case OL_DEVICE_INFO_VENDOR:
return Info.writeString("Liboffload");
case OL_DEVICE_INFO_DRIVER_VERSION:
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 11c4296acef54..34f8799d596d2 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -793,7 +793,6 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// Get the unique identifier of the device.
const char *getDeviceUid() const { return DeviceUid.c_str(); }
- static constexpr const char *getHostDeviceUid() { return "HOST"; }
/// Set the context of the device if needed, before calling device-specific
/// functions. Plugins may implement this function as a no-op if not needed.
@@ -1295,6 +1294,9 @@ struct GenericPluginTy {
return *Devices[DeviceId];
}
+ const GenericDeviceTy &getDevice(int32_t DeviceId) const {
+ return cast<const GenericDeviceTy>(getDevice(DeviceId));
+ }
/// Get the number of active devices.
int32_t getNumDevices() const { return NumDevices; }
@@ -1305,6 +1307,14 @@ struct GenericPluginTy {
return UserDeviceIds.at(DeviceId);
}
+ /// Get the UID for the given device.
+ const char *getDeviceUid(int32_t DeviceId) const {
+ return getDevice(DeviceId).getDeviceUid();
+ }
+
+ /// Get the UID for the host device.
+ static constexpr const char *getHostDeviceUid() { return "HOST"; }
+
/// Get the ELF code to recognize the binary image of this plugin.
virtual uint16_t getMagicElfBits() const = 0;
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index f75c9cd29b2ad..38201433193f2 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -149,7 +149,7 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
GenELF64DeviceTy(GenericPluginTy &Plugin, int32_t DeviceId,
int32_t NumDevices)
: GenericDeviceTy(Plugin, DeviceId, NumDevices, GenELF64GridValues) {
- DeviceUid = getHostDeviceUid();
+ DeviceUid = Plugin.getHostDeviceUid();
}
~GenELF64DeviceTy() {}
>From 7c753ef2f862f9d91c21f909f515adfa08e99929 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Wed, 22 Oct 2025 07:07:25 -0500
Subject: [PATCH 05/11] make virtual host devices have UIDs different from the
initial device
---
offload/liboffload/src/OffloadImpl.cpp | 2 +-
offload/plugins-nextgen/common/include/PluginInterface.h | 4 ++--
offload/plugins-nextgen/host/src/rtl.cpp | 4 +---
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 84bc414396811..8a117e6bcad15 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -546,7 +546,7 @@ Error olGetDeviceInfoImplDetailHost(ol_device_handle_t Device,
case OL_DEVICE_INFO_PRODUCT_NAME:
return Info.writeString("Virtual Host Device");
case OL_DEVICE_INFO_UID:
- return Info.writeString(GenericPluginTy::getHostDeviceUid());
+ return Info.writeString(GenericPluginTy::getInitialDeviceUid());
case OL_DEVICE_INFO_VENDOR:
return Info.writeString("Liboffload");
case OL_DEVICE_INFO_DRIVER_VERSION:
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 34f8799d596d2..d0f8f459e3b5e 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1312,8 +1312,8 @@ struct GenericPluginTy {
return getDevice(DeviceId).getDeviceUid();
}
- /// Get the UID for the host device.
- static constexpr const char *getHostDeviceUid() { return "HOST"; }
+ /// Get the UID for the initial (= host) device.
+ static constexpr const char *getInitialDeviceUid() { return "HOST"; }
/// Get the ELF code to recognize the binary image of this plugin.
virtual uint16_t getMagicElfBits() const = 0;
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index 38201433193f2..eb4ecac9907a1 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -148,9 +148,7 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
/// Create the device with a specific id.
GenELF64DeviceTy(GenericPluginTy &Plugin, int32_t DeviceId,
int32_t NumDevices)
- : GenericDeviceTy(Plugin, DeviceId, NumDevices, GenELF64GridValues) {
- DeviceUid = Plugin.getHostDeviceUid();
- }
+ : GenericDeviceTy(Plugin, DeviceId, NumDevices, GenELF64GridValues) {}
~GenELF64DeviceTy() {}
>From 34dd9dd869da557c191c5842000e8b9fb850fb7b Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Wed, 22 Oct 2025 07:38:50 -0500
Subject: [PATCH 06/11] fix const getDevice() call
---
offload/plugins-nextgen/common/include/PluginInterface.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index d0f8f459e3b5e..dcb51b8e8e13d 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1295,7 +1295,7 @@ struct GenericPluginTy {
return *Devices[DeviceId];
}
const GenericDeviceTy &getDevice(int32_t DeviceId) const {
- return cast<const GenericDeviceTy>(getDevice(DeviceId));
+ return const_cast<GenericPluginTy *>(this)->getDevice(DeviceId);
}
/// Get the number of active devices.
>From 04ba6a5557f49216419bd82df5ac082f447f536b Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Wed, 22 Oct 2025 09:38:35 -0500
Subject: [PATCH 07/11] fix cuda plugin UID
---
offload/plugins-nextgen/amdgpu/src/rtl.cpp | 2 +-
offload/plugins-nextgen/common/include/PluginInterface.h | 2 +-
offload/plugins-nextgen/common/src/PluginInterface.cpp | 2 +-
offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h | 4 +++-
offload/plugins-nextgen/cuda/src/rtl.cpp | 7 ++++---
5 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index 785dcdf9992b5..1a9fd4011950e 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -2091,7 +2091,7 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
//
// Agents that do not support UUID will return the string "GPU-XX" or
// "CPU-XX" or "DSP-XX" depending on their device type.
- char Uuid[24];
+ char Uuid[24] = {0};
if (auto Err = getDeviceAttr(HSA_AMD_AGENT_INFO_UUID, Uuid))
return Err;
if (strcmp(Uuid + 3, "-XX") != 0)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index dcb51b8e8e13d..daff77a6d591f 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1216,7 +1216,7 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// between different plugins.
std::string DeviceUid;
/// Construct the device UID from the vendor (U)UID.
- void setDeviceUidFromVendorUid(const char *VendorUid);
+ void setDeviceUidFromVendorUid(StringRef VendorUid);
/// The default grid values used for this device.
llvm::omp::GV GridValues;
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index d5895bc6457df..c7862d9088177 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1613,7 +1613,7 @@ Expected<bool> GenericDeviceTy::isAccessiblePtr(const void *Ptr, size_t Size) {
return isAccessiblePtrImpl(Ptr, Size);
}
-void GenericDeviceTy::setDeviceUidFromVendorUid(const char *VendorUid) {
+void GenericDeviceTy::setDeviceUidFromVendorUid(StringRef VendorUid) {
DeviceUid = std::string(Plugin.getName()) + "-" + std::string(VendorUid);
}
diff --git a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
index cc1ba4b577645..a470d6df1079d 100644
--- a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
+++ b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
@@ -33,7 +33,9 @@ typedef struct CUfunc_st *CUfunction;
typedef void (*CUhostFn)(void *userData);
typedef struct CUstream_st *CUstream;
typedef struct CUevent_st *CUevent;
-typedef struct CUuuid_st *CUuuid;
+typedef struct CUuuid_st {
+ char bytes[16];
+} CUuuid;
#define CU_DEVICE_INVALID ((CUdevice)(-2))
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index 468581d522f51..aecbb17217c04 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -25,6 +25,7 @@
#include "PluginInterface.h"
#include "Utils/ELF.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
@@ -293,11 +294,11 @@ struct CUDADeviceTy : public GenericDeviceTy {
if (auto Err = Plugin::check(Res, "error in cuDeviceGet: %s"))
return Err;
- char Uuid[16];
- Res = cuDeviceGetUuid(Uuid, Device);
+ CUuuid Uuid = {0};
+ Res = cuDeviceGetUuid(&Uuid, Device);
if (auto Err = Plugin::check(Res, "error in cuDeviceGetUuid: %s"))
return Err;
- setDeviceUidFromVendorUid(Uuid);
+ setDeviceUidFromVendorUid(toHex(Uuid.bytes, true));
// Query the current flags of the primary context and set its flags if
// it is inactive.
>From 30a3437ee1763574df0c939482ce48a06dc00d16 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Wed, 22 Oct 2025 10:44:22 -0500
Subject: [PATCH 08/11] capitalize UUID; use StringRef::ends_with
---
offload/plugins-nextgen/amdgpu/src/rtl.cpp | 8 ++++----
offload/plugins-nextgen/cuda/src/rtl.cpp | 6 +++---
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index 1a9fd4011950e..928c6cd7569e3 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -2091,11 +2091,11 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
//
// Agents that do not support UUID will return the string "GPU-XX" or
// "CPU-XX" or "DSP-XX" depending on their device type.
- char Uuid[24] = {0};
- if (auto Err = getDeviceAttr(HSA_AMD_AGENT_INFO_UUID, Uuid))
+ char UUID[24] = {0};
+ if (auto Err = getDeviceAttr(HSA_AMD_AGENT_INFO_UUID, UUID))
return Err;
- if (strcmp(Uuid + 3, "-XX") != 0)
- setDeviceUidFromVendorUid(Uuid);
+ if (!StringRef(UUID).ends_with("-XX"))
+ setDeviceUidFromVendorUid(UUID);
// Get the wavefront size.
uint32_t WavefrontSize = 0;
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index aecbb17217c04..a9adcc397fb7b 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -294,11 +294,11 @@ struct CUDADeviceTy : public GenericDeviceTy {
if (auto Err = Plugin::check(Res, "error in cuDeviceGet: %s"))
return Err;
- CUuuid Uuid = {0};
- Res = cuDeviceGetUuid(&Uuid, Device);
+ CUuuid UUID = {0};
+ Res = cuDeviceGetUuid(&UUID, Device);
if (auto Err = Plugin::check(Res, "error in cuDeviceGetUuid: %s"))
return Err;
- setDeviceUidFromVendorUid(toHex(Uuid.bytes, true));
+ setDeviceUidFromVendorUid(toHex(UUID.bytes, true));
// Query the current flags of the primary context and set its flags if
// it is inactive.
>From fff258a67adca8fc6acd89a87de31a7ac22ec89d Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Thu, 23 Oct 2025 02:19:12 -0500
Subject: [PATCH 09/11] rename getInitialDeviceUid to getHostDeviceUid again
---
offload/liboffload/src/OffloadImpl.cpp | 2 +-
offload/plugins-nextgen/common/include/PluginInterface.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 8a117e6bcad15..84bc414396811 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -546,7 +546,7 @@ Error olGetDeviceInfoImplDetailHost(ol_device_handle_t Device,
case OL_DEVICE_INFO_PRODUCT_NAME:
return Info.writeString("Virtual Host Device");
case OL_DEVICE_INFO_UID:
- return Info.writeString(GenericPluginTy::getInitialDeviceUid());
+ return Info.writeString(GenericPluginTy::getHostDeviceUid());
case OL_DEVICE_INFO_VENDOR:
return Info.writeString("Liboffload");
case OL_DEVICE_INFO_DRIVER_VERSION:
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index daff77a6d591f..2d5140988b02f 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1312,8 +1312,8 @@ struct GenericPluginTy {
return getDevice(DeviceId).getDeviceUid();
}
- /// Get the UID for the initial (= host) device.
- static constexpr const char *getInitialDeviceUid() { return "HOST"; }
+ /// Get the UID for the host device.
+ static constexpr const char *getHostDeviceUid() { return "HOST"; }
/// Get the ELF code to recognize the binary image of this plugin.
virtual uint16_t getMagicElfBits() const = 0;
>From c2464ee43adac7be2ab7a06ca6778c626f0e79c7 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 24 Oct 2025 09:04:46 -0500
Subject: [PATCH 10/11] duplicate getDevice() implementation to avoid
const_cast
---
offload/plugins-nextgen/common/include/PluginInterface.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 2d5140988b02f..c6b43f5c9f524 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1295,7 +1295,10 @@ struct GenericPluginTy {
return *Devices[DeviceId];
}
const GenericDeviceTy &getDevice(int32_t DeviceId) const {
- return const_cast<GenericPluginTy *>(this)->getDevice(DeviceId);
+ assert(isValidDeviceId(DeviceId) && "Invalid device id");
+ assert(Devices[DeviceId] && "Device is uninitialized");
+
+ return *Devices[DeviceId];
}
/// Get the number of active devices.
>From a35b1be493a003ac6a00117103d7445a41f246d4 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 24 Oct 2025 09:18:30 -0500
Subject: [PATCH 11/11] remove plugin-level getDeviceUid()
---
.../plugins-nextgen/common/include/PluginInterface.h | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index c6b43f5c9f524..f9dcdea7213fd 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1294,12 +1294,6 @@ struct GenericPluginTy {
return *Devices[DeviceId];
}
- const GenericDeviceTy &getDevice(int32_t DeviceId) const {
- assert(isValidDeviceId(DeviceId) && "Invalid device id");
- assert(Devices[DeviceId] && "Device is uninitialized");
-
- return *Devices[DeviceId];
- }
/// Get the number of active devices.
int32_t getNumDevices() const { return NumDevices; }
@@ -1310,11 +1304,6 @@ struct GenericPluginTy {
return UserDeviceIds.at(DeviceId);
}
- /// Get the UID for the given device.
- const char *getDeviceUid(int32_t DeviceId) const {
- return getDevice(DeviceId).getDeviceUid();
- }
-
/// Get the UID for the host device.
static constexpr const char *getHostDeviceUid() { return "HOST"; }
More information about the llvm-commits
mailing list