diff options
| author | Rafal Bielski <rafal.bielski@codeplay.com> | 2025-08-19 13:02:01 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-19 13:02:01 +0100 |
| commit | 9c9d9e4cb6dfd8a3cada7fb6c8b4dc2b77b5514c (patch) | |
| tree | 0c07d20f0f49b1b2ef60b96df3f6995b963b30c5 /offload/liboffload | |
| parent | fcb36ca8ccd073c110cfc44b92f78562811f2ce9 (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.td | 4 | ||||
| -rw-r--r-- | offload/liboffload/API/Device.td | 34 | ||||
| -rw-r--r-- | offload/liboffload/src/OffloadImpl.cpp | 93 |
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); |
