[llvm] [Offload] Define additional device info properties (PR #152533)

Rafal Bielski via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 8 09:00:33 PDT 2025


https://github.com/rafbiels updated https://github.com/llvm/llvm-project/pull/152533

>From b391017e18b7bb8cf1c1d8a8b3187cb0e439dc6f Mon Sep 17 00:00:00 2001
From: Rafal Bielski <rafal.bielski at codeplay.com>
Date: Mon, 4 Aug 2025 15:27:28 +0100
Subject: [PATCH] [Offload] Define additional device info properties

Add the following properties in Offload device info:
* VENDOR_ID
* NUM_COMPUTE_UNITS
* [SINGLE|DOUBLE|HALF]_FP_CONFIG
* PREFERRED_VECTOR_WIDTH_[CHAR|SHORT|INT|LONG|FLOAT|DOUBLE|HALF]
* 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

Introduce templated enumerators in Offload TableGen to reduce
code duplication for the per-type definitions.

Use macros in unit test definitions to reduce code duplication.
---
 offload/liboffload/API/APIDefs.td             |  16 +++
 offload/liboffload/API/Device.td              |  32 ++++++
 offload/liboffload/src/OffloadImpl.cpp        | 107 +++++++++++++++++-
 .../plugins-nextgen/amdgpu/dynamic_hsa/hsa.h  |   6 +
 .../amdgpu/dynamic_hsa/hsa_ext_amd.h          |   1 +
 offload/plugins-nextgen/amdgpu/src/rtl.cpp    |  25 +++-
 offload/plugins-nextgen/cuda/src/rtl.cpp      |  17 ++-
 offload/tools/offload-tblgen/APIGen.cpp       |  29 +++--
 offload/tools/offload-tblgen/MiscGen.cpp      |  22 +++-
 offload/tools/offload-tblgen/PrintGen.cpp     |  58 ++++++----
 offload/tools/offload-tblgen/RecordTypes.hpp  |  37 +++++-
 .../OffloadAPI/device/olGetDeviceInfo.cpp     |  94 ++++++++++++++-
 .../OffloadAPI/device/olGetDeviceInfoSize.cpp |  99 ++++++++++------
 13 files changed, 453 insertions(+), 90 deletions(-)

diff --git a/offload/liboffload/API/APIDefs.td b/offload/liboffload/API/APIDefs.td
index 640932dcf8464..3460d6842a2e6 100644
--- a/offload/liboffload/API/APIDefs.td
+++ b/offload/liboffload/API/APIDefs.td
@@ -158,16 +158,32 @@ class Etor<string Name, string Desc> {
   string tagged_type;
 }
 
+class EtorTemplate<string Name, string Desc, list<string> TemplateValues> : Etor<Name, Desc> {
+  // Create Etor for every value in template_values by replacing the string
+  // "%TEMPLATE%" with the template value in the name and description
+  list<string> template_values = TemplateValues;
+}
+
 class TaggedEtor<string Name, string Type, string Desc> : Etor<Name, Desc> {
   let tagged_type = Type;
 }
 
+class TaggedEtorTemplate<string Name, string Type, string Desc, list<string> TemplateValues> : TaggedEtor<Name, Type, Desc> {
+  // Create TaggedEtor for every value in template_values by replacing the
+  // string "%TEMPLATE%" with the template value in the name and description
+  list<string> template_values = TemplateValues;
+}
+
 class Enum : APIObject {
   // This refers to whether the enumerator descriptions specify a return
   // type for functions where this enum may be used as an output type. If set,
   // 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 857c596124b27..2cd9dc1e4758e 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -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">,
+    TaggedEtorTemplate<"%TEMPLATE%_FP_CONFIG", "ol_device_fp_capability_flags_t", "%TEMPLATE% precision floating point capability", ["Single","Half","Double"]>,
+    TaggedEtorTemplate<"PREFERRED_VECTOR_WIDTH_%TEMPLATE%", "uint32_t", "Preferred vector width for %TEMPLATE%", ["char","short","int","long","float","double","half"]>,
+    TaggedEtorTemplate<"NATIVE_VECTOR_WIDTH_%TEMPLATE%", "uint32_t", "Native vector width for %TEMPLATE%", ["char","short","int","long","float","double","half"]>,
+    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">,
   ];
 }
 
