[llvm] [Offload] Add `MAX_WORK_GROUP_SIZE` device info query (PR #143718)
Ross Brunton via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 25 05:56:18 PDT 2025
https://github.com/RossBrunton updated https://github.com/llvm/llvm-project/pull/143718
>From 91bfce23596991746e08d42c5c26807e6e97fd20 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Wed, 11 Jun 2025 15:55:09 +0100
Subject: [PATCH 1/4] [Offload] Add `MAX_WORK_GROUP_SIZE` device info query
This adds a new device info query for the maximum workgroup/block size
for each dimension. Since this returns three values, a new `ol_range_t`
type was added as an `{x, y, z}` triplet. Device info handling and
struct printing was also updated to handle it.
---
offload/liboffload/API/Device.td | 3 +-
offload/liboffload/src/OffloadImpl.cpp | 28 +++++++++++++++++++
offload/tools/offload-tblgen/PrintGen.cpp | 5 ++++
.../OffloadAPI/device/olGetDeviceInfo.cpp | 9 ++++++
.../OffloadAPI/device/olGetDeviceInfoSize.cpp | 8 ++++++
5 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/offload/liboffload/API/Device.td b/offload/liboffload/API/Device.td
index 4abc24f3ba27f..94bd6cbf0e5be 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -31,7 +31,8 @@ def : Enum {
TaggedEtor<"PLATFORM", "ol_platform_handle_t", "the platform associated with the device">,
TaggedEtor<"NAME", "char[]", "Device name">,
TaggedEtor<"VENDOR", "char[]", "Device vendor">,
- TaggedEtor<"DRIVER_VERSION", "char[]", "Driver version">
+ TaggedEtor<"DRIVER_VERSION", "char[]", "Driver version">,
+ TaggedEtor<"MAX_WORK_GROUP_SIZE", "ol_dimensions_t", "Maximum work group size in each dimension">,
];
}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index da2101529ffec..139af2f9a9616 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -264,6 +264,31 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
return "";
};
+ auto GetInfoXyz = [&](std::vector<std::string> Names) {
+ if (!Device->Device)
+ return ol_dimensions_t{0, 0, 0};
+
+ auto Info = Device->Device->obtainInfoImpl();
+ if (auto Err = Info.takeError())
+ return ol_dimensions_t{0, 0, 0};
+
+ for (auto Name : Names) {
+ if (auto Entry = Info->get(Name)) {
+ auto Node = *Entry;
+ ol_dimensions_t Out{0, 0, 0};
+
+ if (auto X = Node->get("x"))
+ Out.x = std::get<size_t>((*X)->Value);
+ if (auto Y = Node->get("y"))
+ Out.y = std::get<size_t>((*Y)->Value);
+ if (auto Z = Node->get("z"))
+ Out.z = std::get<size_t>((*Z)->Value);
+ return Out;
+ }
+ }
+
+ return ol_dimensions_t{0, 0, 0};
+ };
switch (PropName) {
case OL_DEVICE_INFO_PLATFORM:
@@ -279,6 +304,9 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
case OL_DEVICE_INFO_DRIVER_VERSION:
return ReturnValue(
GetInfoString({"CUDA Driver Version", "HSA Runtime Version"}));
+ case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE:
+ return ReturnValue(GetInfoXyz({"Workgroup Max Size per Dimension" /*AMD*/,
+ "Maximum Block Dimensions" /*CUDA*/}));
default:
return createOffloadError(ErrorCode::INVALID_ENUMERATION,
"getDeviceInfo enum '%i' is invalid", PropName);
diff --git a/offload/tools/offload-tblgen/PrintGen.cpp b/offload/tools/offload-tblgen/PrintGen.cpp
index a964ff09d0f6e..d1189688a90a3 100644
--- a/offload/tools/offload-tblgen/PrintGen.cpp
+++ b/offload/tools/offload-tblgen/PrintGen.cpp
@@ -213,6 +213,11 @@ template <typename T> inline void printTagged(llvm::raw_ostream &os, const void
"enum {0} value);\n",
EnumRec{R}.getName());
}
+ for (auto *R : Records.getAllDerivedDefinitions("Struct")) {
+ OS << formatv("inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os, "
+ "const struct {0} param);\n",
+ StructRec{R}.getName());
+ }
OS << "\n";
// Create definitions
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
index 0247744911eaa..a6f0145ab39b4 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
@@ -77,6 +77,15 @@ TEST_P(olGetDeviceInfoTest, SuccessDriverVersion) {
ASSERT_EQ(std::strlen(DriverVersion.data()), Size - 1);
}
+TEST_P(olGetDeviceInfoTest, SuccessMaxWorkGroupSize) {
+ ol_dimensions_t Value{0, 0, 0};
+ ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE,
+ sizeof(Value), &Value));
+ ASSERT_GT(Value.x, 0);
+ ASSERT_GT(Value.y, 0);
+ ASSERT_GT(Value.z, 0);
+}
+
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 edd2704a722dd..a908078a25211 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp
@@ -44,6 +44,14 @@ TEST_P(olGetDeviceInfoSizeTest, SuccessDriverVersion) {
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(ol_dimensions_t));
+ ASSERT_EQ(Size, sizeof(uint32_t) * 3);
+}
+
TEST_P(olGetDeviceInfoSizeTest, InvalidNullHandle) {
size_t Size = 0;
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
>From 95a5f197469fc5b151629980c3f2bca4de5ebcf3 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Wed, 11 Jun 2025 16:43:12 +0100
Subject: [PATCH 2/4] Small fixes
---
offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
index a6f0145ab39b4..c534c45205993 100644
--- a/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
+++ b/offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp
@@ -81,9 +81,9 @@ TEST_P(olGetDeviceInfoTest, SuccessMaxWorkGroupSize) {
ol_dimensions_t Value{0, 0, 0};
ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE,
sizeof(Value), &Value));
- ASSERT_GT(Value.x, 0);
- ASSERT_GT(Value.y, 0);
- ASSERT_GT(Value.z, 0);
+ ASSERT_GT(Value.x, 0u);
+ ASSERT_GT(Value.y, 0u);
+ ASSERT_GT(Value.z, 0u);
}
TEST_P(olGetDeviceInfoTest, InvalidNullHandleDevice) {
>From 872264af641a4cc5f822c3598c3a2d2fd9586102 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Wed, 25 Jun 2025 13:40:39 +0100
Subject: [PATCH 3/4] Return Error from GetInfoXYZ
---
offload/liboffload/src/OffloadImpl.cpp | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 139af2f9a9616..5d83017ffc258 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -13,6 +13,8 @@
#include "OffloadImpl.hpp"
#include "Helpers.hpp"
+// Required for operator<< implementation of ol_device_info_t
+#include "OffloadPrint.hpp"
#include "PluginManager.h"
#include "llvm/Support/FormatVariadic.h"
#include <OffloadAPI.h>
@@ -264,13 +266,16 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
return "";
};
- auto GetInfoXyz = [&](std::vector<std::string> Names) {
- if (!Device->Device)
- return ol_dimensions_t{0, 0, 0};
+ auto GetInfoXyz = [&](std::vector<std::string> Names) -> Error {
+ if (Device == OffloadContext::get().HostDevice())
+ return ReturnValue(ol_dimensions_t{0u, 0u, 0u});
+
+ assert(Device->Device &&
+ "liboffload device handle contains a null plugin device");
auto Info = Device->Device->obtainInfoImpl();
if (auto Err = Info.takeError())
- return ol_dimensions_t{0, 0, 0};
+ return Err;
for (auto Name : Names) {
if (auto Entry = Info->get(Name)) {
@@ -283,11 +288,14 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
Out.y = std::get<size_t>((*Y)->Value);
if (auto Z = Node->get("z"))
Out.z = std::get<size_t>((*Z)->Value);
- return Out;
+ return ReturnValue(Out);
}
}
- return ol_dimensions_t{0, 0, 0};
+ std::string ErrBuffer;
+ llvm::raw_string_ostream(ErrBuffer)
+ << "plugin did not provide information for " << PropName;
+ return Plugin::error(ErrorCode::UNIMPLEMENTED, ErrBuffer.c_str());
};
switch (PropName) {
@@ -305,8 +313,8 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
return ReturnValue(
GetInfoString({"CUDA Driver Version", "HSA Runtime Version"}));
case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE:
- return ReturnValue(GetInfoXyz({"Workgroup Max Size per Dimension" /*AMD*/,
- "Maximum Block Dimensions" /*CUDA*/}));
+ return GetInfoXyz({"Workgroup Max Size per Dimension" /*AMD*/,
+ "Maximum Block Dimensions" /*CUDA*/});
default:
return createOffloadError(ErrorCode::INVALID_ENUMERATION,
"getDeviceInfo enum '%i' is invalid", PropName);
>From 1efb1746db9aa2ff93710bfe161c2f523c62d4b5 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Wed, 25 Jun 2025 13:56:04 +0100
Subject: [PATCH 4/4] Put on same line
---
offload/liboffload/src/OffloadImpl.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 5d83017ffc258..84f8c82a909a0 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -13,8 +13,7 @@
#include "OffloadImpl.hpp"
#include "Helpers.hpp"
-// Required for operator<< implementation of ol_device_info_t
-#include "OffloadPrint.hpp"
+#include "OffloadPrint.hpp" // Required for operator<< implementation of ol_device_info_t
#include "PluginManager.h"
#include "llvm/Support/FormatVariadic.h"
#include <OffloadAPI.h>
More information about the llvm-commits
mailing list