summaryrefslogtreecommitdiff
path: root/offload/plugins-nextgen
diff options
context:
space:
mode:
Diffstat (limited to 'offload/plugins-nextgen')
-rw-r--r--offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h1
-rw-r--r--offload/plugins-nextgen/amdgpu/src/rtl.cpp14
-rw-r--r--offload/plugins-nextgen/common/include/PluginInterface.h19
-rw-r--r--offload/plugins-nextgen/common/src/PluginInterface.cpp21
-rw-r--r--offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp1
-rw-r--r--offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h4
-rw-r--r--offload/plugins-nextgen/cuda/src/rtl.cpp7
7 files changed, 63 insertions, 4 deletions
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 29cfe78082db..ddfa65c76cf2 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 0b03ef534d27..928c6cd7569e 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] = {0};
+ if (auto Err = getDeviceAttr(HSA_AMD_AGENT_INFO_UUID, UUID))
+ return Err;
+ if (!StringRef(UUID).ends_with("-XX"))
+ setDeviceUidFromVendorUid(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 f9bff9abd903..f9dcdea7213f 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -791,6 +791,9 @@ 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(); }
+
/// 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 +992,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 +1210,14 @@ protected:
/// 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;
+ /// Construct the device UID from the vendor (U)UID.
+ void setDeviceUidFromVendorUid(StringRef VendorUid);
+
/// The default grid values used for this device.
llvm::omp::GV GridValues;
@@ -1290,6 +1304,9 @@ struct GenericPluginTy {
return UserDeviceIds.at(DeviceId);
}
+ /// 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/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 36d643b65922..d7e5a21600ab 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -715,6 +715,10 @@ GenericDeviceTy::GenericDeviceTy(GenericPluginTy &Plugin, int32_t DeviceId,
DeviceId(DeviceId), GridValues(OMPGridValues),
PeerAccesses(NumDevices, PeerAccessState::PENDING), PeerAccessesLock(),
PinnedAllocs(*this), RPCServer(nullptr) {
+ // Conservative fall-back to the plugin's device uid for the case that no real
+ // vendor (u)uid will become available later.
+ setDeviceUidFromVendorUid(std::to_string(static_cast<uint64_t>(DeviceId)));
+
#ifdef OMPT_SUPPORT
OmptInitialized.store(false);
// Bind the callbacks to this device's member functions
@@ -1524,15 +1528,22 @@ Error GenericDeviceTy::enqueueHostCall(void (*Callback)(void *), void *UserData,
return Err;
}
+Expected<InfoTreeNode> GenericDeviceTy::obtainInfo() {
+ auto InfoOrErr = obtainInfoImpl();
+ if (InfoOrErr)
+ InfoOrErr->add("UID", getDeviceUid(), "", DeviceInfo::UID);
+ return InfoOrErr;
+}
+
Error GenericDeviceTy::printInfo() {
- auto Info = obtainInfoImpl();
+ auto InfoOrErr = obtainInfo();
// Get the vendor-specific info entries describing the device properties.
- if (auto Err = Info.takeError())
+ if (auto Err = InfoOrErr.takeError())
return Err;
// Print all info entries.
- Info->print();
+ InfoOrErr->print();
return Plugin::success();
}
@@ -1603,6 +1614,10 @@ Expected<bool> GenericDeviceTy::isAccessiblePtr(const void *Ptr, size_t Size) {
return isAccessiblePtrImpl(Ptr, Size);
}
+void GenericDeviceTy::setDeviceUidFromVendorUid(StringRef 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 f5b2d074a47e..e7a1ca38b3c1 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 dec4e33508c6..a470d6df1079 100644
--- a/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
+++ b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h
@@ -33,6 +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 {
+ char bytes[16];
+} CUuuid;
#define CU_DEVICE_INVALID ((CUdevice)(-2))
@@ -301,6 +304,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 db94f7f2dd99..a9adcc397fb7 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,6 +294,12 @@ struct CUDADeviceTy : public GenericDeviceTy {
if (auto Err = Plugin::check(Res, "error in cuDeviceGet: %s"))
return Err;
+ CUuuid UUID = {0};
+ Res = cuDeviceGetUuid(&UUID, Device);
+ if (auto Err = Plugin::check(Res, "error in cuDeviceGetUuid: %s"))
+ return Err;
+ setDeviceUidFromVendorUid(toHex(UUID.bytes, true));
+
// Query the current flags of the primary context and set its flags if
// it is inactive.
unsigned int FormerPrimaryCtxFlags = 0;