+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 272a12ab59a06..bc03e51bc2664 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -302,10 +302,57 @@ 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_PREFERRED_VECTOR_WIDTH_CHAR:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_SHORT:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_INT:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_LONG:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_FLOAT:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_DOUBLE:
+  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_PREFERRED_VECTOR_WIDTH_HALF:
+  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 +363,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 +375,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 +450,47 @@ 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_PREFERRED_VECTOR_WIDTH_CHAR:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_SHORT:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_INT:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_LONG:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_FLOAT:
+  case OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_DOUBLE:
+  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_PREFERRED_VECTOR_WIDTH_HALF:
+  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);
diff --git a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
index 61f680bab3a07..ad135f72fff12 100644
--- a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
+++ b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h
@@ -70,10 +70,16 @@ typedef enum {
   HSA_ISA_INFO_NAME = 1
 } hsa_isa_info_t;
 
+typedef enum {
+  HSA_MACHINE_MODEL_SMALL = 0,
+  HSA_MACHINE_MODEL_LARGE = 1
+} hsa_machine_model_t;
+
 typedef enum {
   HSA_AGENT_INFO_NAME = 0,
   HSA_AGENT_INFO_VENDOR_NAME = 1,
   HSA_AGENT_INFO_FEATURE = 2,
+  HSA_AGENT_INFO_MACHINE_MODEL = 3,
   HSA_AGENT_INFO_PROFILE = 4,
   HSA_AGENT_INFO_WAVEFRONT_SIZE = 6,
   HSA_AGENT_INFO_WORKGROUP_MAX_DIM = 7,
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 3117763e35896..29cfe78082dbb 100644
--- a/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h
+++ b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h
@@ -67,6 +67,7 @@ typedef enum hsa_amd_agent_info_s {
   HSA_AMD_AGENT_INFO_CACHELINE_SIZE = 0xA001,
   HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT = 0xA002,
   HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY = 0xA003,
+  HSA_AMD_AGENT_INFO_MEMORY_MAX_FREQUENCY = 0xA008,
   HSA_AMD_AGENT_INFO_PRODUCT_NAME = 0xA009,
   HSA_AMD_AGENT_INFO_MAX_WAVES_PER_CU = 0xA00A,
   HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU = 0xA00B,
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index 852c0e99b2266..20d8994f97a39 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -2643,6 +2643,15 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
     if (Status == HSA_STATUS_SUCCESS)
       Info.add("Vendor Name", TmpChar, "", DeviceInfo::VENDOR);
 
+    Info.add("Vendor ID", uint64_t{4130}, "", DeviceInfo::VENDOR_ID);
+
+    hsa_machine_model_t MachineModel;
+    Status = getDeviceAttrRaw(HSA_AGENT_INFO_MACHINE_MODEL, MachineModel);
+    if (Status == HSA_STATUS_SUCCESS)
+      Info.add("Memory Address Size",
+               uint64_t{MachineModel == HSA_MACHINE_MODEL_SMALL ? 32u : 64u},
+               "bits", DeviceInfo::ADDRESS_BITS);
+
     hsa_device_type_t DevType;
     Status = getDeviceAttrRaw(HSA_AGENT_INFO_DEVICE, DevType);
     if (Status == HSA_STATUS_SUCCESS) {
@@ -2693,11 +2702,17 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
 
     Status = getDeviceAttrRaw(HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY, TmpUInt);
     if (Status == HSA_STATUS_SUCCESS)
-      Info.add("Max Clock Freq", TmpUInt, "MHz");
+      Info.add("Max Clock Freq", TmpUInt, "MHz",
+               DeviceInfo::MAX_CLOCK_FREQUENCY);
+
+    Status = getDeviceAttrRaw(HSA_AMD_AGENT_INFO_MEMORY_MAX_FREQUENCY, TmpUInt);
+    if (Status == HSA_STATUS_SUCCESS)
+      Info.add("Max Memory Clock Freq", TmpUInt, "MHz",
+               DeviceInfo::MEMORY_CLOCK_RATE);
 
     Status = getDeviceAttrRaw(HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, TmpUInt);
     if (Status == HSA_STATUS_SUCCESS)
-      Info.add("Compute Units", TmpUInt);
+      Info.add("Compute Units", TmpUInt, "", DeviceInfo::NUM_COMPUTE_UNITS);
 
     Status = getDeviceAttrRaw(HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU, TmpUInt);
     if (Status == HSA_STATUS_SUCCESS)
@@ -2779,7 +2794,11 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
 
       Status = Pool->getAttrRaw(HSA_AMD_MEMORY_POOL_INFO_SIZE, TmpSt);
       if (Status == HSA_STATUS_SUCCESS)
-        PoolNode.add("Size", TmpSt, "bytes");
+        PoolNode.add(
+            "Size", TmpSt, "bytes",
+            (Pool->isGlobal() && Pool->isCoarseGrained())
+                ? std::optional<DeviceInfo>{DeviceInfo::GLOBAL_MEM_SIZE}
+                : std::nullopt);
 
       Status = Pool->getAttrRaw(HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED,
                                 TmpBool);
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index 7649fd9285bb5..0b785df91d967 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -951,13 +951,20 @@ struct CUDADeviceTy : public GenericDeviceTy {
 
     Info.add("Vendor Name", "NVIDIA", "", DeviceInfo::VENDOR);
 
+    Info.add("Vendor ID", uint64_t{4318}, "", DeviceInfo::VENDOR_ID);
+
+    Info.add("Memory Address Size", std::numeric_limits<CUdeviceptr>::digits,
+             "bits", DeviceInfo::ADDRESS_BITS);
+
     Res = cuDeviceTotalMem(&TmpSt, Device);
     if (Res == CUDA_SUCCESS)
-      Info.add("Global Memory Size", TmpSt, "bytes");
+      Info.add("Global Memory Size", TmpSt, "bytes",
+               DeviceInfo::GLOBAL_MEM_SIZE);
 
     Res = getDeviceAttrRaw(CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, TmpInt);
     if (Res == CUDA_SUCCESS)
-      Info.add("Number of Multiprocessors", TmpInt);
+      Info.add("Number of Multiprocessors", TmpInt, "",
+               DeviceInfo::NUM_COMPUTE_UNITS);
 
     Res = getDeviceAttrRaw(CU_DEVICE_ATTRIBUTE_GPU_OVERLAP, TmpInt);
     if (Res == CUDA_SUCCESS)
@@ -1018,7 +1025,8 @@ struct CUDADeviceTy : public GenericDeviceTy {
 
     Res = getDeviceAttrRaw(CU_DEVICE_ATTRIBUTE_CLOCK_RATE, TmpInt);
     if (Res == CUDA_SUCCESS)
-      Info.add("Clock Rate", TmpInt, "kHz");
+      Info.add("Clock Rate", TmpInt / 1000, "MHz",
+               DeviceInfo::MAX_CLOCK_FREQUENCY);
 
     Res = getDeviceAttrRaw(CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, TmpInt);
     if (Res == CUDA_SUCCESS)
@@ -1055,7 +1063,8 @@ struct CUDADeviceTy : public GenericDeviceTy {
 
     Res = getDeviceAttrRaw(CU_DEVICE_ATTRIBUTE_MEMORY_CLOCK_RATE, TmpInt);
     if (Res == CUDA_SUCCESS)
-      Info.add("Memory Clock Rate", TmpInt, "kHz");
+      Info.add("Memory Clock Rate", TmpInt / 1000, "MHz",
+               DeviceInfo::MEMORY_CLOCK_RATE);
 
     Res = getDeviceAttrRaw(CU_DEVICE_ATTRIBUTE_GLOBAL_MEMORY_BUS_WIDTH, TmpInt);
     if (Res == CUDA_SUCCESS)
diff --git a/offload/tools/offload-tblgen/APIGen.cpp b/offload/tools/offload-tblgen/APIGen.cpp
index 8c61d1f12de7a..6f953cc734fc8 100644
--- a/offload/tools/offload-tblgen/APIGen.cpp
+++ b/offload/tools/offload-tblgen/APIGen.cpp
@@ -131,17 +131,28 @@ static void ProcessEnum(const EnumRec &Enum, raw_ostream &OS) {
   OS << formatv("/// @brief {0}\n", Enum.getDesc());
   OS << formatv("typedef enum {0} {{\n", Enum.getName());
 
-  uint32_t EtorVal = 0;
+  uint32_t EtorVal = Enum.isBitField();
   for (const auto &EnumVal : Enum.getValues()) {
-    if (Enum.isTyped()) {
-      OS << MakeComment(
-          formatv("[{0}] {1}", EnumVal.getTaggedType(), EnumVal.getDesc())
-              .str());
-    } else {
-      OS << MakeComment(EnumVal.getDesc());
+    for (size_t TemplateIndex{0};
+         TemplateIndex == 0 ||
+         TemplateIndex < EnumVal.getTemplateValues().size();
+         ++TemplateIndex) {
+      std::string Name{EnumVal.getTemplateName(TemplateIndex)};
+      std::string Desc{EnumVal.getTemplateDesc(TemplateIndex)};
+      if (Enum.isTyped()) {
+        OS << MakeComment(
+            formatv("[{0}] {1}", EnumVal.getTaggedType(), Desc).str());
+      } else {
+        OS << MakeComment(Desc);
+      }
+      OS << formatv(TAB_1 "{0}_{1} = {2},\n", Enum.getEnumValNamePrefix(), Name,
+                    EtorVal);
+      if (Enum.isBitField()) {
+        EtorVal <<= 1u;
+      } else {
+        ++EtorVal;
+      }
     }
-    OS << formatv(TAB_1 "{0}_{1} = {2},\n", Enum.getEnumValNamePrefix(),
-                  EnumVal.getName(), EtorVal++);
   }
 
   // Add last_element/force uint32 val
diff --git a/offload/tools/offload-tblgen/MiscGen.cpp b/offload/tools/offload-tblgen/MiscGen.cpp
index b90e5cfdec8b2..3f01b34d76c74 100644
--- a/offload/tools/offload-tblgen/MiscGen.cpp
+++ b/offload/tools/offload-tblgen/MiscGen.cpp
@@ -107,10 +107,22 @@ void EmitOffloadInfo(const RecordKeeper &Records, raw_ostream &OS) {
 
 )";
 
-  auto ErrorCodeEnum = EnumRec{Records.getDef("DeviceInfo")};
-  uint32_t EtorVal = 0;
-  for (const auto &EnumVal : ErrorCodeEnum.getValues()) {
-    OS << formatv(TAB_1 "OFFLOAD_DEVINFO({0}, \"{1}\", {2})\n",
-                  EnumVal.getName(), EnumVal.getDesc(), EtorVal++);
+  auto Enum = EnumRec{Records.getDef("DeviceInfo")};
+
+  uint32_t EtorVal = Enum.isBitField();
+  for (const auto &EnumVal : Enum.getValues()) {
+    for (size_t TemplateIndex{0};
+         TemplateIndex == 0 ||
+         TemplateIndex < EnumVal.getTemplateValues().size();
+         ++TemplateIndex) {
+      OS << formatv(TAB_1 "OFFLOAD_DEVINFO({0}, \"{1}\", {2})\n",
+                    EnumVal.getTemplateName(TemplateIndex),
+                    EnumVal.getTemplateDesc(TemplateIndex), EtorVal);
+      if (Enum.isBitField()) {
+        EtorVal <<= 1u;
+      } else {
+        ++EtorVal;
+      }
+    }
   }
 }
diff --git a/offload/tools/offload-tblgen/PrintGen.cpp b/offload/tools/offload-tblgen/PrintGen.cpp
index 89d7c820426cf..3389deca34b5e 100644
--- a/offload/tools/offload-tblgen/PrintGen.cpp
+++ b/offload/tools/offload-tblgen/PrintGen.cpp
@@ -40,10 +40,15 @@ static void ProcessEnum(const EnumRec &Enum, raw_ostream &OS) {
                 Enum.getName());
 
   for (const auto &Val : Enum.getValues()) {
-    auto Name = Enum.getEnumValNamePrefix() + "_" + Val.getName();
-    OS << formatv(TAB_1 "case {0}:\n", Name);
-    OS << formatv(TAB_2 "os << \"{0}\";\n", Name);
-    OS << formatv(TAB_2 "break;\n");
+    for (size_t TemplateIndex{0};
+         TemplateIndex == 0 || TemplateIndex < Val.getTemplateValues().size();
+         ++TemplateIndex) {
+      std::string Name{Enum.getEnumValNamePrefix() + "_" +
+                       Val.getTemplateName(TemplateIndex)};
+      OS << formatv(TAB_1 "case {0}:\n", Name);
+      OS << formatv(TAB_2 "os << \"{0}\";\n", Name);
+      OS << formatv(TAB_2 "break;\n");
+    }
   }
 
   OS << TAB_1 "default:\n" TAB_2 "os << \"unknown enumerator\";\n" TAB_2
@@ -67,29 +72,34 @@ inline void printTagged(llvm::raw_ostream &os, const void *ptr, {0} value, size_
                 Enum.getName());
 
   for (const auto &Val : Enum.getValues()) {
-    auto Name = Enum.getEnumValNamePrefix() + "_" + Val.getName();
-    auto Type = Val.getTaggedType();
-    OS << formatv(TAB_1 "case {0}: {{\n", Name);
-    // Special case for strings
-    if (Type == "char[]") {
-      OS << formatv(TAB_2 "printPtr(os, (const char*) ptr);\n");
-    } else {
-      if (Type == "void *")
-        OS << formatv(TAB_2 "void * const * const tptr = (void * "
-                            "const * const)ptr;\n");
-      else
-        OS << formatv(
-            TAB_2 "const {0} * const tptr = (const {0} * const)ptr;\n", Type);
-      // TODO: Handle other cases here
-      OS << TAB_2 "os << (const void *)tptr << \" (\";\n";
-      if (Type.ends_with("*")) {
-        OS << TAB_2 "os << printPtr(os, tptr);\n";
+    for (size_t TemplateIndex{0};
+         TemplateIndex == 0 || TemplateIndex < Val.getTemplateValues().size();
+         ++TemplateIndex) {
+      std::string Name{Enum.getEnumValNamePrefix() + "_" +
+                       Val.getTemplateName(TemplateIndex)};
+      auto Type = Val.getTaggedType();
+      OS << formatv(TAB_1 "case {0}: {{\n", Name);
+      // Special case for strings
+      if (Type == "char[]") {
+        OS << formatv(TAB_2 "printPtr(os, (const char*) ptr);\n");
       } else {
-        OS << TAB_2 "os << *tptr;\n";
+        if (Type == "void *")
+          OS << formatv(TAB_2 "void * const * const tptr = (void * "
+                              "const * const)ptr;\n");
+        else
+          OS << formatv(
+              TAB_2 "const {0} * const tptr = (const {0} * const)ptr;\n", Type);
+        // TODO: Handle other cases here
+        OS << TAB_2 "os << (const void *)tptr << \" (\";\n";
+        if (Type.ends_with("*")) {
+          OS << TAB_2 "os << printPtr(os, tptr);\n";
+        } else {
+          OS << TAB_2 "os << *tptr;\n";
+        }
+        OS << TAB_2 "os << \")\";\n";
       }
-      OS << TAB_2 "os << \")\";\n";
+      OS << formatv(TAB_2 "break;\n" TAB_1 "}\n");
     }
-    OS << formatv(TAB_2 "break;\n" TAB_1 "}\n");
   }
 
   OS << TAB_1 "default:\n" TAB_2 "os << \"unknown enumerator\";\n" TAB_2
diff --git a/offload/tools/offload-tblgen/RecordTypes.hpp b/offload/tools/offload-tblgen/RecordTypes.hpp
index 65c0a4ce4a2c7..da55f6e88eea5 100644
--- a/offload/tools/offload-tblgen/RecordTypes.hpp
+++ b/offload/tools/offload-tblgen/RecordTypes.hpp
@@ -63,15 +63,48 @@ class TypedefRec {
 
 class EnumValueRec {
 public:
-  explicit EnumValueRec(const Record *rec) : rec(rec) {}
+  explicit EnumValueRec(const Record *rec) : rec(rec) {
+    if (rec->getValue("template_values") == nullptr) {
+      TemplateValues = {};
+    } else {
+      TemplateValues = rec->getValueAsListOfStrings("template_values");
+    }
+  }
   std::string getName() const { return rec->getValueAsString("name").upper(); }
   StringRef getDesc() const { return rec->getValueAsString("desc"); }
   StringRef getTaggedType() const {
     return rec->getValueAsString("tagged_type");
   }
+  const std::vector<StringRef> &getTemplateValues() const {
+    return TemplateValues;
+  }
+  std::string getTemplateName(size_t index) const {
+    if (TemplateValues.empty())
+      return getName();
+
+    return replaceTemplate(getName(), "%TEMPLATE%",
+                           TemplateValues.at(index).upper());
+  }
+  std::string getTemplateDesc(size_t index) const {
+    if (TemplateValues.empty())
+      return getDesc().str();
+
+    return replaceTemplate(getDesc().str(), "%TEMPLATE%",
+                           TemplateValues.at(index));
+  }
 
 private:
   const Record *rec;
+  std::vector<StringRef> TemplateValues;
+  static std::string replaceTemplate(std::string s, StringRef old_token,
+                                     StringRef new_token) {
+    auto pos = s.find(old_token);
+    while (pos != std::string::npos) {
+      s.replace(pos, old_token.size(), new_token);
+      pos = s.find(old_token, pos + new_token.size());
+    }
+    return s;
+  }
 };
 
 class EnumRec {
@@ -92,6 +125,8 @@ class EnumRec {
 
   bool isTyped() const { return rec->getValueAsBit("is_typed"); }
 
+  bool isBitField() const { return rec->getValueAsBit("is_bit_field"); }
+
 private:
   const Record *rec;
   std::vector<EnumValueRec> vals;
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
index 5657320a33a29..7ab2286cbc9c3 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
@@ -13,6 +13,38 @@
 using olGetDeviceInfoTest = OffloadDeviceTest;
 OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetDeviceInfoTest);
 
+#define OL_DEVICE_INFO_TEST_SUCCESS_CHECK(TestName, PropType, PropName, Dev,   \
+                                          Expr)                                \
+  TEST_P(olGetDeviceInfoTest, Test##Dev##TestName) {                           \
+    PropType Value;                                                            \
+    ASSERT_SUCCESS(olGetDeviceInfo(Dev, PropName, sizeof(Value), &Value));     \
+    Expr;                                                                      \
+  }
+
+#define OL_DEVICE_INFO_TEST_DEVICE_SUCCESS(TestName, PropType, PropName)       \
+  OL_DEVICE_INFO_TEST_SUCCESS_CHECK(TestName, PropType, PropName, Device, {})
+
+#define OL_DEVICE_INFO_TEST_HOST_SUCCESS(TestName, PropType, PropName)         \
+  OL_DEVICE_INFO_TEST_SUCCESS_CHECK(TestName, PropType, PropName, Host, {})
+
+#define OL_DEVICE_INFO_TEST_SUCCESS(TestName, PropType, PropName)              \
+  OL_DEVICE_INFO_TEST_DEVICE_SUCCESS(TestName, PropType, PropName)             \
+  OL_DEVICE_INFO_TEST_HOST_SUCCESS(TestName, PropType, PropName)
+
+#define OL_DEVICE_INFO_TEST_DEVICE_VALUE_GT(TestName, PropType, PropName,      \
+                                            LowBound)                          \
+  OL_DEVICE_INFO_TEST_SUCCESS_CHECK(TestName, PropType, PropName, Device,      \
+                                    ASSERT_GT(Value, LowBound))
+
+#define OL_DEVICE_INFO_TEST_HOST_VALUE_GT(TestName, PropType, PropName,        \
+                                          LowBound)                            \
+  OL_DEVICE_INFO_TEST_SUCCESS_CHECK(TestName, PropType, PropName, Host,        \
+                                    ASSERT_GT(Value, LowBound))
+
+#define OL_DEVICE_INFO_TEST_VALUE_GT(TestName, PropType, PropName, LowBound)   \
+  OL_DEVICE_INFO_TEST_DEVICE_VALUE_GT(TestName, PropType, PropName, LowBound)  \
+  OL_DEVICE_INFO_TEST_HOST_VALUE_GT(TestName, PropType, PropName, LowBound)
+
 TEST_P(olGetDeviceInfoTest, SuccessType) {
   ol_device_type_t DeviceType;
   ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_TYPE,
@@ -77,12 +109,8 @@ TEST_P(olGetDeviceInfoTest, SuccessDriverVersion) {
   ASSERT_EQ(std::strlen(DriverVersion.data()), Size - 1);
 }
 
-TEST_P(olGetDeviceInfoTest, SuccessMaxWorkGroupSize) {
-  uint32_t Value;
-  ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE,
-                                 sizeof(Value), &Value));
-  ASSERT_GT(Value, 0u);
-}
+OL_DEVICE_INFO_TEST_VALUE_GT(MaxWorkGroupSize, uint32_t,
+                             OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE, 0);
 
 TEST_P(olGetDeviceInfoTest, SuccessMaxWorkGroupSizePerDimension) {
   ol_dimensions_t Value{0, 0, 0};
@@ -94,6 +122,60 @@ TEST_P(olGetDeviceInfoTest, SuccessMaxWorkGroupSizePerDimension) {
   ASSERT_GT(Value.z, 0u);
 }
 
+OL_DEVICE_INFO_TEST_DEVICE_VALUE_GT(VendorId, uint32_t,
+                                    OL_DEVICE_INFO_VENDOR_ID, 0);
+OL_DEVICE_INFO_TEST_HOST_SUCCESS(VendorId, uint32_t, OL_DEVICE_INFO_VENDOR_ID);
+OL_DEVICE_INFO_TEST_VALUE_GT(NumComputeUnits, uint32_t,
+                             OL_DEVICE_INFO_NUM_COMPUTE_UNITS, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(SingleFPConfig, ol_device_fp_capability_flags_t,
+                             OL_DEVICE_INFO_SINGLE_FP_CONFIG, 0);
+OL_DEVICE_INFO_TEST_SUCCESS(HalfFPConfig, ol_device_fp_capability_flags_t,
+                            OL_DEVICE_INFO_HALF_FP_CONFIG);
+OL_DEVICE_INFO_TEST_VALUE_GT(DoubleFPConfig, ol_device_fp_capability_flags_t,
+                             OL_DEVICE_INFO_DOUBLE_FP_CONFIG, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(PreferredVectorWidthChar, uint32_t,
+                             OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_CHAR, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(PreferredVectorWidthShort, uint32_t,
+                             OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_SHORT, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(PreferredVectorWidthInt, uint32_t,
+                             OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_INT, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(PreferredVectorWidthLong, uint32_t,
+                             OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_LONG, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(PreferredVectorWidthFloat, uint32_t,
+                             OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_FLOAT, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(PreferredVectorWidthDouble, uint32_t,
+                             OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_DOUBLE, 0);
+OL_DEVICE_INFO_TEST_SUCCESS(PreferredVectorWidthHalf, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_HALF);
+OL_DEVICE_INFO_TEST_VALUE_GT(NativeVectorWidthChar, uint32_t,
+                             OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(NativeVectorWidthShort, uint32_t,
+                             OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(NativeVectorWidthInt, uint32_t,
+                             OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(NativeVectorWidthLong, uint32_t,
+                             OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(NativeVectorWidthFloat, uint32_t,
+                             OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(NativeVectorWidthDouble, uint32_t,
+                             OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE, 0);
+OL_DEVICE_INFO_TEST_SUCCESS(NativeVectorWidthHalf, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF);
+OL_DEVICE_INFO_TEST_VALUE_GT(MaxClockFrequency, uint32_t,
+                             OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(MemoryClockRate, uint32_t,
+                             OL_DEVICE_INFO_MEMORY_CLOCK_RATE, 0);
+OL_DEVICE_INFO_TEST_VALUE_GT(AddressBits, uint32_t, OL_DEVICE_INFO_ADDRESS_BITS,
+                             0);
+OL_DEVICE_INFO_TEST_DEVICE_VALUE_GT(MaxMemAllocSize, uint64_t,
+                                    OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE, 0);
+OL_DEVICE_INFO_TEST_HOST_SUCCESS(MaxMemAllocSize, uint64_t,
+                                 OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE);
+OL_DEVICE_INFO_TEST_DEVICE_VALUE_GT(GlobalMemSize, uint64_t,
+                                    OL_DEVICE_INFO_GLOBAL_MEM_SIZE, 0);
+OL_DEVICE_INFO_TEST_HOST_SUCCESS(GlobalMemSize, uint64_t,
+                                 OL_DEVICE_INFO_GLOBAL_MEM_SIZE);
+
 TEST_P(olGetDeviceInfoTest, InvalidNullHandleDevice) {
   ol_device_type_t DeviceType;
   ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
index 4e29978fc20f0..da9bbcadf3ee4 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
@@ -13,43 +13,74 @@
 using olGetDeviceInfoSizeTest = OffloadDeviceTest;
 OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetDeviceInfoSizeTest);
 
-TEST_P(olGetDeviceInfoSizeTest, SuccessType) {
-  size_t Size = 0;
-  ASSERT_SUCCESS(olGetDeviceInfoSize(Device, OL_DEVICE_INFO_TYPE, &Size));
-  ASSERT_EQ(Size, sizeof(ol_device_type_t));
-}
-
-TEST_P(olGetDeviceInfoSizeTest, SuccessPlatform) {
-  size_t Size = 0;
-  ASSERT_SUCCESS(olGetDeviceInfoSize(Device, OL_DEVICE_INFO_PLATFORM, &Size));
-  ASSERT_EQ(Size, sizeof(ol_platform_handle_t));
-}
-
-TEST_P(olGetDeviceInfoSizeTest, SuccessName) {
-  size_t Size = 0;
-  ASSERT_SUCCESS(olGetDeviceInfoSize(Device, OL_DEVICE_INFO_NAME, &Size));
-  ASSERT_NE(Size, 0ul);
-}
+#define OL_DEVICE_INFO_SIZE_TEST(TestName, PropName, Expr)                     \
+  TEST_P(olGetDeviceInfoSizeTest, Success##TestName) {                         \
+    size_t Size = 0;                                                           \
+    ASSERT_SUCCESS(olGetDeviceInfoSize(Device, PropName, &Size));              \
+    Expr;                                                                      \
+  }
 
-TEST_P(olGetDeviceInfoSizeTest, SuccessVendor) {
-  size_t Size = 0;
-  ASSERT_SUCCESS(olGetDeviceInfoSize(Device, OL_DEVICE_INFO_VENDOR, &Size));
-  ASSERT_NE(Size, 0ul);
-}
+#define OL_DEVICE_INFO_SIZE_TEST_EQ(TestName, PropType, PropName)              \
+  OL_DEVICE_INFO_SIZE_TEST(TestName, PropName,                                 \
+                           ASSERT_EQ(Size, sizeof(PropType)));
 
-TEST_P(olGetDeviceInfoSizeTest, SuccessDriverVersion) {
-  size_t Size = 0;
-  ASSERT_SUCCESS(
-      olGetDeviceInfoSize(Device, OL_DEVICE_INFO_DRIVER_VERSION, &Size));
-  ASSERT_NE(Size, 0ul);
-}
+#define OL_DEVICE_INFO_SIZE_TEST_NONZERO(TestName, PropName)                   \
+  OL_DEVICE_INFO_SIZE_TEST(TestName, PropName, ASSERT_NE(Size, 0ul));
 
-TEST_P(olGetDeviceInfoSizeTest, SuccessMaxWorkGroupSize) {
-  size_t Size = 0;
-  ASSERT_SUCCESS(
-      olGetDeviceInfoSize(Device, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE, &Size));
-  ASSERT_EQ(Size, sizeof(uint32_t));
-}
+OL_DEVICE_INFO_SIZE_TEST_EQ(Type, ol_device_type_t, OL_DEVICE_INFO_TYPE);
+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(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,
+                            OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE);
+OL_DEVICE_INFO_SIZE_TEST_EQ(VendorId, uint32_t, OL_DEVICE_INFO_VENDOR_ID);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NumComputeUnits, uint32_t,
+                            OL_DEVICE_INFO_NUM_COMPUTE_UNITS);
+OL_DEVICE_INFO_SIZE_TEST_EQ(SingleFPConfig, ol_device_fp_capability_flags_t,
+                            OL_DEVICE_INFO_SINGLE_FP_CONFIG);
+OL_DEVICE_INFO_SIZE_TEST_EQ(HalfFPConfig, ol_device_fp_capability_flags_t,
+                            OL_DEVICE_INFO_HALF_FP_CONFIG);
+OL_DEVICE_INFO_SIZE_TEST_EQ(DoubleFPConfig, ol_device_fp_capability_flags_t,
+                            OL_DEVICE_INFO_DOUBLE_FP_CONFIG);
+OL_DEVICE_INFO_SIZE_TEST_EQ(PreferredVectorWidthChar, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_CHAR);
+OL_DEVICE_INFO_SIZE_TEST_EQ(PreferredVectorWidthShort, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_SHORT);
+OL_DEVICE_INFO_SIZE_TEST_EQ(PreferredVectorWidthInt, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_INT);
+OL_DEVICE_INFO_SIZE_TEST_EQ(PreferredVectorWidthLong, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_LONG);
+OL_DEVICE_INFO_SIZE_TEST_EQ(PreferredVectorWidthFloat, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_FLOAT);
+OL_DEVICE_INFO_SIZE_TEST_EQ(PreferredVectorWidthDouble, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_DOUBLE);
+OL_DEVICE_INFO_SIZE_TEST_EQ(PreferredVectorWidthHalf, uint32_t,
+                            OL_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_HALF);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NativeVectorWidthChar, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NativeVectorWidthShort, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NativeVectorWidthInt, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NativeVectorWidthLong, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NativeVectorWidthFloat, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NativeVectorWidthDouble, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE);
+OL_DEVICE_INFO_SIZE_TEST_EQ(NativeVectorWidthHalf, uint32_t,
+                            OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF);
+OL_DEVICE_INFO_SIZE_TEST_EQ(MaxClockFrequency, uint32_t,
+                            OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY);
+OL_DEVICE_INFO_SIZE_TEST_EQ(MemoryClockRate, uint32_t,
+                            OL_DEVICE_INFO_MEMORY_CLOCK_RATE);
+OL_DEVICE_INFO_SIZE_TEST_EQ(AddressBits, uint32_t, OL_DEVICE_INFO_ADDRESS_BITS);
+OL_DEVICE_INFO_SIZE_TEST_EQ(MaxMemAllocSize, uint64_t,
+                            OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE);
+OL_DEVICE_INFO_SIZE_TEST_EQ(GlobalMemSize, uint64_t,
+                            OL_DEVICE_INFO_GLOBAL_MEM_SIZE);
 
 TEST_P(olGetDeviceInfoSizeTest, SuccessMaxWorkGroupSizePerDimension) {
   size_t Size = 0;



More information about the llvm-commits mailing list