[llvm] [offload] add context to olMemAlloc* (PR #222677)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 07:52:14 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Ɓukasz Plewa (lplewa)

<details>
<summary>Changes</summary>

This is the last part of the context refactor. This patch:
- Adds context param to all memory allocation functions.
- Routes ptr info through the plugins instead of a global map.
- Removes allocation tracking from liboffload.
- olGetMemInfo(OL_MEM_INFO_DEVICE) now returns INVALID_ARGUMENT for host allocations, which have no per-device affinity.

Assisted-by: Claude Opus 4.7

---

Patch is 118.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/222677.diff


35 Files Affected:

- (modified) libsycl/src/detail/queue_impl.cpp (+7-4) 
- (modified) libsycl/src/usm_functions.cpp (+7-4) 
- (modified) libsycl/unittests/handler/test_helpers.hpp (+4-4) 
- (modified) libsycl/unittests/mock/helpers.cpp (+19-11) 
- (modified) libsycl/unittests/mock/helpers.hpp (+8-6) 
- (modified) libsycl/unittests/mock/mock.cpp (+15-11) 
- (modified) libsycl/unittests/queue/memcpy.cpp (+6-4) 
- (modified) offload/languages/kernel/src/LanguageRuntime.cpp (+9-4) 
- (modified) offload/liboffload/API/Memory.td (+32-7) 
- (modified) offload/liboffload/src/OffloadImpl.cpp (+113-147) 
- (modified) offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h (+2) 
- (modified) offload/plugins-nextgen/amdgpu/src/rtl.cpp (+73) 
- (modified) offload/plugins-nextgen/common/include/PluginInterface.h (+78-25) 
- (modified) offload/plugins-nextgen/common/src/PluginInterface.cpp (+133-63) 
- (modified) offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h (+15-1) 
- (modified) offload/plugins-nextgen/cuda/src/rtl.cpp (+70) 
- (modified) offload/plugins-nextgen/host/src/rtl.cpp (+50) 
- (modified) offload/plugins-nextgen/level_zero/include/L0Plugin.h (+2) 
- (modified) offload/plugins-nextgen/level_zero/src/L0Plugin.cpp (+25) 
- (modified) offload/unittests/Conformance/include/mathtest/DeviceContext.hpp (+5-3) 
- (modified) offload/unittests/Conformance/include/mathtest/DeviceResources.hpp (+9-6) 
- (modified) offload/unittests/Conformance/lib/DeviceContext.cpp (+4-3) 
- (modified) offload/unittests/Conformance/lib/DeviceResources.cpp (+3-2) 
- (modified) offload/unittests/OffloadAPI/event/olGetEventElapsedTime.cpp (+2-2) 
- (modified) offload/unittests/OffloadAPI/kernel/olLaunchKernel.cpp (+39-35) 
- (modified) offload/unittests/OffloadAPI/memory/olGetMemInfo.cpp (+33-22) 
- (modified) offload/unittests/OffloadAPI/memory/olGetMemInfoSize.cpp (+9-7) 
- (modified) offload/unittests/OffloadAPI/memory/olMemAlloc.cpp (+16-13) 
- (modified) offload/unittests/OffloadAPI/memory/olMemAllocAligned.cpp (+22-19) 
- (modified) offload/unittests/OffloadAPI/memory/olMemFill.cpp (+30-20) 
- (modified) offload/unittests/OffloadAPI/memory/olMemFree.cpp (+7-6) 
- (modified) offload/unittests/OffloadAPI/memory/olMemPrefetch.cpp (+21-14) 
- (modified) offload/unittests/OffloadAPI/memory/olMemcpy.cpp (+39-32) 
- (modified) offload/unittests/OffloadAPI/queue/olLaunchHostFunction.cpp (+2-2) 
- (modified) offload/unittests/OffloadAPI/queue/olWaitEvents.cpp (+3-3) 


``````````diff
diff --git a/libsycl/src/detail/queue_impl.cpp b/libsycl/src/detail/queue_impl.cpp
index 65fe04eeadd37..2705b0024290c 100644
--- a/libsycl/src/detail/queue_impl.cpp
+++ b/libsycl/src/detail/queue_impl.cpp
@@ -138,11 +138,12 @@ void QueueImpl::submitKernelImpl(DeviceKernelInfo &KernelInfo, void *ArgData,
       createEvent(std::move(MCurrentSubmitInfo.DepEvents));
 }
 
-static ol_device_handle_t getAllocDevice(const void *ptr) {
+static ol_device_handle_t getAllocDevice(ol_context_handle_t Context,
+                                         const void *ptr) {
   // TODO: consider caching this information to avoid querying it every time.
   ol_device_handle_t Device{};
   [[maybe_unused]] ol_result_t Result =
-      callNoCheck(olGetMemInfo, ptr, OL_MEM_INFO_DEVICE,
+      callNoCheck(olGetMemInfo, Context, ptr, OL_MEM_INFO_DEVICE,
                   sizeof(ol_device_handle_t), &Device);
   if (detail::isFailed(Result)) {
     // If liboffload could not find the allocation, assume it is a host one.
@@ -169,8 +170,10 @@ QueueImpl::memcpy(void *Dest, const void *Src, std::size_t NumBytes,
                           "Nullptr argument in memcpy operation");
   }
 
-  ol_device_handle_t DestOLDevice = getAllocDevice(Dest);
-  ol_device_handle_t SrcOLDevice = getAllocDevice(Src);
+  ol_device_handle_t DestOLDevice =
+      getAllocDevice(MContext.getOLHandleRef(), Dest);
+  ol_device_handle_t SrcOLDevice =
+      getAllocDevice(MContext.getOLHandleRef(), Src);
 
   handleEventDependencies(DepEvents);
   callAndThrow(olMemcpy, MOffloadQueue, Dest, DestOLDevice, Src, SrcOLDevice,
diff --git a/libsycl/src/usm_functions.cpp b/libsycl/src/usm_functions.cpp
index 0f921e055f9a2..352912cdaad86 100644
--- a/libsycl/src/usm_functions.cpp
+++ b/libsycl/src/usm_functions.cpp
@@ -8,6 +8,7 @@
 
 #include <sycl/__impl/usm_functions.hpp>
 
+#include <detail/context_impl.hpp>
 #include <detail/device_impl.hpp>
 #include <detail/offload/offload_utils.hpp>
 
@@ -103,10 +104,12 @@ void *malloc(std::size_t numBytes, const device &syclDevice,
 
   void *Ptr{};
   auto OLDevice = detail::getSyclObjImpl(syclDevice)->getOLHandle();
+  auto OLContext = detail::getSyclObjImpl(syclContext)->getOLHandleRef();
   auto Result =
       kind == usm::alloc::host
-          ? detail::callNoCheck(olMemAllocHost, OLDevice, numBytes, &Ptr)
-          : detail::callNoCheck(olMemAlloc, OLDevice,
+          ? detail::callNoCheck(olMemAllocHost, OLContext, OLDevice, numBytes,
+                                &Ptr)
+          : detail::callNoCheck(olMemAlloc, OLContext, OLDevice,
                                 detail::getOlAllocType(kind), numBytes, &Ptr);
   return detail::isFailed(Result) ? nullptr : Ptr;
 }
@@ -120,8 +123,8 @@ void *malloc(std::size_t numBytes, const queue &syclQueue, usm::alloc kind,
 // SYCL 2020 4.8.3.6. Memory deallocation functions.
 
 void free(void *ptr, const context &ctxt) {
-  std::ignore = ctxt;
-  detail::callAndThrow(olMemFree, ptr);
+  auto OLContext = detail::getSyclObjImpl(ctxt)->getOLHandleRef();
+  detail::callAndThrow(olMemFree, OLContext, ptr);
 }
 
 void free(void *ptr, const queue &q) { return free(ptr, q.get_context()); }
diff --git a/libsycl/unittests/handler/test_helpers.hpp b/libsycl/unittests/handler/test_helpers.hpp
index ad43374df79cd..1c383e747390e 100644
--- a/libsycl/unittests/handler/test_helpers.hpp
+++ b/libsycl/unittests/handler/test_helpers.hpp
@@ -18,12 +18,12 @@ inline void expectDeviceMemoryInfo(mock::MockWrapper &Mock,
                                    const std::vector<const void *> ExpectedPtrs,
                                    ol_device_handle_t Device, int Count) {
   EXPECT_CALL(Mock.get(),
-              olGetMemInfo(::testing::_, OL_MEM_INFO_DEVICE,
+              olGetMemInfo(::testing::_, ::testing::_, OL_MEM_INFO_DEVICE,
                            sizeof(ol_device_handle_t), ::testing::_))
       .Times(Count)
-      .WillRepeatedly([ExpectedPtrs, Device](const void *Ptr, ol_mem_info_t,
-                                             size_t,
-                                             void *PropValue) -> ol_result_t {
+      .WillRepeatedly([ExpectedPtrs, Device](
+                          ol_context_handle_t, const void *Ptr, ol_mem_info_t,
+                          size_t, void *PropValue) -> ol_result_t {
         EXPECT_NE(std::find(ExpectedPtrs.begin(), ExpectedPtrs.end(), Ptr),
                   ExpectedPtrs.end());
         *(static_cast<ol_device_handle_t *>(PropValue)) = Device;
diff --git a/libsycl/unittests/mock/helpers.cpp b/libsycl/unittests/mock/helpers.cpp
index dcf563a1a862e..665e919f61cc3 100644
--- a/libsycl/unittests/mock/helpers.cpp
+++ b/libsycl/unittests/mock/helpers.cpp
@@ -328,8 +328,10 @@ void mock::MockLiboffload::initDefault() {
         return OL_SUCCESS;
       });
   ON_CALL(*this, olGetMemInfo)
-      .WillByDefault([this](const void *Ptr, ol_mem_info_t PropName,
-                            size_t PropSize, void *PropValue) -> ol_result_t {
+      .WillByDefault([this](ol_context_handle_t Context, const void *Ptr,
+                            ol_mem_info_t PropName, size_t PropSize,
+                            void *PropValue) -> ol_result_t {
+        std::ignore = Context;
         EXPECT_NE(Ptr, nullptr);
         // Other properties are not used by the runtime yet
         EXPECT_EQ(PropName, OL_MEM_INFO_DEVICE);
@@ -346,8 +348,10 @@ void mock::MockLiboffload::initDefault() {
       });
 
   ON_CALL(*this, olMemAlloc)
-      .WillByDefault([](ol_device_handle_t Device, ol_alloc_type_t Type,
-                        size_t Size, void **AllocationOut) -> ol_result_t {
+      .WillByDefault([](ol_context_handle_t Context, ol_device_handle_t Device,
+                        ol_alloc_type_t Type, size_t Size,
+                        void **AllocationOut) -> ol_result_t {
+        std::ignore = Context;
         EXPECT_NE(Device, nullptr);
         EXPECT_NE(Type, OL_ALLOC_TYPE_HOST);
         EXPECT_GT(Size, 0);
@@ -357,8 +361,9 @@ void mock::MockLiboffload::initDefault() {
       });
 
   ON_CALL(*this, olMemAllocHost)
-      .WillByDefault([](ol_device_handle_t Device, size_t Size,
-                        void **AllocationOut) -> ol_result_t {
+      .WillByDefault([](ol_context_handle_t Context, ol_device_handle_t Device,
+                        size_t Size, void **AllocationOut) -> ol_result_t {
+        std::ignore = Context;
         EXPECT_NE(Device, nullptr);
         EXPECT_GT(Size, 0);
         EXPECT_NE(AllocationOut, nullptr);
@@ -366,9 +371,12 @@ void mock::MockLiboffload::initDefault() {
         return OL_SUCCESS;
       });
 
-  ON_CALL(*this, olMemFree).WillByDefault([](void *Address) -> ol_result_t {
-    EXPECT_NE(Address, nullptr);
-    mock::releaseDummyHandle(Address);
-    return OL_SUCCESS;
-  });
+  ON_CALL(*this, olMemFree)
+      .WillByDefault(
+          [](ol_context_handle_t Context, void *Address) -> ol_result_t {
+            std::ignore = Context;
+            EXPECT_NE(Address, nullptr);
+            mock::releaseDummyHandle(Address);
+            return OL_SUCCESS;
+          });
 }
diff --git a/libsycl/unittests/mock/helpers.hpp b/libsycl/unittests/mock/helpers.hpp
index 64b3c2fc55f23..e2d42875e7f1b 100644
--- a/libsycl/unittests/mock/helpers.hpp
+++ b/libsycl/unittests/mock/helpers.hpp
@@ -131,14 +131,16 @@ class MockLiboffload {
               (ol_queue_handle_t Queue, size_t Count, const void **Mems,
                const size_t *Sizes, ol_mem_migration_flags_t Flags));
   MOCK_METHOD(ol_result_t, olGetMemInfo,
-              (const void *Ptr, ol_mem_info_t PropName, size_t PropSize,
-               void *PropValue));
+              (ol_context_handle_t Context, const void *Ptr,
+               ol_mem_info_t PropName, size_t PropSize, void *PropValue));
   MOCK_METHOD(ol_result_t, olMemAlloc,
-              (ol_device_handle_t Device, ol_alloc_type_t Type, size_t Size,
-               void **AllocationOut));
+              (ol_context_handle_t Context, ol_device_handle_t Device,
+               ol_alloc_type_t Type, size_t Size, void **AllocationOut));
   MOCK_METHOD(ol_result_t, olMemAllocHost,
-              (ol_device_handle_t Device, size_t Size, void **AllocationOut));
-  MOCK_METHOD(ol_result_t, olMemFree, (void *Address));
+              (ol_context_handle_t Context, ol_device_handle_t Device,
+               size_t Size, void **AllocationOut));
+  MOCK_METHOD(ol_result_t, olMemFree,
+              (ol_context_handle_t Context, void *Address));
 
   ol_result_t makeEmptyStrError(ol_errc_t Code) {
     auto [Iterator, Flag] =
diff --git a/libsycl/unittests/mock/mock.cpp b/libsycl/unittests/mock/mock.cpp
index 74131c4692874..4ac97bbb71ccd 100644
--- a/libsycl/unittests/mock/mock.cpp
+++ b/libsycl/unittests/mock/mock.cpp
@@ -125,25 +125,29 @@ ol_result_t olMemPrefetch(ol_queue_handle_t Queue, size_t Count,
                                                  Flags);
 }
 
-ol_result_t olGetMemInfo(const void *Ptr, ol_mem_info_t PropName,
-                         size_t PropSize, void *PropValue) {
-  return mock::getMockLiboffload().olGetMemInfo(Ptr, PropName, PropSize,
-                                                PropValue);
+ol_result_t olGetMemInfo(ol_context_handle_t Context, const void *Ptr,
+                         ol_mem_info_t PropName, size_t PropSize,
+                         void *PropValue) {
+  return mock::getMockLiboffload().olGetMemInfo(Context, Ptr, PropName,
+                                                PropSize, PropValue);
 }
 
-ol_result_t olMemAlloc(ol_device_handle_t Device, ol_alloc_type_t Type,
-                       size_t Size, void **AllocationOut) {
-  return mock::getMockLiboffload().olMemAlloc(Device, Type, Size,
+ol_result_t olMemAlloc(ol_context_handle_t Context, ol_device_handle_t Device,
+                       ol_alloc_type_t Type, size_t Size,
+                       void **AllocationOut) {
+  return mock::getMockLiboffload().olMemAlloc(Context, Device, Type, Size,
                                               AllocationOut);
 }
 
-ol_result_t olMemAllocHost(ol_device_handle_t Device, size_t Size,
+ol_result_t olMemAllocHost(ol_context_handle_t Context,
+                           ol_device_handle_t Device, size_t Size,
                            void **AllocationOut) {
-  return mock::getMockLiboffload().olMemAllocHost(Device, Size, AllocationOut);
+  return mock::getMockLiboffload().olMemAllocHost(Context, Device, Size,
+                                                  AllocationOut);
 }
 
-ol_result_t olMemFree(void *Address) {
-  return mock::getMockLiboffload().olMemFree(Address);
+ol_result_t olMemFree(ol_context_handle_t Context, void *Address) {
+  return mock::getMockLiboffload().olMemFree(Context, Address);
 }
 
 ol_result_t olCreateEvent(ol_queue_handle_t Queue, ol_event_flags_t Flags,
diff --git a/libsycl/unittests/queue/memcpy.cpp b/libsycl/unittests/queue/memcpy.cpp
index db977f79d5bef..25e99b2689b24 100644
--- a/libsycl/unittests/queue/memcpy.cpp
+++ b/libsycl/unittests/queue/memcpy.cpp
@@ -26,11 +26,13 @@ TEST(Queue, Memcpy) {
   ol_device_handle_t OLDev =
       detail::getSyclObjImpl(Q.get_device())->getOLHandle();
 
-  EXPECT_CALL(Mock.get(), olGetMemInfo(_, OL_MEM_INFO_DEVICE,
+  EXPECT_CALL(Mock.get(), olGetMemInfo(_, _, OL_MEM_INFO_DEVICE,
                                        sizeof(ol_device_handle_t), _))
       .Times(NMemcpies * 2)
-      .WillRepeatedly([&](const void *Ptr, ol_mem_info_t PropName,
-                          size_t PropSize, void *PropValue) -> ol_result_t {
+      .WillRepeatedly([&](ol_context_handle_t Context, const void *Ptr,
+                          ol_mem_info_t PropName, size_t PropSize,
+                          void *PropValue) -> ol_result_t {
+        std::ignore = Context;
         EXPECT_TRUE(Ptr == SrcPtr || Ptr == DstPtr);
         bool IsHostPtr = Ptr == SrcPtr ? IsSrcHostPtr : IsDstHostPtr;
         if (IsHostPtr)
@@ -73,7 +75,7 @@ TEST(Queue, MemcpyZeroBytes) {
   mock::MockWrapper Mock;
   queue Q;
   EXPECT_CALL(Mock.get(), olWaitEvents(_, _, 1)).Times(1);
-  EXPECT_CALL(Mock.get(), olGetMemInfo(_, _, _, _)).Times(0);
+  EXPECT_CALL(Mock.get(), olGetMemInfo(_, _, _, _, _)).Times(0);
   EXPECT_CALL(Mock.get(), olMemcpy(_, _, _, _, _, _)).Times(0);
   event Event = Q.memcpy(nullptr, nullptr, 0);
   Q.memcpy(nullptr, nullptr, 0, Event);
diff --git a/offload/languages/kernel/src/LanguageRuntime.cpp b/offload/languages/kernel/src/LanguageRuntime.cpp
index 6dab19fc2fd8c..b4eb18c59de30 100644
--- a/offload/languages/kernel/src/LanguageRuntime.cpp
+++ b/offload/languages/kernel/src/LanguageRuntime.cpp
@@ -34,12 +34,15 @@ using namespace llvm::offload;
 Error_t Malloc(void **DevPtr, size_t Size) {
   ThreadStateTy &ThreadState = ThreadStateTy::get();
   ol_device_handle_t Device = ThreadState.getDefaultDevice();
-  ol_result_t Result = olMemAlloc(Device, OL_ALLOC_TYPE_DEVICE, Size, DevPtr);
+  ol_context_handle_t Context = StateTy::get().getContext();
+  ol_result_t Result =
+      olMemAlloc(Context, Device, OL_ALLOC_TYPE_DEVICE, Size, DevPtr);
   return convertAndSetLastError(Result);
 }
 
 Error_t Free(void *DevPtr) {
-  ol_result_t Result = olMemFree(DevPtr);
+  ol_context_handle_t Context = StateTy::get().getContext();
+  ol_result_t Result = olMemFree(Context, DevPtr);
   return convertAndSetLastError(Result);
 }
 
@@ -121,7 +124,8 @@ Error_t SetDevice(int DeviceNo) {
 Error_t HostAlloc(void **Ptr, size_t Size, unsigned int Flags) {
   ThreadStateTy &ThreadState = ThreadStateTy::get();
   ol_device_handle_t Device = ThreadState.getDefaultDevice();
-  ol_result_t Result = olMemAllocHost(Device, Size, Ptr);
+  ol_context_handle_t Context = StateTy::get().getContext();
+  ol_result_t Result = olMemAllocHost(Context, Device, Size, Ptr);
   return convertAndSetLastError(Result);
 }
 
@@ -130,7 +134,8 @@ Error_t MallocHost(void **Ptr, size_t Size) {
 }
 
 Error_t FreeHost(void *Ptr) {
-  ol_result_t Result = olMemFree(Ptr);
+  ol_context_handle_t Context = StateTy::get().getContext();
+  ol_result_t Result = olMemFree(Context, Ptr);
   return convertAndSetLastError(Result);
 }
 
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 17eabeccce9e0..23c54aee9e8a2 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -36,10 +36,11 @@ def ol_memory_register_flag_t : Enum {
 def olMemAlloc : Function {
   let desc = "Creates a memory allocation on the specified device.";
   let details = [
-      "All liboffload allocations share a single virtual address range. There is no risk of multiple devices returning equal pointers to different memory.",
+      "The allocation is scoped to `Context` and `Device` must belong to it.",
       "This function can only be used to create device or managed allocations. To create a host allocation use `olMemAllocHost`."
   ];
   let params = [
+    Param<"ol_context_handle_t", "Context", "handle of the context", PARAM_IN>,
     Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
     Param<"ol_alloc_type_t", "Type", "type of the allocation. Must be either `OL_ALLOC_TYPE_DEVICE` or `OL_ALLOC_TYPE_MANAGED`", PARAM_IN>,
     Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>,
@@ -51,6 +52,9 @@ def olMemAlloc : Function {
     ]>,
     Return<"OL_ERRC_INVALID_ENUMERATION", [
       "`Type == OL_ALLOC_TYPE_HOST`"
+    ]>,
+    Return<"OL_ERRC_INVALID_DEVICE", [
+      "Device does not belong to `Context`"
     ]>
   ];
 }
@@ -58,9 +62,10 @@ def olMemAlloc : Function {
 def olMemAllocHost : Function {
   let desc = "Creates a host memory allocation accessible from the specified device.";
   let details = [
-      "All liboffload allocations share a single virtual address range. There is no risk of multiple devices returning equal pointers to different memory."
+      "The allocation is scoped to `Context` and `Device` must belong to it."
   ];
   let params = [
+    Param<"ol_context_handle_t", "Context", "handle of the context", PARAM_IN>,
     Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
     Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>,
     Param<"void**", "AllocationOut", "output for the allocated pointer", PARAM_OUT>
@@ -68,6 +73,9 @@ def olMemAllocHost : Function {
   let returns = [
     Return<"OL_ERRC_INVALID_SIZE", [
       "`Size == 0`"
+    ]>,
+    Return<"OL_ERRC_INVALID_DEVICE", [
+      "Device does not belong to `Context`"
     ]>
   ];
 }
@@ -75,10 +83,11 @@ def olMemAllocHost : Function {
 def olMemAllocAligned : Function {
   let desc = "Creates a memory allocation on the specified device with the specified alignment.";
   let details = [
-      "All liboffload allocations share a single virtual address range. There is no risk of multiple devices returning equal pointers to different memory.",
+      "The allocation is scoped to `Context` and `Device` must belong to it.",
       "This function can only be used to create device or managed allocations. To create a host allocation use `olMemAllocAlignedHost`."
   ];
   let params = [
+    Param<"ol_context_handle_t", "Context", "handle of the context", PARAM_IN>,
     Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
     Param<"ol_alloc_type_t", "Type", "type of the allocation. Must be either `OL_ALLOC_TYPE_DEVICE` or `OL_ALLOC_TYPE_MANAGED`", PARAM_IN>,
     Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>,
@@ -100,15 +109,19 @@ def olMemAllocAligned : Function {
     Return<"OL_ERRC_INVALID_ENUMERATION", [
       "`Type == OL_ALLOC_TYPE_HOST`"
     ]>,
+    Return<"OL_ERRC_INVALID_DEVICE", [
+      "Device does not belong to `Context`"
+    ]>,
   ];
 }
 
 def olMemAllocAlignedHost : Function {
   let desc = "Creates a host memory allocation with the specified alignment.";
   let details = [
-      "All liboffload allocations share a single virtual address range. There is no risk of multiple devices returning equal pointers to different memory."
+      "The allocation is scoped to `Context` and `Device` must belong to it."
   ];
   let params = [
+    Param<"ol_context_handle_t", "Context", "handle of the context", PARAM_IN>,
     Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
     Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>,
     Param<"size_t", "Alignment",
@@ -126,15 +139,23 @@ def olMemAllocAlignedHost : Function {
     Return<"OL_ERRC_INVALID_ARGUMENT", [
       "`(Alignment & (Alignment - 1)) != 0`"
     ]>,
+    Return<"OL_ERRC_INVALID_DEVICE", [
+      "Device does not belong to `Context`"
+    ]>,
   ];
 }
 
 def olMemFree : Function {
   let desc = "Frees a memory allocation previously made by an olMemAlloc* function.";
   let params = [
+    Param<"ol_context_handle_t", "Context", "handle of the context the allocation was made in", PARAM_IN>,
     Param<"void*", "Address", "address of the allocation to free", PARAM_IN>,
   ];
-  let returns = [];
+  let returns = [
+    Return<"OL_ERRC_INVALID_CONTEXT", [
+      "The allocation was not made in `Context`"
+    ]>
+  ];
 }
 
 def ol_mem_info_t : Enum {
@@ -153,8 +174,10 @@ def olGetMemInfo : Function {
   let details = [
     "`olGetMemInfoSize` can be used to query the storage size required for the given query.",
     "The provided pointer can point to any location inside the allocation.",
+    "The allocation must have been made in `Context`.",
   ];
   let params = [
+    Param<"ol_context_handle_t", "Context", "handle of the context the allocation was made in", PARAM_IN>,
     Param<"const void *", "Ptr", "pointer to the allocated memory", PARAM_IN>,
     Param<"ol_mem_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>,
@@ -168,7 +191,7 @@ def olGetMemInfo : Function {
       "`PropSize == 0`",
       "If `PropSize` is less than the real number of bytes needed to return the info."
     ]>,
-    Return<"OL_ERRC_NOT_FOUND", ["memory was not allocated by liboffload"]>
+    Return<"OL_ERRC_NOT_FOUND", ["memory was not allocated in `Context`"]>
   ];
 }
 
@@ -176,14 +199,16 @@ def olGetMemInfoSize : Function {
   let desc = "Returns the storage size of the given queue query.";
   let details = [
     "The provided p...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list