[llvm] [Offload] Implement olGetQueueInfo, olGetEventInfo (PR #142947)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 5 04:18:30 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-offload

Author: Callum Fare (callumfare)

<details>
<summary>Changes</summary>

Add info queries for queues and events.

`olGetQueueInfo` only supports getting the associated device. We were already tracking this so we can implement this for free. We will likely add other queries to it in the future (whether the queue is empty, what flags it was created with, etc)

`olGetEventInfo` only supports getting the associated queue. This is another thing we were already storing in the handle. We'll be able to add other queries in future (the event type, status, etc)

---
Full diff: https://github.com/llvm/llvm-project/pull/142947.diff


7 Files Affected:

- (modified) offload/liboffload/API/Event.td (+48) 
- (modified) offload/liboffload/API/Queue.td (+48) 
- (modified) offload/liboffload/src/OffloadImpl.cpp (+55) 
- (modified) offload/unittests/OffloadAPI/CMakeLists.txt (+6-2) 
- (modified) offload/unittests/OffloadAPI/common/Fixtures.hpp (+25) 
- (added) offload/unittests/OffloadAPI/queue/olGetQueueInfo.cpp (+55) 
- (added) offload/unittests/OffloadAPI/queue/olGetQueueInfoSize.cpp (+37) 


``````````diff
diff --git a/offload/liboffload/API/Event.td b/offload/liboffload/API/Event.td
index c9f79159cf263..dd5751cc0bdaf 100644
--- a/offload/liboffload/API/Event.td
+++ b/offload/liboffload/API/Event.td
@@ -29,3 +29,51 @@ def : Function {
     ];
     let returns = [];
 }
+
+def : Enum {
+  let name = "ol_event_info_t";
+  let desc = "Supported event info.";
+  let is_typed = 1;
+  let etors = [
+    TaggedEtor<"QUEUE", "ol_queue_handle_t", "The handle of the queue associated with the device.">
+  ];
+}
+
+def : Function {
+  let name = "olGetEventInfo";
+  let desc = "Queries the given property of the event.";
+  let details = [
+    "`olGetEventInfoSize` can be used to query the storage size "
+    "required for the given query."
+  ];
+  let params = [
+    Param<"ol_event_handle_t", "Event", "handle of the event", PARAM_IN>,
+    Param<"ol_event_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 to 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_INVALID_SIZE", [
+      "`PropSize == 0`",
+      "If `PropSize` is less than the real number of bytes needed to return the info."
+    ]>,
+    Return<"OL_ERRC_INVALID_EVENT">
+  ];
+}
+
+def : Function {
+  let name = "olGetEventInfoSize";
+  let desc = "Returns the storage size of the given event query.";
+  let details = [];
+  let params = [
+    Param<"ol_event_handle_t", "Event", "handle of the event", PARAM_IN>,
+    Param<"ol_event_info_t", "PropName", "type of the info to query", PARAM_IN>,
+    Param<"size_t*", "PropSizeRet", "pointer to the number of bytes required to store the query", PARAM_OUT>
+  ];
+  let returns = [
+    Return<"OL_ERRC_INVALID_EVENT">
+  ];
+}
diff --git a/offload/liboffload/API/Queue.td b/offload/liboffload/API/Queue.td
index b5bb619c57514..fea928321cd12 100644
--- a/offload/liboffload/API/Queue.td
+++ b/offload/liboffload/API/Queue.td
@@ -40,3 +40,51 @@ def : Function {
     ];
     let returns = [];
 }
