[llvm] [Offload] Enable querying a kernel's program (PR #142632)
Ross Brunton via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 4 03:28:10 PDT 2025
https://github.com/RossBrunton updated https://github.com/llvm/llvm-project/pull/142632
>From b0fabb337faf5ab9c3a33bb662e092d95ebce487 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Tue, 3 Jun 2025 16:12:39 +0100
Subject: [PATCH 1/3] [Offload] Enable querying a kernel's program
Added new entrypoints GetKernelInfo and GetKernelInfoSize for querying
info about a kernel. Currently, the only supported info is the program
handle which was used to create the program.
As part of implementing this, `ol_kernel_handle_t` has been "promoted"
to a real handle type rather than a bitcast.
---
offload/liboffload/API/Common.td | 3 +-
offload/liboffload/API/Kernel.td | 50 +++++++++++++++++
offload/liboffload/src/OffloadImpl.cpp | 39 ++++++++++++-
offload/unittests/OffloadAPI/CMakeLists.txt | 4 +-
.../OffloadAPI/kernel/olGetKernelInfo.cpp | 55 +++++++++++++++++++
.../OffloadAPI/kernel/olGetKernelInfoSize.cpp | 20 +++++++
6 files changed, 166 insertions(+), 5 deletions(-)
create mode 100644 offload/unittests/OffloadAPI/kernel/olGetKernelInfo.cpp
create mode 100644 offload/unittests/OffloadAPI/kernel/olGetKernelInfoSize.cpp
diff --git a/offload/liboffload/API/Common.td b/offload/liboffload/API/Common.td
index 7674da0438c29..680396e379f16 100644
--- a/offload/liboffload/API/Common.td
+++ b/offload/liboffload/API/Common.td
@@ -77,10 +77,9 @@ def : Handle {
let desc = "Handle of program object";
}
-def : Typedef {
+def : Handle {
let name = "ol_kernel_handle_t";
let desc = "Handle of kernel object";
- let value = "void *";
}
def ErrorCode : Enum {
diff --git a/offload/liboffload/API/Kernel.td b/offload/liboffload/API/Kernel.td
index 247f9c1bf5b6a..e61916d91f2dd 100644
--- a/offload/liboffload/API/Kernel.td
+++ b/offload/liboffload/API/Kernel.td
@@ -10,6 +10,15 @@
//
//===----------------------------------------------------------------------===//
+def : Enum {
+ let name = "ol_kernel_info_t";
+ let desc = "Supported kernel info.";
+ let is_typed = 1;
+ let etors =[
+ TaggedEtor<"PROGRAM", "ol_program_handle_t", "the program associated with this kernel">,
+ ];
+}
+
def : Function {
let name = "olGetKernel";
let desc = "Get a kernel from the function identified by `KernelName` in the given program.";
@@ -59,3 +68,44 @@ def : Function {
Return<"OL_ERRC_INVALID_DEVICE", ["If Queue is non-null but does not belong to Device"]>,
];
}
+
+def : Function {
+ let name = "olGetKernelInfo";
+ let desc = "Queries the given property of the device.";
+ let details = [];
+ let params = [
+ Param<"ol_kernel_handle_t", "Kernel", "handle of the kernel instance", PARAM_IN>,
+ Param<"ol_kernel_info_t", "PropName", "type of the info to retrieve", PARAM_IN>,
+ Param<"size_t", "PropSize", "the number of bytes pointed to by PropValue.", PARAM_IN>,
+ TypeTaggedParam<"void*", "PropValue", "array of bytes holding the info. If PropSize is not equal to or greater than the real "
+ "number of bytes needed to return the info then the OL_ERRC_INVALID_SIZE error is returned and "
+ "PropValue is not used.", PARAM_OUT, TypeInfo<"PropName" , "PropSize">>
+ ];
+ let returns = [
+ Return<"OL_ERRC_UNSUPPORTED_ENUMERATION", [
+ "If `PropName` is not supported by the kernel."
+ ]>,
+ Return<"OL_ERRC_INVALID_SIZE", [
+ "`PropSize == 0`",
+ "If `PropSize` is less than the real number of bytes needed to return the info."
+ ]>,
+ Return<"OL_ERRC_INVALID_DEVICE">
+ ];
+}
+
+def : Function {
+ let name = "olGetKernelInfoSize";
+ let desc = "Returns the storage size of the given device query.";
+ let details = [];
+ let params = [
+ Param<"ol_kernel_handle_t", "Kernel", "handle of the kernel instance", PARAM_IN>,
+ Param<"ol_kernel_info_t", "PropName", "type of the info to retrieve", PARAM_IN>,
+ Param<"size_t*", "PropSizeRet", "pointer to the number of bytes required to store the query", PARAM_OUT>
+ ];
+ let returns = [
+ Return<"OL_ERRC_UNSUPPORTED_ENUMERATION", [
+ "If `PropName` is not supported by the kernel."
+ ]>,
+ Return<"OL_ERRC_INVALID_DEVICE">
+ ];
+}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 7b67cbba43e68..71aff00052ace 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -85,6 +85,13 @@ struct ol_program_impl_t {
__tgt_device_image DeviceImage;
};
+struct ol_kernel_impl_t {
+ ol_kernel_impl_t(plugin::GenericKernelTy *Kernel, ol_program_handle_t Program)
+ : Kernel(Kernel), Program(Program) {}
+ plugin::GenericKernelTy *Kernel;
+ ol_program_handle_t Program;
+};
+
namespace llvm {
namespace offload {
@@ -286,6 +293,34 @@ Error olGetDeviceInfoSize_impl(ol_device_handle_t Device,
return olGetDeviceInfoImplDetail(Device, PropName, 0, nullptr, PropSizeRet);
}
+Error olGetKernelInfoImplDetail(ol_kernel_handle_t Kernel,
+ ol_kernel_info_t PropName, size_t PropSize,
+ void *PropValue, size_t *PropSizeRet) {
+
+ ReturnHelper ReturnValue(PropSize, PropValue, PropSizeRet);
+
+ switch (PropName) {
+ case OL_KERNEL_INFO_PROGRAM:
+ return ReturnValue(Kernel->Program);
+ default:
+ return createOffloadError(ErrorCode::INVALID_ENUMERATION,
+ "getKernelInfo enum '%i' is invalid", PropName);
+ }
+
+ return Error::success();
+}
+
+Error olGetKernelInfo_impl(ol_kernel_handle_t Kernel, ol_kernel_info_t PropName,
+ size_t PropSize, void *PropValue) {
+ return olGetKernelInfoImplDetail(Kernel, PropName, PropSize, PropValue,
+ nullptr);
+}
+
+Error olGetKernelInfoSize_impl(ol_kernel_handle_t Kernel,
+ ol_kernel_info_t PropName, size_t *PropSizeRet) {
+ return olGetKernelInfoImplDetail(Kernel, PropName, 0, nullptr, PropSizeRet);
+}
+
Error olIterateDevices_impl(ol_device_iterate_cb_t Callback, void *UserData) {
for (auto &Platform : Platforms()) {
for (auto &Device : Platform.Devices) {
@@ -479,7 +514,7 @@ Error olGetKernel_impl(ol_program_handle_t Program, const char *KernelName,
if (auto Err = KernelImpl->init(Device, *Program->Image))
return Err;
- *Kernel = &*KernelImpl;
+ *Kernel = new ol_kernel_impl_t(std::move(&*KernelImpl), Program);
return Error::success();
}
@@ -514,7 +549,7 @@ Error olLaunchKernel_impl(ol_queue_handle_t Queue, ol_device_handle_t Device,
// Don't do anything with pointer indirection; use arg data as-is
LaunchArgs.Flags.IsCUDA = true;
- auto *KernelImpl = reinterpret_cast<GenericKernelTy *>(Kernel);
+ auto *KernelImpl = Kernel->Kernel;
auto Err = KernelImpl->launch(*DeviceImpl, LaunchArgs.ArgPtrs, nullptr,
LaunchArgs, AsyncInfoWrapper);
diff --git a/offload/unittests/OffloadAPI/CMakeLists.txt b/offload/unittests/OffloadAPI/CMakeLists.txt
index 2844b675e5de1..245710e7d8ac4 100644
--- a/offload/unittests/OffloadAPI/CMakeLists.txt
+++ b/offload/unittests/OffloadAPI/CMakeLists.txt
@@ -14,7 +14,9 @@ add_offload_unittest("event"
add_offload_unittest("kernel"
kernel/olGetKernel.cpp
- kernel/olLaunchKernel.cpp)
+ kernel/olLaunchKernel.cpp
+ kernel/olGetKernelInfo.cpp
+ kernel/olGetKernelInfoSize.cpp)
add_offload_unittest("memory"
memory/olMemAlloc.cpp
diff --git a/offload/unittests/OffloadAPI/kernel/olGetKernelInfo.cpp b/offload/unittests/OffloadAPI/kernel/olGetKernelInfo.cpp
new file mode 100644
index 0000000000000..ceaf40fb0d353
--- /dev/null
+++ b/offload/unittests/OffloadAPI/kernel/olGetKernelInfo.cpp
@@ -0,0 +1,55 @@
+//===------- Offload API tests - olGetKernelInfo --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <OffloadAPI.h>
+
+#include "../common/Fixtures.hpp"
+
+using olGetKernelInfoTest = OffloadKernelTest;
+OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetKernelInfoTest);
+
+TEST_P(olGetKernelInfoTest, SuccessProgram) {
+ ol_program_handle_t ReadProgram;
+ ASSERT_SUCCESS(olGetKernelInfo(Kernel, OL_KERNEL_INFO_PROGRAM,
+ sizeof(ol_program_handle_t), &ReadProgram));
+ ASSERT_EQ(Program, ReadProgram);
+}
+
+TEST_P(olGetKernelInfoTest, InvalidNullHandle) {
+ ol_program_handle_t Program;
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
+ olGetKernelInfo(nullptr, OL_KERNEL_INFO_PROGRAM, sizeof(Program),
+ &Program));
+}
+
+TEST_P(olGetKernelInfoTest, InvalidKernelInfoEnumeration) {
+ ol_program_handle_t Program;
+ ASSERT_ERROR(OL_ERRC_INVALID_ENUMERATION,
+ olGetKernelInfo(Kernel, OL_KERNEL_INFO_FORCE_UINT32,
+ sizeof(Program), &Program));
+}
+
+TEST_P(olGetKernelInfoTest, InvalidSizeZero) {
+ ol_program_handle_t Program;
+ ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
+ olGetKernelInfo(Kernel, OL_KERNEL_INFO_PROGRAM, 0, &Program));
+}
+
+TEST_P(olGetKernelInfoTest, InvalidSizeSmall) {
+ ol_program_handle_t Program;
+ ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
+ olGetKernelInfo(Kernel, OL_KERNEL_INFO_PROGRAM,
+ sizeof(Program) - 1, &Program));
+}
+
+TEST_P(olGetKernelInfoTest, InvalidNullPointerPropValue) {
+ ol_program_handle_t Program;
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+ olGetKernelInfo(Kernel, OL_KERNEL_INFO_PROGRAM, sizeof(Program),
+ nullptr));
+}
diff --git a/offload/unittests/OffloadAPI/kernel/olGetKernelInfoSize.cpp b/offload/unittests/OffloadAPI/kernel/olGetKernelInfoSize.cpp
new file mode 100644
index 0000000000000..4c726764f4e42
--- /dev/null
+++ b/offload/unittests/OffloadAPI/kernel/olGetKernelInfoSize.cpp
@@ -0,0 +1,20 @@
+//===------- Offload API tests - olGetKernelInfoSize ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <OffloadAPI.h>
+
+#include "../common/Fixtures.hpp"
+
+using olGetKernelInfoSizeTest = OffloadKernelTest;
+OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetKernelInfoSizeTest);
+
+TEST_P(olGetKernelInfoSizeTest, SuccessProgram) {
+ size_t Size = 0;
+ ASSERT_SUCCESS(olGetKernelInfoSize(Kernel, OL_KERNEL_INFO_PROGRAM, &Size));
+ ASSERT_EQ(Size, sizeof(ol_program_handle_t));
+}
>From 842bdaae6f0f9bc388c1d5437ee167dadd7be88b Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Tue, 3 Jun 2025 16:26:06 +0100
Subject: [PATCH 2/3] Don't std::move a pointer
---
offload/liboffload/src/OffloadImpl.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 71aff00052ace..348dda0f06a5d 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -514,7 +514,7 @@ Error olGetKernel_impl(ol_program_handle_t Program, const char *KernelName,
if (auto Err = KernelImpl->init(Device, *Program->Image))
return Err;
- *Kernel = new ol_kernel_impl_t(std::move(&*KernelImpl), Program);
+ *Kernel = new ol_kernel_impl_t(&*KernelImpl, Program);
return Error::success();
}
>From 3ede7b6d12be2b986aa065d101084c25c4097c52 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Wed, 4 Jun 2025 11:27:51 +0100
Subject: [PATCH 3/3] Track down some misrenames
---
offload/liboffload/API/Common.td | 1 +
offload/liboffload/API/Kernel.td | 8 ++++----
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/offload/liboffload/API/Common.td b/offload/liboffload/API/Common.td
index 680396e379f16..b3e7000628b58 100644
--- a/offload/liboffload/API/Common.td
+++ b/offload/liboffload/API/Common.td
@@ -112,6 +112,7 @@ def ErrorCode : Enum {
Etor<"INVALID_DEVICE", "invalid device">,
Etor<"INVALID_QUEUE", "invalid queue">,
Etor<"INVALID_EVENT", "invalid event">,
+ Etor<"INVALID_KERNEL", "invalid kernel">,
];
}
diff --git a/offload/liboffload/API/Kernel.td b/offload/liboffload/API/Kernel.td
index e61916d91f2dd..765ffdf2f1860 100644
--- a/offload/liboffload/API/Kernel.td
+++ b/offload/liboffload/API/Kernel.td
@@ -71,7 +71,7 @@ def : Function {
def : Function {
let name = "olGetKernelInfo";
- let desc = "Queries the given property of the device.";
+ let desc = "Queries the given property of the kernel.";
let details = [];
let params = [
Param<"ol_kernel_handle_t", "Kernel", "handle of the kernel instance", PARAM_IN>,
@@ -89,13 +89,13 @@ def : Function {
"`PropSize == 0`",
"If `PropSize` is less than the real number of bytes needed to return the info."
]>,
- Return<"OL_ERRC_INVALID_DEVICE">
+ Return<"OL_ERRC_INVALID_KERNEL">
];
}
def : Function {
let name = "olGetKernelInfoSize";
- let desc = "Returns the storage size of the given device query.";
+ let desc = "Returns the storage size of the given kernel query.";
let details = [];
let params = [
Param<"ol_kernel_handle_t", "Kernel", "handle of the kernel instance", PARAM_IN>,
@@ -106,6 +106,6 @@ def : Function {
Return<"OL_ERRC_UNSUPPORTED_ENUMERATION", [
"If `PropName` is not supported by the kernel."
]>,
- Return<"OL_ERRC_INVALID_DEVICE">
+ Return<"OL_ERRC_INVALID_KERNEL">
];
}
More information about the llvm-commits
mailing list