summaryrefslogtreecommitdiff
path: root/offload/liboffload
diff options
context:
space:
mode:
authorRafal Bielski <rafal.bielski@codeplay.com>2025-08-19 13:02:01 +0100
committerGitHub <noreply@github.com>2025-08-19 13:02:01 +0100
commit9c9d9e4cb6dfd8a3cada7fb6c8b4dc2b77b5514c (patch)
tree0c07d20f0f49b1b2ef60b96df3f6995b963b30c5 /offload/liboffload
parentfcb36ca8ccd073c110cfc44b92f78562811f2ce9 (diff)
[Offload] Define additional device info properties (#152533)
Add the following properties in Offload device info: * VENDOR_ID * NUM_COMPUTE_UNITS * [SINGLE|DOUBLE|HALF]_FP_CONFIG * NATIVE_VECTOR_WIDTH_[CHAR|SHORT|INT|LONG|FLOAT|DOUBLE|HALF] * MAX_CLOCK_FREQUENCY * MEMORY_CLOCK_RATE * ADDRESS_BITS * MAX_MEM_ALLOC_SIZE * GLOBAL_MEM_SIZE Add a bitfield option to enumerators, allowing the values to be bit-shifted instead of incremented. Generate the per-type enums using `foreach` to reduce code duplication. Use macros in unit test definitions to reduce code duplication.
Diffstat (limited to 'offload/liboffload')
-rw-r--r--offload/liboffload/API/APIDefs.td4
-rw-r--r--offload/liboffload/API/Device.td34
-rw-r--r--offload/liboffload/src/OffloadImpl.cpp93
3 files changed, 126 insertions, 5 deletions
diff --git a/offload/liboffload/API/APIDefs.td b/offload/liboffload/API/APIDefs.td
index bd4cbbaa546b..a30307fc9084 100644
--- a/offload/liboffload/API/APIDefs.td
+++ b/offload/liboffload/API/APIDefs.td
@@ -176,6 +176,10 @@ class Enum : APIObject {
// all Etor values must be TaggedEtor records
bit is_typed = 0;
+ // This refers to whether the enumerator is used to name bits of a bit field,
+ // where consecutive values are bit-shifted rather than incremented.
+ bit is_bit_field = 0;
+
list<Etor> etors = [];
}
diff --git a/offload/liboffload/API/Device.td b/offload/liboffload/API/Device.td
index 857c596124b2..f9ba184759c2 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -26,7 +26,7 @@ def DeviceInfo : Enum {
let name = "ol_device_info_t";
let desc = "Supported device info.";
let is_typed = 1;
- let etors =[
+ list<TaggedEtor> basic_etors =[
TaggedEtor<"TYPE", "ol_device_type_t", "type of the device">,
TaggedEtor<"PLATFORM", "ol_platform_handle_t", "the platform associated with the device">,
TaggedEtor<"NAME", "char[]", "Device name">,
@@ -34,9 +34,41 @@ def DeviceInfo : Enum {
TaggedEtor<"DRIVER_VERSION", "char[]", "Driver version">,
TaggedEtor<"MAX_WORK_GROUP_SIZE", "uint32_t", "Maximum total work group size in work items">,
TaggedEtor<"MAX_WORK_GROUP_SIZE_PER_DIMENSION", "ol_dimensions_t", "Maximum work group size in each dimension">,
+ TaggedEtor<"VENDOR_ID", "uint32_t", "A unique vendor device identifier assigned by PCI-SIG">,
+ TaggedEtor<"NUM_COMPUTE_UNITS", "uint32_t", "The number of parallel compute units available to the device">,
+ TaggedEtor<"MAX_CLOCK_FREQUENCY", "uint32_t", "The maximum configured clock frequency of this device in MHz">,
+ TaggedEtor<"MEMORY_CLOCK_RATE", "uint32_t", "Memory clock frequency in MHz">,
+ TaggedEtor<"ADDRESS_BITS", "uint32_t", "Number of bits used to represent an address in device memory">,
+ TaggedEtor<"MAX_MEM_ALLOC_SIZE", "uint64_t", "The maximum size of memory object allocation in bytes">,
+ TaggedEtor<"GLOBAL_MEM_SIZE", "uint64_t", "The size of global device memory in bytes">,
+ ];
+ list<TaggedEtor> fp_configs = !foreach(type, ["Single", "Double", "Half"], TaggedEtor<type # "_FP_CONFIG", "ol_device_fp_capability_flags_t", type # " precision floating point capability">);
+ list<TaggedEtor> native_vec_widths = !foreach(type, ["char","short","int","long","float","double","half"], TaggedEtor<"NATIVE_VECTOR_WIDTH_" # type, "uint32_t", "Native vector width for " # type>);
+ let etors = !listconcat(basic_etors, fp_configs, native_vec_widths);
+}
+
+def : Enum {
+ let name = "ol_device_fp_capability_flag_t";
+ let desc = "Device floating-point capability flags";
+ let is_bit_field = 1;
+ let etors =[
+ Etor<"CORRECTLY_ROUNDED_DIVIDE_SQRT", "Support correctly rounded divide and sqrt">,
+ Etor<"ROUND_TO_NEAREST", "Support round to nearest">,
+ Etor<"ROUND_TO_ZERO", "Support round to zero">,
+ Etor<"ROUND_TO_INF", "Support round to infinity">,
+ Etor<"INF_NAN", "Support INF to NAN">,
+ Etor<"DENORM", "Support denorm">,
+ Etor<"FMA", "Support fused multiply-add">,
+ Etor<"SOFT_FLOAT", "Basic floating point operations implemented in software">,
];
}
+def : Typedef {
+ let name = "ol_device_fp_capability_flags_t";
+ let desc = "Device floating-point capability flags";
+ let value = "uint32_t";
+}
+
def : FptrTypedef {
let name = "ol_device_iterate_cb_t";
let desc = "User-provided function to be used with `olIterateDevices`";
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 1c9dfc69d445..cfb3342016f4 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -302,10 +302,50 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
};
// These are not implemented by the plugin interface
- if (PropName == OL_DEVICE_INFO_PLATFORM)
+ switch (PropName) {
+ case OL_DEVICE_INFO_PLATFORM:
return Info.write<void *>(Device->Platform);
- if (PropName == OL_DEVICE_INFO_TYPE)
+
+ case OL_DEVICE_INFO_TYPE:
return Info.write<ol_device_type_t>(OL_DEVICE_TYPE_GPU);
+
+ case OL_DEVICE_INFO_SINGLE_FP_CONFIG:
+ case OL_DEVICE_INFO_DOUBLE_FP_CONFIG: {
+ ol_device_fp_capability_flags_t flags{0};
+ flags |= OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT |
+ OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST |
+ OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO |
+ OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF |
+ OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN |
+ OL_DEVICE_FP_CAPABILITY_FLAG_DENORM |
+ OL_DEVICE_FP_CAPABILITY_FLAG_FMA;
+ return Info.write(flags);
+ }
+
+ case OL_DEVICE_INFO_HALF_FP_CONFIG:
+ return Info.write<ol_device_fp_capability_flags_t>(0);
+
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE:
+ return Info.write<uint32_t>(1);
+
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF:
+ return Info.write<uint32_t>(0);
+
+ // None of the existing plugins specify a limit on a single allocation,
+ // so return the global memory size instead
+ case OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE:
+ PropName = OL_DEVICE_INFO_GLOBAL_MEM_SIZE;
+ break;
+
+ default:
+ break;
+ }
+
if (PropName >= OL_DEVICE_INFO_LAST)
return createOffloadError(ErrorCode::INVALID_ENUMERATION,
"getDeviceInfo enum '%i' is invalid", PropName);
@@ -316,6 +356,7 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
"plugin did not provide a response for this information");
auto Entry = *EntryOpt;
+ // Retrieve properties from the plugin interface
switch (PropName) {
case OL_DEVICE_INFO_NAME:
case OL_DEVICE_INFO_VENDOR:
@@ -327,7 +368,20 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
return Info.writeString(std::get<std::string>(Entry->Value).c_str());
}
- case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE: {
+ case OL_DEVICE_INFO_GLOBAL_MEM_SIZE: {
+ // Uint64 values
+ if (!std::holds_alternative<uint64_t>(Entry->Value))
+ return makeError(ErrorCode::BACKEND_FAILURE,
+ "plugin returned incorrect type");
+ return Info.write(std::get<uint64_t>(Entry->Value));
+ }
+
+ case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE:
+ case OL_DEVICE_INFO_VENDOR_ID:
+ case OL_DEVICE_INFO_NUM_COMPUTE_UNITS:
+ case OL_DEVICE_INFO_ADDRESS_BITS:
+ case OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY:
+ case OL_DEVICE_INFO_MEMORY_CLOCK_RATE: {
// Uint32 values
if (!std::holds_alternative<uint64_t>(Entry->Value))
return makeError(ErrorCode::BACKEND_FAILURE,
@@ -389,9 +443,40 @@ Error olGetDeviceInfoImplDetailHost(ol_device_handle_t Device,
case OL_DEVICE_INFO_DRIVER_VERSION:
return Info.writeString(LLVM_VERSION_STRING);
case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE:
- return Info.write<uint64_t>(1);
+ return Info.write<uint32_t>(1);
case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE_PER_DIMENSION:
return Info.write<ol_dimensions_t>(ol_dimensions_t{1, 1, 1});
+ case OL_DEVICE_INFO_VENDOR_ID:
+ return Info.write<uint32_t>(0);
+ case OL_DEVICE_INFO_NUM_COMPUTE_UNITS:
+ return Info.write<uint32_t>(1);
+ case OL_DEVICE_INFO_SINGLE_FP_CONFIG:
+ case OL_DEVICE_INFO_DOUBLE_FP_CONFIG:
+ return Info.write<ol_device_fp_capability_flags_t>(
+ OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT |
+ OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST |
+ OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO |
+ OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF |
+ OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN |
+ OL_DEVICE_FP_CAPABILITY_FLAG_DENORM | OL_DEVICE_FP_CAPABILITY_FLAG_FMA);
+ case OL_DEVICE_INFO_HALF_FP_CONFIG:
+ return Info.write<ol_device_fp_capability_flags_t>(0);
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT:
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE:
+ return Info.write<uint32_t>(1);
+ case OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF:
+ return Info.write<uint32_t>(0);
+ case OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY:
+ case OL_DEVICE_INFO_MEMORY_CLOCK_RATE:
+ case OL_DEVICE_INFO_ADDRESS_BITS:
+ return Info.write<uint32_t>(std::numeric_limits<uintptr_t>::digits);
+ case OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE:
+ case OL_DEVICE_INFO_GLOBAL_MEM_SIZE:
+ return Info.write<uint64_t>(0);
default:
return createOffloadError(ErrorCode::INVALID_ENUMERATION,
"getDeviceInfo enum '%i' is invalid", PropName);