+
+def : Enum {
+  let name = "ol_queue_info_t";
+  let desc = "Supported queue info.";
+  let is_typed = 1;
+  let etors = [
+    TaggedEtor<"DEVICE", "ol_device_handle_t", "The handle of the device associated with the queue.">
+  ];
+}
+
+def : Function {
+  let name = "olGetQueueInfo";
+  let desc = "Queries the given property of the queue.";
+  let details = [
+    "`olGetQueueInfoSize` can be used to query the storage size "
+    "required for the given query."
+  ];
+  let params = [
+    Param<"ol_queue_handle_t", "Queue", "handle of the queue", PARAM_IN>,
+    Param<"ol_queue_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 Size is not equal to or greater to the real number of bytes needed to return the info "
+      "then the OL_ERRC_INVALID_SIZE error is returned and pPlatformInfo is not used.", PARAM_OUT,
+      TypeInfo<"PropName" , "PropSize">>
+  ];
+  let returns = [
+    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_QUEUE">
+  ];
+}
+
+def : Function {
+  let name = "olGetQueueInfoSize";
+  let desc = "Returns the storage size of the given queue query.";
+  let details = [];
+  let params = [
+    Param<"ol_queue_handle_t", "Queue", "handle of the queue", PARAM_IN>,
+    Param<"ol_queue_info_t", "PropName", "type of the info to query", PARAM_IN>,
+    Param<"size_t*", "PropSizeRet", "pointer to the number of bytes required to store the query", PARAM_OUT>
+  ];
+  let returns = [
+    Return<"OL_ERRC_INVALID_QUEUE">
+  ];
+}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 7b67cbba43e68..4d59414072153 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -368,6 +368,33 @@ Error olWaitQueue_impl(ol_queue_handle_t Queue) {
   return Error::success();
 }
 
