[llvm] [offload] Add floating-point support detection queries (PR #193233)
Ćukasz Plewa via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 21 07:40:55 PDT 2026
https://github.com/lplewa updated https://github.com/llvm/llvm-project/pull/193233
>From f5a64d5429e8a1e772a45dcc8ceae7cc795d95f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Plewa?= <lukasz.plewa at intel.com>
Date: Mon, 20 Apr 2026 13:01:56 +0200
Subject: [PATCH] [offload] Add floating-point support detection queries
Add device info queries to detect support for half-, single-, and
double-precision floating-point formats.
For the AMDGPU, CUDA, and Host plugins, add the new queries alongside
the existing capability reporting without changing current behavior.
For the Level Zero plugin, implement floating-point support detection
and capability querying.
---
offload/liboffload/API/Device.td | 7 +-
offload/liboffload/src/OffloadImpl.cpp | 29 ++++----
offload/plugins-nextgen/amdgpu/src/rtl.cpp | 23 ++++++
offload/plugins-nextgen/common/CMakeLists.txt | 1 +
offload/plugins-nextgen/cuda/src/rtl.cpp | 21 ++++++
offload/plugins-nextgen/host/src/rtl.cpp | 22 ++++++
.../level_zero/dynamic_l0/L0DynWrapper.cpp | 1 +
.../level_zero/dynamic_l0/level_zero/ze_api.h | 51 ++++++++++++++
.../level_zero/include/L0Device.h | 23 ++++++
.../level_zero/src/L0Device.cpp | 70 +++++++++++++++++++
.../deviceinfo/llvm-offload-device-info.cpp | 8 +++
.../OffloadAPI/device/olGetDeviceInfo.cpp | 6 ++
12 files changed, 245 insertions(+), 17 deletions(-)
diff --git a/offload/liboffload/API/Device.td b/offload/liboffload/API/Device.td
index 6ada191089674..86ccf446bdec8 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -47,7 +47,12 @@ def ol_device_info_t : Enum {
];
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);
+ list<TaggedEtor> fp_support =
+ !foreach(type, ["Single", "Double", "Half"],
+ TaggedEtor<type#"_FP_SUPPORT", "bool",
+ type#" precision floating point support">);
+ let etors =
+ !listconcat(basic_etors, fp_configs, native_vec_widths, fp_support);
}
def ol_device_fp_capability_flag_t : Enum {
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 314788794842d..71712c2bc6b45 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -429,22 +429,6 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
else
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:
@@ -503,6 +487,9 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
case OL_DEVICE_INFO_NUM_COMPUTE_UNITS:
case OL_DEVICE_INFO_ADDRESS_BITS:
case OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY:
+ case OL_DEVICE_INFO_SINGLE_FP_CONFIG:
+ case OL_DEVICE_INFO_DOUBLE_FP_CONFIG:
+ case OL_DEVICE_INFO_HALF_FP_CONFIG:
case OL_DEVICE_INFO_MEMORY_CLOCK_RATE: {
// Uint32 values
if (!std::holds_alternative<uint64_t>(Entry->Value))
@@ -522,6 +509,16 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
return Info.write(std::get<uint64_t>(Entry->Value));
}
+ case OL_DEVICE_INFO_SINGLE_FP_SUPPORT:
+ case OL_DEVICE_INFO_DOUBLE_FP_SUPPORT:
+ case OL_DEVICE_INFO_HALF_FP_SUPPORT: {
+ // Boolean values
+ if (!std::holds_alternative<bool>(Entry->Value))
+ return makeError(ErrorCode::BACKEND_FAILURE,
+ "plugin returned incorrect type");
+ return Info.write<bool>(std::get<bool>(Entry->Value));
+ }
+
case OL_DEVICE_INFO_MAX_WORK_SIZE_PER_DIMENSION:
case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE_PER_DIMENSION: {
// {x, y, z} triples
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index e608c5d6ce666..6817245572f17 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -31,6 +31,7 @@
#include "Utils/ELF.h"
#include "GlobalHandler.h"
+#include "OffloadAPI.h"
#include "OpenMP/OMPT/Callback.h"
#include "PluginInterface.h"
#include "UtilitiesRTL.h"
@@ -3321,6 +3322,28 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
if (Err)
consumeError(std::move(Err));
+ ol_device_fp_capability_flags_t FPFlags =
+ 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;
+
+ Info.add("Single FP Support", true, "", DeviceInfo::SINGLE_FP_SUPPORT);
+ Info.add("Single FP Capabilities", FPFlags, "",
+ DeviceInfo::SINGLE_FP_CONFIG);
+
+ Info.add("Double FP Support", true, "", DeviceInfo::DOUBLE_FP_SUPPORT);
+ Info.add("Double FP Capabilities", FPFlags, "",
+ DeviceInfo::DOUBLE_FP_CONFIG);
+
+ // TODO: Use HSA_AGENT_INFO_FAST_F16_OPERATION to detect FP16 support.
+ Info.add("Half FP Support", ol_bool_t(false), "",
+ DeviceInfo::HALF_FP_SUPPORT);
+ Info.add("Half FP Capabilities", ol_device_fp_capability_flags_t{0}, "",
+ DeviceInfo::HALF_FP_CONFIG);
+
return Info;
}
diff --git a/offload/plugins-nextgen/common/CMakeLists.txt b/offload/plugins-nextgen/common/CMakeLists.txt
index cd150d1bf9298..e7a9451df4cfc 100644
--- a/offload/plugins-nextgen/common/CMakeLists.txt
+++ b/offload/plugins-nextgen/common/CMakeLists.txt
@@ -53,6 +53,7 @@ target_link_options(PluginCommon PUBLIC ${offload_link_flags})
target_include_directories(PluginCommon PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/include
+ ${CMAKE_CURRENT_BINARY_DIR}/../../liboffload/API
${LIBOMPTARGET_LLVM_INCLUDE_DIRS}
${LIBOMPTARGET_BINARY_INCLUDE_DIR}
${LIBOMPTARGET_INCLUDE_DIR}
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index 8a7c8a4ffd42d..5d93ec589b1f8 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -21,6 +21,7 @@
#include "Shared/Environment.h"
#include "GlobalHandler.h"
+#include "OffloadAPI.h"
#include "OpenMP/OMPT/Callback.h"
#include "PluginInterface.h"
#include "Utils/ELF.h"
@@ -1241,6 +1242,26 @@ struct CUDADeviceTy : public GenericDeviceTy {
Info.add("Compute Capabilities", ComputeCapability.str());
+ ol_device_fp_capability_flags_t FPFlags =
+ 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;
+
+ Info.add("Single FP Support", true, "", DeviceInfo::SINGLE_FP_SUPPORT);
+ Info.add("Single FP Capabilities", FPFlags, "",
+ DeviceInfo::SINGLE_FP_CONFIG);
+
+ Info.add("Double FP Support", true, "", DeviceInfo::DOUBLE_FP_SUPPORT);
+ Info.add("Double FP Capabilities", FPFlags, "",
+ DeviceInfo::DOUBLE_FP_CONFIG);
+
+ Info.add("Half FP Support", false, "", DeviceInfo::HALF_FP_SUPPORT);
+ Info.add("Half FP Capabilities", ol_device_fp_capability_flags_t{0}, "",
+ DeviceInfo::HALF_FP_CONFIG);
+
return Info;
}
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index bef49faf45383..3f2cc612e4df6 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -20,6 +20,7 @@
#include "Utils/ELF.h"
#include "GlobalHandler.h"
+#include "OffloadAPI.h"
#include "OpenMP/OMPT/Callback.h"
#include "PluginInterface.h"
#include "omptarget.h"
@@ -403,6 +404,27 @@ struct GenELF64DeviceTy : public GenericDeviceTy {
MaxSize.add("x", uint32_max);
MaxSize.add("y", uint32_max);
MaxSize.add("z", uint32_max);
+
+ ol_device_fp_capability_flags_t FPFlags =
+ 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;
+
+ Info.add("Single FP Support", true, "", DeviceInfo::SINGLE_FP_SUPPORT);
+ Info.add("Single FP Capabilities", FPFlags, "",
+ DeviceInfo::SINGLE_FP_CONFIG);
+
+ Info.add("Double FP Support", true, "", DeviceInfo::DOUBLE_FP_SUPPORT);
+ Info.add("Double FP Capabilities", FPFlags, "",
+ DeviceInfo::DOUBLE_FP_CONFIG);
+
+ Info.add("Half FP Support", false, "", DeviceInfo::HALF_FP_SUPPORT);
+ Info.add("Half FP Capabilities", ol_device_fp_capability_flags_t{0}, "",
+ DeviceInfo::HALF_FP_CONFIG);
+
return Info;
}
diff --git a/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp b/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp
index e68bddd0047a1..8643897facacd 100644
--- a/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp
+++ b/offload/plugins-nextgen/level_zero/dynamic_l0/L0DynWrapper.cpp
@@ -50,6 +50,7 @@ DLWRAP(zeDeviceCanAccessPeer, 3)
DLWRAP(zeDeviceGetProperties, 2)
DLWRAP(zeDeviceGetCommandQueueGroupProperties, 3)
DLWRAP(zeDeviceGetComputeProperties, 2)
+DLWRAP(zeDeviceGetModuleProperties, 2)
DLWRAP(zeDeviceGetMemoryProperties, 3)
DLWRAP(zeDeviceGetCacheProperties, 3)
DLWRAP(zeDeviceGetGlobalTimestamps, 3)
diff --git a/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h b/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h
index 6049bd2c83ad1..81a4c00269160 100644
--- a/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h
+++ b/offload/plugins-nextgen/level_zero/dynamic_l0/level_zero/ze_api.h
@@ -148,6 +148,7 @@ typedef enum _ze_structure_type_t {
ZE_STRUCTURE_TYPE_DRIVER_PROPERTIES = 0x1,
ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES = 0x3,
ZE_STRUCTURE_TYPE_DEVICE_COMPUTE_PROPERTIES = 0x4,
+ ZE_STRUCTURE_TYPE_DEVICE_MODULE_PROPERTIES = 0x5,
ZE_STRUCTURE_TYPE_COMMAND_QUEUE_GROUP_PROPERTIES = 0x6,
ZE_STRUCTURE_TYPE_DEVICE_MEMORY_PROPERTIES = 0x7,
ZE_STRUCTURE_TYPE_DEVICE_CACHE_PROPERTIES = 0x9,
@@ -399,6 +400,53 @@ typedef struct _ze_device_cache_properties_t {
size_t cacheSize;
} ze_device_cache_properties_t;
+/* Native kernel UUID */
+#ifndef ZE_MAX_NATIVE_KERNEL_UUID_SIZE
+#define ZE_MAX_NATIVE_KERNEL_UUID_SIZE 16
+#endif
+
+typedef struct _ze_native_kernel_uuid_t {
+ uint8_t id[ZE_MAX_NATIVE_KERNEL_UUID_SIZE];
+} ze_native_kernel_uuid_t;
+
+/* Device module flags */
+typedef uint32_t ze_device_module_flags_t;
+typedef enum _ze_device_module_flag_t {
+ ZE_DEVICE_MODULE_FLAG_FP16 = ZE_BIT(0),
+ ZE_DEVICE_MODULE_FLAG_FP64 = ZE_BIT(1),
+ ZE_DEVICE_MODULE_FLAG_INT64_ATOMICS = ZE_BIT(2),
+ ZE_DEVICE_MODULE_FLAG_DP4A = ZE_BIT(3),
+ ZE_DEVICE_MODULE_FLAG_FORCE_UINT32 = 0x7fffffff
+} ze_device_module_flag_t;
+
+/* Floating-point capability flags */
+typedef uint32_t ze_device_fp_flags_t;
+typedef enum _ze_device_fp_flag_t {
+ ZE_DEVICE_FP_FLAG_DENORM = ZE_BIT(0),
+ ZE_DEVICE_FP_FLAG_INF_NAN = ZE_BIT(1),
+ ZE_DEVICE_FP_FLAG_ROUND_TO_NEAREST = ZE_BIT(2),
+ ZE_DEVICE_FP_FLAG_ROUND_TO_ZERO = ZE_BIT(3),
+ ZE_DEVICE_FP_FLAG_ROUND_TO_INF = ZE_BIT(4),
+ ZE_DEVICE_FP_FLAG_FMA = ZE_BIT(5),
+ ZE_DEVICE_FP_FLAG_ROUNDED_DIVIDE_SQRT = ZE_BIT(6),
+ ZE_DEVICE_FP_FLAG_SOFT_FLOAT = ZE_BIT(7),
+ ZE_DEVICE_FP_FLAG_FORCE_UINT32 = 0x7fffffff
+} ze_device_fp_flag_t;
+
+/* Device module properties */
+typedef struct _ze_device_module_properties_t {
+ ze_structure_type_t stype;
+ void *pNext;
+ uint32_t spirvVersionSupported;
+ ze_device_module_flags_t flags;
+ ze_device_fp_flags_t fp16flags;
+ ze_device_fp_flags_t fp32flags;
+ ze_device_fp_flags_t fp64flags;
+ uint32_t maxArgumentsSize;
+ uint32_t printfBufferSize;
+ ze_native_kernel_uuid_t nativeKernelSupported;
+} ze_device_module_properties_t;
+
/* Device IP version (extension) */
typedef struct _ze_device_ip_version_ext_t {
ze_structure_type_t stype;
@@ -612,6 +660,9 @@ ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetComputeProperties(
ze_device_handle_t hDevice,
ze_device_compute_properties_t *pComputeProperties);
ZE_APIEXPORT ze_result_t ZE_APICALL
+zeDeviceGetModuleProperties(ze_device_handle_t hDevice,
+ ze_device_module_properties_t *pModuleProperties);
+ZE_APIEXPORT ze_result_t ZE_APICALL
zeDeviceGetMemoryProperties(ze_device_handle_t hDevice, uint32_t *pCount,
ze_device_memory_properties_t *pMemProperties);
ZE_APIEXPORT ze_result_t ZE_APICALL
diff --git a/offload/plugins-nextgen/level_zero/include/L0Device.h b/offload/plugins-nextgen/level_zero/include/L0Device.h
index 8c83d14f8d1b0..1ca62145f536e 100644
--- a/offload/plugins-nextgen/level_zero/include/L0Device.h
+++ b/offload/plugins-nextgen/level_zero/include/L0Device.h
@@ -188,6 +188,7 @@ class L0DeviceTy final : public GenericDeviceTy {
ze_device_compute_properties_t ComputeProperties{};
ze_device_memory_properties_t MemoryProperties{};
ze_device_cache_properties_t CacheProperties{};
+ ze_device_module_properties_t ModuleProperties{};
/// Devices' default target allocation kind for internal allocation.
int32_t AllocKind = TARGET_ALLOC_DEVICE;
@@ -257,6 +258,8 @@ class L0DeviceTy final : public GenericDeviceTy {
MemoryProperties.pNext = nullptr;
CacheProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_CACHE_PROPERTIES;
CacheProperties.pNext = nullptr;
+ ModuleProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_MODULE_PROPERTIES;
+ ModuleProperties.pNext = nullptr;
}
static L0DeviceTy &makeL0Device(GenericDeviceTy &Device) {
@@ -385,6 +388,26 @@ class L0DeviceTy final : public GenericDeviceTy {
return DeviceProperties.maxMemAllocSize;
}
+ bool supportsFP64() const {
+ return ModuleProperties.flags & ZE_DEVICE_MODULE_FLAG_FP64;
+ }
+
+ bool supportsFP16() const {
+ return ModuleProperties.flags & ZE_DEVICE_MODULE_FLAG_FP16;
+ }
+
+ ze_device_fp_flags_t getFP64Flags() const {
+ return ModuleProperties.fp64flags;
+ }
+
+ ze_device_fp_flags_t getFP16Flags() const {
+ return ModuleProperties.fp16flags;
+ }
+
+ ze_device_fp_flags_t getFP32Flags() const {
+ return ModuleProperties.fp32flags;
+ }
+
int32_t getAllocKind() const { return AllocKind; }
DeviceArchTy getDeviceArch() const { return DeviceArch; }
bool isDeviceArch(DeviceArchTy Arch) const { return DeviceArch == Arch; }
diff --git a/offload/plugins-nextgen/level_zero/src/L0Device.cpp b/offload/plugins-nextgen/level_zero/src/L0Device.cpp
index 461f12407680f..3a7334ec45066 100644
--- a/offload/plugins-nextgen/level_zero/src/L0Device.cpp
+++ b/offload/plugins-nextgen/level_zero/src/L0Device.cpp
@@ -18,6 +18,7 @@
#include "L0Trace.h"
#include "GlobalHandler.h"
+#include "OffloadAPI.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Object/ELF.h"
@@ -195,6 +196,7 @@ Error L0DeviceTy::initImpl(GenericPluginTy &Plugin) {
&MemoryProperties);
CALL_ZE_RET_ERROR(zeDeviceGetCacheProperties, zeDevice, &Count,
&CacheProperties);
+ CALL_ZE_RET_ERROR(zeDeviceGetModuleProperties, zeDevice, &ModuleProperties);
DeviceName = std::string(DeviceProperties.name);
@@ -639,6 +641,74 @@ Expected<InfoTreeNode> L0DeviceTy::obtainInfoImpl() {
DeviceInfo::MEMORY_CLOCK_RATE);
Info.add("Memory Address Size", uint64_t{64u}, "bits",
DeviceInfo::ADDRESS_BITS);
+
+ // FP64 (Double precision).
+ Info.add("Double FP Support", supportsFP64(), "",
+ DeviceInfo::DOUBLE_FP_SUPPORT);
+ ol_device_fp_capability_flags_t DoubleFPCapabilities = 0;
+ ze_device_fp_flags_t ZeDoubleFPFlags = getFP64Flags();
+ if (ZeDoubleFPFlags & ZE_DEVICE_FP_FLAG_DENORM)
+ DoubleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_DENORM;
+ if (ZeDoubleFPFlags & ZE_DEVICE_FP_FLAG_INF_NAN)
+ DoubleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN;
+ if (ZeDoubleFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_NEAREST)
+ DoubleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST;
+ if (ZeDoubleFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_ZERO)
+ DoubleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO;
+ if (ZeDoubleFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_INF)
+ DoubleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF;
+ if (ZeDoubleFPFlags & ZE_DEVICE_FP_FLAG_FMA)
+ DoubleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_FMA;
+ if (ZeDoubleFPFlags & ZE_DEVICE_FP_FLAG_ROUNDED_DIVIDE_SQRT)
+ DoubleFPCapabilities |=
+ OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT;
+ Info.add("Double FP Capabilities", DoubleFPCapabilities, "",
+ DeviceInfo::DOUBLE_FP_CONFIG);
+
+ // FP16 (Half precision).
+ Info.add("Half FP Support", supportsFP16(), "", DeviceInfo::HALF_FP_SUPPORT);
+ ol_device_fp_capability_flags_t HalfFPCapabilities = 0;
+ ze_device_fp_flags_t ZeHalfFPFlags = getFP16Flags();
+ if (ZeHalfFPFlags & ZE_DEVICE_FP_FLAG_DENORM)
+ HalfFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_DENORM;
+ if (ZeHalfFPFlags & ZE_DEVICE_FP_FLAG_INF_NAN)
+ HalfFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN;
+ if (ZeHalfFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_NEAREST)
+ HalfFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST;
+ if (ZeHalfFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_ZERO)
+ HalfFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO;
+ if (ZeHalfFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_INF)
+ HalfFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF;
+ if (ZeHalfFPFlags & ZE_DEVICE_FP_FLAG_FMA)
+ HalfFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_FMA;
+ if (ZeHalfFPFlags & ZE_DEVICE_FP_FLAG_ROUNDED_DIVIDE_SQRT)
+ HalfFPCapabilities |=
+ OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT;
+ Info.add("Half FP Capabilities", HalfFPCapabilities, "",
+ DeviceInfo::HALF_FP_CONFIG);
+
+ // FP32 (Single FP).
+ Info.add("Single FP Support", true, "", DeviceInfo::SINGLE_FP_SUPPORT);
+ ol_device_fp_capability_flags_t SingleFPCapabilities = 0;
+ ze_device_fp_flags_t ZeSingleFPFlags = getFP32Flags();
+ if (ZeSingleFPFlags & ZE_DEVICE_FP_FLAG_DENORM)
+ SingleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_DENORM;
+ if (ZeSingleFPFlags & ZE_DEVICE_FP_FLAG_INF_NAN)
+ SingleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN;
+ if (ZeSingleFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_NEAREST)
+ SingleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST;
+ if (ZeSingleFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_ZERO)
+ SingleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO;
+ if (ZeSingleFPFlags & ZE_DEVICE_FP_FLAG_ROUND_TO_INF)
+ SingleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF;
+ if (ZeSingleFPFlags & ZE_DEVICE_FP_FLAG_FMA)
+ SingleFPCapabilities |= OL_DEVICE_FP_CAPABILITY_FLAG_FMA;
+ if (ZeSingleFPFlags & ZE_DEVICE_FP_FLAG_ROUNDED_DIVIDE_SQRT)
+ SingleFPCapabilities |=
+ OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT;
+ Info.add("Single FP Capabilities", SingleFPCapabilities, "",
+ DeviceInfo::SINGLE_FP_CONFIG);
+
return Info;
}
diff --git a/offload/tools/deviceinfo/llvm-offload-device-info.cpp b/offload/tools/deviceinfo/llvm-offload-device-info.cpp
index 936d082695b47..ab2b3c5706f4b 100644
--- a/offload/tools/deviceinfo/llvm-offload-device-info.cpp
+++ b/offload/tools/deviceinfo/llvm-offload-device-info.cpp
@@ -211,14 +211,22 @@ ol_result_t printDevice(std::ostream &S, ol_device_handle_t D) {
OFFLOAD_ERR(
printDeviceValue<uint64_t>(S, D, OL_DEVICE_INFO_WORK_GROUP_LOCAL_MEM_SIZE,
"Work Group Shared Mem Size", "B"));
+ OFFLOAD_ERR(
+ printDeviceValue<bool>(S, D, OL_DEVICE_INFO_SINGLE_FP_SUPPORT,
+ "Single Precision Floating Point Support"));
OFFLOAD_ERR(
(printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
S, D, OL_DEVICE_INFO_SINGLE_FP_CONFIG,
"Single Precision Floating Point Capability")));
+ OFFLOAD_ERR(
+ printDeviceValue<bool>(S, D, OL_DEVICE_INFO_DOUBLE_FP_SUPPORT,
+ "Double Precision Floating Point Support"));
OFFLOAD_ERR(
(printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
S, D, OL_DEVICE_INFO_DOUBLE_FP_CONFIG,
"Double Precision Floating Point Capability")));
+ OFFLOAD_ERR(printDeviceValue<bool>(S, D, OL_DEVICE_INFO_HALF_FP_SUPPORT,
+ "Half Precision Floating Point Support"));
OFFLOAD_ERR(
(printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
S, D, OL_DEVICE_INFO_HALF_FP_CONFIG,
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
index ba29fb153682d..f2ea60cffdf12 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
@@ -201,6 +201,12 @@ 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(SingleFPSupport, bool,
+ OL_DEVICE_INFO_SINGLE_FP_SUPPORT);
+OL_DEVICE_INFO_TEST_SUCCESS(DoubleFPSupport, bool,
+ OL_DEVICE_INFO_DOUBLE_FP_SUPPORT);
+OL_DEVICE_INFO_TEST_SUCCESS(HalfFPSupport, bool,
+ OL_DEVICE_INFO_HALF_FP_SUPPORT);
OL_DEVICE_INFO_TEST_SUCCESS(NativeVectorWidthHalf, uint32_t,
OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF);
OL_DEVICE_INFO_TEST_VALUE_GT(MaxClockFrequency, uint32_t,
More information about the llvm-commits
mailing list