Skip to content

Commit e47c8ed

Browse files
committed
[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.
1 parent 4f60321 commit e47c8ed

File tree

5 files changed

+81
-13
lines changed

5 files changed

+81
-13
lines changed

offload/liboffload/API/Device.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def : Enum {
3131
TaggedEtor<"PLATFORM", "ol_platform_handle_t", "the platform associated with the device">,
3232
TaggedEtor<"NAME", "char[]", "Device name">,
3333
TaggedEtor<"VENDOR", "char[]", "Device vendor">,
34-
TaggedEtor<"DRIVER_VERSION", "char[]", "Driver version">
34+
TaggedEtor<"DRIVER_VERSION", "char[]", "Driver version">,
35+
TaggedEtor<"MAX_WORK_GROUP_SIZE", "ol_dimensions_t", "Maximum work group size in each dimension">,
3536
];
3637
}
3738

offload/liboffload/src/OffloadImpl.cpp

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,13 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
228228
ReturnHelper ReturnValue(PropSize, PropValue, PropSizeRet);
229229

230230
// Find the info if it exists under any of the given names
231-
auto GetInfo = [&](std::vector<std::string> Names) {
232-
InfoQueueTy DevInfo;
233-
if (Device == HostDevice())
234-
return std::string("Host");
235-
231+
auto FindInfo = [&](InfoQueueTy &DevInfo, std::vector<std::string> &Names)
232+
-> std::optional<decltype(DevInfo.getQueue().begin())> {
236233
if (!Device->Device)
237-
return std::string("");
234+
return std::nullopt;
238235

239236
if (auto Err = Device->Device->obtainInfoImpl(DevInfo))
240-
return std::string("");
237+
return std::nullopt;
241238

242239
for (auto Name : Names) {
243240
auto InfoKeyMatches = [&](const InfoQueueTy::InfoQueueEntryTy &Info) {
@@ -247,11 +244,50 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
247244
DevInfo.getQueue().end(), InfoKeyMatches);
248245

249246
if (Item != std::end(DevInfo.getQueue())) {
250-
return Item->Value;
247+
return Item;
251248
}
252249
}
253250

254-
return std::string("");
251+
return std::nullopt;
252+
};
253+
auto GetInfoString = [&](std::vector<std::string> Names) {
254+
InfoQueueTy DevInfo;
255+
256+
if (auto Item = FindInfo(DevInfo, Names)) {
257+
return (*Item)->Value.c_str();
258+
} else {
259+
return "";
260+
}
261+
};
262+
auto GetInfoXyz = [&](std::vector<std::string> Names) {
263+
InfoQueueTy DevInfo;
264+
265+
if (auto Item = FindInfo(DevInfo, Names)) {
266+
auto Iter = *Item;
267+
ol_dimensions_t Out{0, 0, 0};
268+
auto Level = Iter->Level + 1;
269+
270+
while ((++Iter)->Level == Level) {
271+
switch (Iter->Key[0]) {
272+
case 'x':
273+
Out.x = std::stoi(Iter->Value);
274+
break;
275+
case 'y':
276+
Out.y = std::stoi(Iter->Value);
277+
break;
278+
case 'z':
279+
Out.z = std::stoi(Iter->Value);
280+
break;
281+
default:
282+
// Ignore any extra values
283+
(void)0;
284+
}
285+
}
286+
287+
return Out;
288+
} else {
289+
return ol_dimensions_t{0, 0, 0};
290+
}
255291
};
256292

257293
switch (PropName) {
@@ -261,12 +297,21 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
261297
return Device == HostDevice() ? ReturnValue(OL_DEVICE_TYPE_HOST)
262298
: ReturnValue(OL_DEVICE_TYPE_GPU);
263299
case OL_DEVICE_INFO_NAME:
264-
return ReturnValue(GetInfo({"Device Name"}).c_str());
300+
if (Device == HostDevice())
301+
return ReturnValue("Host");
302+
return ReturnValue(GetInfoString({"Device Name"}));
265303
case OL_DEVICE_INFO_VENDOR:
266-
return ReturnValue(GetInfo({"Vendor Name"}).c_str());
304+
if (Device == HostDevice())
305+
return ReturnValue("Host");
306+
return ReturnValue(GetInfoString({"Vendor Name"}));
267307
case OL_DEVICE_INFO_DRIVER_VERSION:
308+
if (Device == HostDevice())
309+
return ReturnValue("Host");
268310
return ReturnValue(
269-
GetInfo({"CUDA Driver Version", "HSA Runtime Version"}).c_str());
311+
GetInfoString({"CUDA Driver Version", "HSA Runtime Version"}));
312+
case OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE:
313+
return ReturnValue(GetInfoXyz({"Workgroup Max Size per Dimension" /*AMD*/,
314+
"Maximum Block Dimensions" /*CUDA*/}));
270315
default:
271316
return createOffloadError(ErrorCode::INVALID_ENUMERATION,
272317
"getDeviceInfo enum '%i' is invalid", PropName);

offload/tools/offload-tblgen/PrintGen.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ template <typename T> inline void printTagged(llvm::raw_ostream &os, const void
213213
"enum {0} value);\n",
214214
EnumRec{R}.getName());
215215
}
216+
for (auto *R : Records.getAllDerivedDefinitions("Struct")) {
217+
OS << formatv("inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os, "
218+
"const struct {0} param);\n",
219+
StructRec{R}.getName());
220+
}
216221
OS << "\n";
217222

218223
// Create definitions

offload/unittests/OffloadAPI/device/olGetDeviceInfo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ TEST_P(olGetDeviceInfoTest, SuccessDriverVersion) {
7777
ASSERT_EQ(std::strlen(DriverVersion.data()), Size - 1);
7878
}
7979

80+
TEST_P(olGetDeviceInfoTest, SuccessMaxWorkGroupSize) {
81+
ol_dimensions_t Value{0, 0, 0};
82+
ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE,
83+
sizeof(Value), &Value));
84+
ASSERT_GT(Value.x, 0);
85+
ASSERT_GT(Value.y, 0);
86+
ASSERT_GT(Value.z, 0);
87+
}
88+
8089
TEST_P(olGetDeviceInfoTest, InvalidNullHandleDevice) {
8190
ol_device_type_t DeviceType;
8291
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,

offload/unittests/OffloadAPI/device/olGetDeviceInfoSize.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ TEST_P(olGetDeviceInfoSizeTest, SuccessDriverVersion) {
4444
ASSERT_NE(Size, 0ul);
4545
}
4646

47+
TEST_P(olGetDeviceInfoSizeTest, SuccessMaxWorkGroupSize) {
48+
size_t Size = 0;
49+
ASSERT_SUCCESS(
50+
olGetDeviceInfoSize(Device, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE, &Size));
51+
ASSERT_EQ(Size, sizeof(ol_dimensions_t));
52+
ASSERT_EQ(Size, sizeof(uint32_t) * 3);
53+
}
54+
4755
TEST_P(olGetDeviceInfoSizeTest, InvalidNullHandle) {
4856
size_t Size = 0;
4957
ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,

0 commit comments

Comments
 (0)