+Error olGetQueueInfoImplDetail(ol_queue_handle_t Queue,
+                               ol_queue_info_t PropName, size_t PropSize,
+                               void *PropValue, size_t *PropSizeRet) {
+  ReturnHelper ReturnValue(PropSize, PropValue, PropSizeRet);
+
+  switch (PropName) {
+  case OL_QUEUE_INFO_DEVICE:
+    return ReturnValue(Queue->Device);
+  default:
+    return createOffloadError(ErrorCode::INVALID_ENUMERATION,
+                              "olGetQueueInfo enum '%i' is invalid", PropName);
+  }
+
+  return Error::success();
+}
+
+Error olGetQueueInfo_impl(ol_queue_handle_t Queue, ol_queue_info_t PropName,
+                          size_t PropSize, void *PropValue) {
+  return olGetQueueInfoImplDetail(Queue, PropName, PropSize, PropValue,
+                                  nullptr);
+}
+
+Error olGetQueueInfoSize_impl(ol_queue_handle_t Queue, ol_queue_info_t PropName,
+                              size_t *PropSizeRet) {
+  return olGetQueueInfoImplDetail(Queue, PropName, 0, nullptr, PropSizeRet);
+}
+
 Error olWaitEvent_impl(ol_event_handle_t Event) {
   if (auto Res = Event->Queue->Device->Device->syncEvent(Event->EventInfo))
     return Res;
@@ -382,6 +409,34 @@ Error olDestroyEvent_impl(ol_event_handle_t Event) {
   return olDestroy(Event);
 }
 
+Error olGetEventInfoImplDetail(ol_event_handle_t Event,
+                               ol_event_info_t PropName, size_t PropSize,
+                               void *PropValue, size_t *PropSizeRet) {
+  ReturnHelper ReturnValue(PropSize, PropValue, PropSizeRet);
+
+  switch (PropName) {
+  case OL_EVENT_INFO_QUEUE:
+    return ReturnValue(Event->Queue);
+  default:
+    return createOffloadError(ErrorCode::INVALID_ENUMERATION,
+                              "olGetEventInfo enum '%i' is invalid", PropName);
+  }
+
+  return Error::success();
+}
+
+Error olGetEventInfo_impl(ol_event_handle_t Event, ol_event_info_t PropName,
+                          size_t PropSize, void *PropValue) {
+
+  return olGetEventInfoImplDetail(Event, PropName, PropSize, PropValue,
+                                  nullptr);
+}
+
+Error olGetEventInfoSize_impl(ol_event_handle_t Event, ol_event_info_t PropName,
+                              size_t *PropSizeRet) {
+  return olGetEventInfoImplDetail(Event, PropName, 0, nullptr, PropSizeRet);
+}
+
 ol_event_handle_t makeEvent(ol_queue_handle_t Queue) {
   auto EventImpl = std::make_unique<ol_event_impl_t>(nullptr, Queue);
   if (auto Res = Queue->Device->Device->createEvent(&EventImpl->EventInfo)) {
diff --git a/offload/unittests/OffloadAPI/CMakeLists.txt b/offload/unittests/OffloadAPI/CMakeLists.txt
index 2844b675e5de1..04144c17b1453 100644
--- a/offload/unittests/OffloadAPI/CMakeLists.txt
+++ b/offload/unittests/OffloadAPI/CMakeLists.txt
@@ -10,7 +10,9 @@ add_offload_unittest("device"
 
 add_offload_unittest("event"
     event/olDestroyEvent.cpp
-    event/olWaitEvent.cpp)
+    event/olWaitEvent.cpp
+    event/olGetEventInfo.cpp
+    event/olGetEventInfoSize.cpp)
 
 add_offload_unittest("kernel"
     kernel/olGetKernel.cpp
@@ -32,4 +34,6 @@ add_offload_unittest("program"
 add_offload_unittest("queue"
     queue/olCreateQueue.cpp
     queue/olWaitQueue.cpp
-    queue/olDestroyQueue.cpp)
+    queue/olDestroyQueue.cpp
+    queue/olGetQueueInfo.cpp
+    queue/olGetQueueInfoSize.cpp)
diff --git a/offload/unittests/OffloadAPI/common/Fixtures.hpp b/offload/unittests/OffloadAPI/common/Fixtures.hpp
index ff3c1f4194807..5a7f8cd51be16 100644
--- a/offload/unittests/OffloadAPI/common/Fixtures.hpp
+++ b/offload/unittests/OffloadAPI/common/Fixtures.hpp
@@ -139,6 +139,31 @@ struct OffloadQueueTest : OffloadDeviceTest {
   ol_queue_handle_t Queue = nullptr;
 };
 
+struct OffloadEventTest : OffloadQueueTest {
+  void SetUp() override {
+    RETURN_ON_FATAL_FAILURE(OffloadQueueTest::SetUp());
+
+    // Get an event from a memcpy. We can still use it in olGetEventInfo etc
+    // after it has been waited on.
+    void *Alloc;
+    uint32_t Value = 42;
+    ASSERT_SUCCESS(
+        olMemAlloc(Device, OL_ALLOC_TYPE_DEVICE, sizeof(Value), &Alloc));
+    ASSERT_SUCCESS(
+        olMemcpy(Queue, Alloc, Device, &Value, Host, sizeof(Value), &Event));
+    ASSERT_SUCCESS(olWaitEvent(Event));
+    ASSERT_SUCCESS(olMemFree(Alloc));
+  }
+
+  void TearDown() override {
+    if (Event)
+      olDestroyEvent(Event);
+    RETURN_ON_FATAL_FAILURE(OffloadQueueTest::TearDown());
+  }
+
+  ol_event_handle_t Event = nullptr;
+};
+
 #define OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(FIXTURE)                      \
   INSTANTIATE_TEST_SUITE_P(                                                    \
       , FIXTURE, ::testing::ValuesIn(TestEnvironment::getDevices()),           \
diff --git a/offload/unittests/OffloadAPI/queue/olGetQueueInfo.cpp b/offload/unittests/OffloadAPI/queue/olGetQueueInfo.cpp
new file mode 100644
index 0000000000000..f4fb752d7ab40
--- /dev/null
+++ b/offload/unittests/OffloadAPI/queue/olGetQueueInfo.cpp
@@ -0,0 +1,55 @@
+//===------- Offload API tests - olGetQueueInfo ---------------------------===//
+//
+// 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 olGetQueueInfoTest = OffloadQueueTest;
+OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetQueueInfoTest);
+
+TEST_P(olGetQueueInfoTest, SuccessDevice) {
+  ol_device_handle_t RetrievedDevice;
+  ASSERT_SUCCESS(olGetQueueInfo(Queue, OL_QUEUE_INFO_DEVICE,
+                                sizeof(ol_device_handle_t), &RetrievedDevice));
+  ASSERT_EQ(Device, RetrievedDevice);
+}
+
+TEST_P(olGetQueueInfoTest, InvalidNullHandle) {
+  ol_device_handle_t RetrievedDevice;
+  ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
+               olGetQueueInfo(nullptr, OL_QUEUE_INFO_DEVICE,
+                              sizeof(RetrievedDevice), &RetrievedDevice));
+}
+
+TEST_P(olGetQueueInfoTest, InvalidQueueInfoEnumeration) {
+  ol_device_handle_t RetrievedDevice;
+  ASSERT_ERROR(OL_ERRC_INVALID_ENUMERATION,
+               olGetQueueInfo(Queue, OL_QUEUE_INFO_FORCE_UINT32,
+                              sizeof(RetrievedDevice), &RetrievedDevice));
+}
+
+TEST_P(olGetQueueInfoTest, InvalidSizeZero) {
+  ol_device_handle_t RetrievedDevice;
+  ASSERT_ERROR(OL_ERRC_INVALID_SIZE, olGetQueueInfo(Queue, OL_QUEUE_INFO_DEVICE,
+                                                    0, &RetrievedDevice));
+}
+
+TEST_P(olGetQueueInfoTest, InvalidSizeSmall) {
+  ol_device_handle_t RetrievedDevice;
+  ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
+               olGetQueueInfo(Queue, OL_QUEUE_INFO_DEVICE,
+                              sizeof(RetrievedDevice) - 1, &RetrievedDevice));
+}
+
+TEST_P(olGetQueueInfoTest, InvalidNullPointerPropValue) {
+  ol_device_handle_t RetrievedDevice;
+  ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+               olGetQueueInfo(Queue, OL_QUEUE_INFO_DEVICE,
+                              sizeof(RetrievedDevice), nullptr));
+}
diff --git a/offload/unittests/OffloadAPI/queue/olGetQueueInfoSize.cpp b/offload/unittests/OffloadAPI/queue/olGetQueueInfoSize.cpp
new file mode 100644
index 0000000000000..f1ad9fa890d71
--- /dev/null
+++ b/offload/unittests/OffloadAPI/queue/olGetQueueInfoSize.cpp
@@ -0,0 +1,37 @@
+//===------- Offload API tests - olGetQueueInfoSize -----------------------===//
+//
+// 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 olGetQueueInfoSizeTest = OffloadQueueTest;
+OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olGetQueueInfoSizeTest);
+
+TEST_P(olGetQueueInfoSizeTest, SuccessDevice) {
+  size_t Size = 0;
+  ASSERT_SUCCESS(olGetQueueInfoSize(Queue, OL_QUEUE_INFO_DEVICE, &Size));
+  ASSERT_EQ(Size, sizeof(ol_device_handle_t));
+}
+
+TEST_P(olGetQueueInfoSizeTest, InvalidNullHandle) {
+  size_t Size = 0;
+  ASSERT_ERROR(OL_ERRC_INVALID_NULL_HANDLE,
+               olGetQueueInfoSize(nullptr, OL_QUEUE_INFO_DEVICE, &Size));
+}
+
+TEST_P(olGetQueueInfoSizeTest, InvalidQueueInfoEnumeration) {
+  size_t Size = 0;
+  ASSERT_ERROR(OL_ERRC_INVALID_ENUMERATION,
+               olGetQueueInfoSize(Queue, OL_QUEUE_INFO_FORCE_UINT32, &Size));
+}
+
+TEST_P(olGetQueueInfoSizeTest, InvalidNullPointer) {
+  ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+               olGetQueueInfoSize(Queue, OL_QUEUE_INFO_DEVICE, nullptr));
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/142947


More information about the llvm-commits mailing list