[llvm] [OFFLOAD] Extend olMemRegister API to handle cases when a memory block may have been mapped outside of liboffload. (PR #172226)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 13 11:13:11 PST 2026
https://github.com/fineg74 updated https://github.com/llvm/llvm-project/pull/172226
>From 53811f9f0c4b6d8dd4ad19788cade99eb40b7bdd Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Fri, 12 Dec 2025 13:24:07 -0800
Subject: [PATCH 01/16] Add memory mapping notification API
---
offload/liboffload/API/Memory.td | 23 +++++++++++++++++++++++
offload/liboffload/src/OffloadImpl.cpp | 10 ++++++++++
2 files changed, 33 insertions(+)
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 79e8038330048..6a00df0c5a575 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -131,3 +131,26 @@ def olMemFill : Function {
Return<"OL_ERRC_INVALID_SIZE", ["`FillSize % PatternSize != 0`"]>
];
}
+
+def olMemDataMappedNotify : Function {
+ let desc = "Notifies device about mapping of memory block.";
+ let params = [
+ Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+ Param<"void *", "Ptr", "Host Pointer", PARAM_IN>,
+ Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>
+ ];
+ let returns = [
+ Return<"OL_ERRC_INVALID_SIZE", [
+ "`Size == 0`"
+ ]>
+ ];
+}
+
+def olMemDataUnMappedNotify : Function {
+ let desc = "Notifies device about unmapping of memory block.";
+ let params = [
+ Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+ Param<"void *", "Ptr", "Host Pointer", PARAM_IN>
+ ];
+ let returns = [];
+}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index eab9627217ca8..8b6eb2edd1923 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1214,5 +1214,15 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
Queue->AsyncInfo);
}
+Error olMemDataMappedNotify_impl(ol_device_handle_t Device, void *Ptr,
+ size_t Size) {
+ return Device->Device->notifyDataMapped(Ptr, Size);
+}
+
+Error olMemDataUnMappedNotify_impl(ol_device_handle_t Device, void *Ptr) {
+ return Device->Device->notifyDataUnmapped(Ptr);
+}
+
+
} // namespace offload
} // namespace llvm
>From c48f649951cb6dbe4a0693bfd64983e858ccb2d5 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 21 Jan 2026 18:35:22 -0800
Subject: [PATCH 02/16] Add test and add API description
---
offload/liboffload/API/Memory.td | 10 ++++
offload/unittests/OffloadAPI/CMakeLists.txt | 3 +-
.../OffloadAPI/memory/olMemMapNotify.cpp | 48 +++++++++++++++++++
3 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 4d06de716b25b..6ef80ec7dca4b 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -179,6 +179,12 @@ def olMemUnregister : Function {
def olMemDataMappedNotify : Function {
let desc = "Notifies device about mapping of memory block.";
+ let details = [
+ "Notifies device about mapping of host memory block after user created",
+ "a mapping of that memory block. The device would mark the buffer",
+ "as mapped so the buffer may be locked and used as source/destination",
+ "for memory transfers."
+ ];
let params = [
Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
Param<"void *", "Ptr", "Host Pointer", PARAM_IN>,
@@ -193,6 +199,10 @@ def olMemDataMappedNotify : Function {
def olMemDataUnMappedNotify : Function {
let desc = "Notifies device about unmapping of memory block.";
+ let details = [
+ "Notifies device about unmapping of a memory block.",
+ "The device would mark that buffer as unmapped and unlock it if it was locked."
+ ];
let params = [
Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
Param<"void *", "Ptr", "Host Pointer", PARAM_IN>
diff --git a/offload/unittests/OffloadAPI/CMakeLists.txt b/offload/unittests/OffloadAPI/CMakeLists.txt
index fce38c5fd75ae..8dcc53fcdea3e 100644
--- a/offload/unittests/OffloadAPI/CMakeLists.txt
+++ b/offload/unittests/OffloadAPI/CMakeLists.txt
@@ -30,7 +30,8 @@ add_offload_unittest("memory"
memory/olMemcpy.cpp
memory/olGetMemInfo.cpp
memory/olGetMemInfoSize.cpp
- memory/olMemRegister.cpp)
+ memory/olMemRegister.cpp
+ memory/olMemMapNotify.cpp)
add_offload_unittest("platform"
platform/olGetPlatformInfo.cpp
diff --git a/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp b/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
new file mode 100644
index 0000000000000..41b8231692e32
--- /dev/null
+++ b/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
@@ -0,0 +1,48 @@
+//===------- Offload API tests - olMemMapNotify -------------------------===//
+//
+// 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 "../common/Fixtures.hpp"
+#include <OffloadAPI.h>
+#include <gtest/gtest.h>
+
+using olMemMapNotifyTest = OffloadDeviceTest;
+OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemMapNotifyTest);
+
+TEST_P(olMemMapNotifyTest, SuccessMapNotify) {
+ int Arr[50];
+
+ ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
+ ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
+}
+
+TEST_P(olMemMapNotifyTest, SuccessMultipleMapNotify) {
+ int Arr[50];
+ ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
+ ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
+ ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
+ ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
+}
+
+TEST_P(olMemMapNotifyTest, InvalidSizeMapNotify) {
+ int Arr[50];
+ ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
+ olMemDataMappedNotify(Device, Arr, 0));
+}
+
+TEST_P(olMemMapNotifyTest, InvalidPtrMapNotify) {
+ int Arr[50];
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+ olMemDataMappedNotify(Device, nullptr, sizeof(Arr)));
+}
+
+TEST_P(olMemMapNotifyTest, InvalidPtrUnMapNotify) {
+ int Arr[50];
+ ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olMemDataUnMappedNotify(Device, nullptr));
+ ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
+}
>From 0a98cb02d94f73193110c825b36f485d3e30ef78 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 21 Jan 2026 19:09:11 -0800
Subject: [PATCH 03/16] Fix formatting
---
offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp b/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
index 41b8231692e32..29e30a78f0ca6 100644
--- a/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
@@ -30,8 +30,7 @@ TEST_P(olMemMapNotifyTest, SuccessMultipleMapNotify) {
TEST_P(olMemMapNotifyTest, InvalidSizeMapNotify) {
int Arr[50];
- ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
- olMemDataMappedNotify(Device, Arr, 0));
+ ASSERT_ERROR(OL_ERRC_INVALID_SIZE, olMemDataMappedNotify(Device, Arr, 0));
}
TEST_P(olMemMapNotifyTest, InvalidPtrMapNotify) {
@@ -43,6 +42,7 @@ TEST_P(olMemMapNotifyTest, InvalidPtrMapNotify) {
TEST_P(olMemMapNotifyTest, InvalidPtrUnMapNotify) {
int Arr[50];
ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
- ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olMemDataUnMappedNotify(Device, nullptr));
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+ olMemDataUnMappedNotify(Device, nullptr));
ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
}
>From 4bef30e332ba131637a763c405e9e50edaca507f Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 27 Jan 2026 13:01:36 -0800
Subject: [PATCH 04/16] Address PR comments
---
offload/liboffload/API/Memory.td | 48 ++-----
offload/liboffload/src/OffloadImpl.cpp | 24 ++--
.../common/include/PluginInterface.h | 25 +++-
.../common/src/PluginInterface.cpp | 136 +++++++-----------
offload/unittests/OffloadAPI/CMakeLists.txt | 3 +-
.../OffloadAPI/memory/olMemMapNotify.cpp | 48 -------
.../OffloadAPI/memory/olMemRegister.cpp | 74 ++++++++--
7 files changed, 159 insertions(+), 199 deletions(-)
delete mode 100644 offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 6ef80ec7dca4b..55fe9ab1b5d1b 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -24,6 +24,16 @@ def ol_memory_register_flags_t : Typedef {
let value = "uint32_t";
}
+def ol_memory_register_flag_t : Enum {
+ let desc = "Memory registering/locking flags";
+ let is_bit_field = 1;
+ let etors =[
+ Etor<"REGISTER_MAPPED_MEMORY", "Memory may already been locked outside of the API">,
+ Etor<"LOCK_MEMORY", "Lock the memory">,
+ Etor<"IGNORE_LOCK_FAILURE", "Ignore memory locking errors">,
+ ];
+}
+
def olMemAlloc : Function {
let desc = "Creates a memory allocation on the specified device.";
let details = [
@@ -153,7 +163,7 @@ def olMemRegister : Function {
Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
Param<"void *", "Ptr", "host pointer", PARAM_IN>,
Param<"size_t", "Size", "size of the memory in bytes", PARAM_IN>,
- Param<"ol_memory_register_flags_t", "Flags", "flags. Reserved for future use", PARAM_IN>,
+ Param<"ol_memory_register_flags_t", "Flags", "flags controlling various aspects of registration", PARAM_IN>,
Param<"void**", "PinnedPtr", "pointer to the pinned memory", PARAM_OUT>
];
let returns = [
@@ -172,40 +182,8 @@ def olMemUnregister : Function {
];
let params = [
Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
- Param<"void *", "Ptr", "host pointer", PARAM_IN>
+ Param<"void *", "Ptr", "host pointer", PARAM_IN>,
+ Param<"ol_memory_register_flags_t", "Flags", "flags controlling various aspects of registration", PARAM_IN>,
];
let returns = [];
}
-
-def olMemDataMappedNotify : Function {
- let desc = "Notifies device about mapping of memory block.";
- let details = [
- "Notifies device about mapping of host memory block after user created",
- "a mapping of that memory block. The device would mark the buffer",
- "as mapped so the buffer may be locked and used as source/destination",
- "for memory transfers."
- ];
- let params = [
- Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
- Param<"void *", "Ptr", "Host Pointer", PARAM_IN>,
- Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>
- ];
- let returns = [
- Return<"OL_ERRC_INVALID_SIZE", [
- "`Size == 0`"
- ]>
- ];
-}
-
-def olMemDataUnMappedNotify : Function {
- let desc = "Notifies device about unmapping of memory block.";
- let details = [
- "Notifies device about unmapping of a memory block.",
- "The device would mark that buffer as unmapped and unlock it if it was locked."
- ];
- let params = [
- Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
- Param<"void *", "Ptr", "Host Pointer", PARAM_IN>
- ];
- let returns = [];
-}
\ No newline at end of file
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 1bb6a15fb956d..6689ee0281acd 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1235,8 +1235,11 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
}
Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
- ol_memory_register_flags_t flags, void **LockedPtr) {
- Expected<void *> LockedPtrOrErr = Device->Device->dataLock(Ptr, Size);
+ ol_memory_register_flags_t Flags, void **LockedPtr) {
+ Expected<void *> LockedPtrOrErr = Device->Device->dataLock(Ptr, Size,
+ Flags & OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY,
+ Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
+ Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
if (!LockedPtrOrErr)
return LockedPtrOrErr.takeError();
@@ -1245,8 +1248,11 @@ Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
return Error::success();
}
-Error olMemUnregister_impl(ol_device_handle_t Device, void *Ptr) {
- return Device->Device->dataUnlock(Ptr);
+Error olMemUnregister_impl(ol_device_handle_t Device, void *Ptr,
+ ol_memory_register_flags_t Flags) {
+ return Device->Device->dataUnlock(Ptr,
+ Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
+ Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
}
Error olQueryQueue_impl(ol_queue_handle_t Queue, bool *IsQueueWorkCompleted) {
@@ -1258,13 +1264,9 @@ Error olQueryQueue_impl(ol_queue_handle_t Queue, bool *IsQueueWorkCompleted) {
return Error::success();
}
-Error olMemDataMappedNotify_impl(ol_device_handle_t Device, void *Ptr,
- size_t Size) {
- return Device->Device->notifyDataMapped(Ptr, Size);
-}
-
-Error olMemDataUnMappedNotify_impl(ol_device_handle_t Device, void *Ptr) {
- return Device->Device->notifyDataUnmapped(Ptr);
+Error olGetHostDevice_impl(ol_device_handle_t *Device) {
+ *Device = OffloadContext::get().HostDevice;
+return Error::success();
}
} // namespace offload
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 19db44cf04655..8765bf9734764 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -738,12 +738,17 @@ class PinnedAllocationMapTy {
/// with an already existing one. A partial overlapping with extension is not
/// allowed. The function returns the device accessible pointer of the pinned
/// buffer. The buffer must be unlocked using the unlockHostBuffer function.
- Expected<void *> lockHostBuffer(void *HstPtr, size_t Size);
+ Expected<void *> lockHostBuffer(void *HstPtr, size_t Size,
+ bool RegisterMappedBuffer = false,
+ bool LockMappedMemory = true,
+ bool IgnoreLockErrors = false);
/// Unlock the host buffer at \p HstPtr or unregister a user if other users
/// are still using the pinned allocation. If this was the last user, the
/// pinned allocation is removed from the map and the memory is unlocked.
- Error unlockHostBuffer(void *HstPtr);
+ Error unlockHostBuffer(void *HstPtr,
+ bool LockMappedMemory = true,
+ bool IgnoreLockErrors = false);
/// Lock or register a host buffer that was recently mapped by libomptarget.
/// This behavior is applied if LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS is
@@ -883,13 +888,21 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// Pin host memory to optimize transfers and return the device accessible
/// pointer that devices should use for memory transfers involving the host
/// pinned allocation.
- Expected<void *> dataLock(void *HstPtr, int64_t Size) {
- return PinnedAllocs.lockHostBuffer(HstPtr, Size);
+ Expected<void *> dataLock(void *HstPtr, int64_t Size,
+ bool RegisterMappedBuffer = false,
+ bool LockMappedMemory = true,
+ bool IgnoreLockErrors = false) {
+ return PinnedAllocs.lockHostBuffer(HstPtr, Size, RegisterMappedBuffer,
+ LockMappedMemory, IgnoreLockErrors);
}
/// Unpin a host memory buffer that was previously pinned.
- Error dataUnlock(void *HstPtr) {
- return PinnedAllocs.unlockHostBuffer(HstPtr);
+ Error dataUnlock(void *HstPtr,
+ bool LockMappedMemory = true,
+ bool IgnoreLockErrors = false) {
+ return PinnedAllocs.unlockHostBuffer(HstPtr,
+ LockMappedMemory,
+ IgnoreLockErrors);
}
/// Lock the host buffer \p HstPtr with \p Size bytes with the vendor-specific
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 807df0ffd7874..731e552eb80bd 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1025,7 +1025,10 @@ Error PinnedAllocationMapTy::unregisterHostBuffer(void *HstPtr) {
}
Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
- size_t Size) {
+ size_t Size,
+ bool RegisterMappedBuffer,
+ bool LockMappedMemory,
+ bool IgnoreLockErrors) {
assert(HstPtr && "Invalid pointer");
assert(Size && "Invalid size");
@@ -1043,11 +1046,40 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
utils::getPtrDiff(HstPtr, Entry->HstPtr));
}
+ if (RegisterMappedBuffer) {
+ size_t BaseSize;
+ void *BaseHstPtr, *BaseDevAccessiblePtr;
+
+ // Check if it was externally pinned by a vendor-specific API.
+ auto IsPinnedOrErr = Device.isPinnedPtrImpl(HstPtr, BaseHstPtr,
+ BaseDevAccessiblePtr, BaseSize);
+ if (!IsPinnedOrErr)
+ return std::move(IsPinnedOrErr.takeError());
+
+ // If pinned, just insert the entry representing the whole pinned buffer.
+ if (*IsPinnedOrErr){
+ if (auto Err = insertEntry(BaseHstPtr, BaseDevAccessiblePtr, BaseSize,
+ /*Externallylocked=*/true))
+ return std::move(Err);
+ return BaseDevAccessiblePtr;
+ }
+ }
+
+ // Not externally pinned. Do nothing if locking of mapped buffers is disabled.
+ if (!LockMappedMemory)
+ return nullptr;
+
// No intersecting registered allocation found in the map. First, lock the
// host buffer and retrieve the device accessible pointer.
auto DevAccessiblePtrOrErr = Device.dataLockImpl(HstPtr, Size);
- if (!DevAccessiblePtrOrErr)
- return DevAccessiblePtrOrErr.takeError();
+ if (!DevAccessiblePtrOrErr) {
+ // Errors may be tolerated.
+ if (!IgnoreLockErrors)
+ return std::move(DevAccessiblePtrOrErr.takeError());
+
+ consumeError(DevAccessiblePtrOrErr.takeError());
+ return nullptr;
+ }
// Now insert the new entry into the map.
if (auto Err = insertEntry(HstPtr, *DevAccessiblePtrOrErr, Size))
@@ -1057,12 +1089,25 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
return *DevAccessiblePtrOrErr;
}
-Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr) {
+Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr,
+ bool LockMappedMemory,
+ bool IgnoreLockErrors) {
assert(HstPtr && "Invalid pointer");
std::lock_guard<std::shared_mutex> Lock(Mutex);
const EntryTy *Entry = findIntersecting(HstPtr);
+
+ // No entry but automatic locking of mapped buffers is disabled, so
+ // nothing to do.
+ if (!Entry && !LockMappedMemory)
+ return Plugin::success();
+
+ // No entry, automatic locking is enabled, but the locking may have failed, so
+ // do nothing.
+ if (!Entry && IgnoreLockErrors)
+ return Plugin::success();
+
if (!Entry)
return Plugin::error(ErrorCode::INVALID_ARGUMENT,
"cannot find locked buffer");
@@ -1089,88 +1134,15 @@ Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr) {
}
Error PinnedAllocationMapTy::lockMappedHostBuffer(void *HstPtr, size_t Size) {
- assert(HstPtr && "Invalid pointer");
- assert(Size && "Invalid size");
-
- std::lock_guard<std::shared_mutex> Lock(Mutex);
+ auto Result = lockHostBuffer(HstPtr, Size, true, LockMappedBuffers, IgnoreLockMappedFailures);
+ if (!Result)
+ return Result.takeError();
- // If previously registered, just register a new user on the entry.
- const EntryTy *Entry = findIntersecting(HstPtr);
- if (Entry)
- return registerEntryUse(*Entry, HstPtr, Size);
-
- size_t BaseSize;
- void *BaseHstPtr, *BaseDevAccessiblePtr;
-
- // Check if it was externally pinned by a vendor-specific API.
- auto IsPinnedOrErr = Device.isPinnedPtrImpl(HstPtr, BaseHstPtr,
- BaseDevAccessiblePtr, BaseSize);
- if (!IsPinnedOrErr)
- return IsPinnedOrErr.takeError();
-
- // If pinned, just insert the entry representing the whole pinned buffer.
- if (*IsPinnedOrErr)
- return insertEntry(BaseHstPtr, BaseDevAccessiblePtr, BaseSize,
- /*Externallylocked=*/true);
-
- // Not externally pinned. Do nothing if locking of mapped buffers is disabled.
- if (!LockMappedBuffers)
- return Plugin::success();
-
- // Otherwise, lock the buffer and insert the new entry.
- auto DevAccessiblePtrOrErr = Device.dataLockImpl(HstPtr, Size);
- if (!DevAccessiblePtrOrErr) {
- // Errors may be tolerated.
- if (!IgnoreLockMappedFailures)
- return DevAccessiblePtrOrErr.takeError();
-
- consumeError(DevAccessiblePtrOrErr.takeError());
- return Plugin::success();
- }
-
- return insertEntry(HstPtr, *DevAccessiblePtrOrErr, Size);
+ return Plugin::success();
}
Error PinnedAllocationMapTy::unlockUnmappedHostBuffer(void *HstPtr) {
- assert(HstPtr && "Invalid pointer");
-
- std::lock_guard<std::shared_mutex> Lock(Mutex);
-
- // Check whether there is any intersecting entry.
- const EntryTy *Entry = findIntersecting(HstPtr);
-
- // No entry but automatic locking of mapped buffers is disabled, so
- // nothing to do.
- if (!Entry && !LockMappedBuffers)
- return Plugin::success();
-
- // No entry, automatic locking is enabled, but the locking may have failed, so
- // do nothing.
- if (!Entry && IgnoreLockMappedFailures)
- return Plugin::success();
-
- // No entry, but the automatic locking is enabled, so this is an error.
- if (!Entry)
- return Plugin::error(ErrorCode::INVALID_ARGUMENT,
- "locked buffer not found");
-
- // There is entry, so unregister a user and check whether it was the last one.
- auto LastUseOrErr = unregisterEntryUse(*Entry);
- if (!LastUseOrErr)
- return LastUseOrErr.takeError();
-
- // If it is not the last one, there is nothing to do.
- if (!(*LastUseOrErr))
- return Plugin::success();
-
- // Otherwise, if it was the last and the buffer was locked by the plugin,
- // unlock it.
- if (!Entry->ExternallyLocked)
- if (auto Err = Device.dataUnlockImpl(Entry->HstPtr))
- return Err;
-
- // Finally erase the entry from the map.
- return eraseEntry(*Entry);
+ return unlockHostBuffer(HstPtr, LockMappedBuffers, IgnoreLockMappedFailures);
}
Error GenericDeviceTy::synchronize(__tgt_async_info *AsyncInfo,
diff --git a/offload/unittests/OffloadAPI/CMakeLists.txt b/offload/unittests/OffloadAPI/CMakeLists.txt
index 8dcc53fcdea3e..fce38c5fd75ae 100644
--- a/offload/unittests/OffloadAPI/CMakeLists.txt
+++ b/offload/unittests/OffloadAPI/CMakeLists.txt
@@ -30,8 +30,7 @@ add_offload_unittest("memory"
memory/olMemcpy.cpp
memory/olGetMemInfo.cpp
memory/olGetMemInfoSize.cpp
- memory/olMemRegister.cpp
- memory/olMemMapNotify.cpp)
+ memory/olMemRegister.cpp)
add_offload_unittest("platform"
platform/olGetPlatformInfo.cpp
diff --git a/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp b/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
deleted file mode 100644
index 29e30a78f0ca6..0000000000000
--- a/offload/unittests/OffloadAPI/memory/olMemMapNotify.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===------- Offload API tests - olMemMapNotify -------------------------===//
-//
-// 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 "../common/Fixtures.hpp"
-#include <OffloadAPI.h>
-#include <gtest/gtest.h>
-
-using olMemMapNotifyTest = OffloadDeviceTest;
-OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemMapNotifyTest);
-
-TEST_P(olMemMapNotifyTest, SuccessMapNotify) {
- int Arr[50];
-
- ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
- ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
-}
-
-TEST_P(olMemMapNotifyTest, SuccessMultipleMapNotify) {
- int Arr[50];
- ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
- ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
- ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
- ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
-}
-
-TEST_P(olMemMapNotifyTest, InvalidSizeMapNotify) {
- int Arr[50];
- ASSERT_ERROR(OL_ERRC_INVALID_SIZE, olMemDataMappedNotify(Device, Arr, 0));
-}
-
-TEST_P(olMemMapNotifyTest, InvalidPtrMapNotify) {
- int Arr[50];
- ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
- olMemDataMappedNotify(Device, nullptr, sizeof(Arr)));
-}
-
-TEST_P(olMemMapNotifyTest, InvalidPtrUnMapNotify) {
- int Arr[50];
- ASSERT_SUCCESS(olMemDataMappedNotify(Device, Arr, sizeof(Arr)));
- ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
- olMemDataUnMappedNotify(Device, nullptr));
- ASSERT_SUCCESS(olMemDataUnMappedNotify(Device, Arr));
-}
diff --git a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
index e98dafc54598d..c9467ee41f322 100644
--- a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
@@ -15,29 +15,29 @@ OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemRegisterTest);
TEST_P(olMemRegisterTest, SuccessRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = {};
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
}
TEST_P(olMemRegisterTest, SuccessMultipleRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = {};
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
void *PinnedPtr1 = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr1));
ASSERT_NE(PinnedPtr1, nullptr);
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr1));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr1, Flags));
}
TEST_P(olMemRegisterTest, InvalidSizeRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = {};
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
olMemRegister(Device, Arr, 0, Flags, &PinnedPtr));
@@ -45,7 +45,7 @@ TEST_P(olMemRegisterTest, InvalidSizeRegister) {
TEST_P(olMemRegisterTest, InvalidPtrRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = {};
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
olMemRegister(Device, nullptr, sizeof(Arr), Flags, &PinnedPtr));
@@ -53,32 +53,76 @@ TEST_P(olMemRegisterTest, InvalidPtrRegister) {
TEST_P(olMemRegisterTest, InvalidPtrUnRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = {};
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olMemUnregister(Device, nullptr));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr));
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olMemUnregister(Device, nullptr, Flags));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
}
TEST_P(olMemRegisterTest, UnregisteredPtrUnRegister) {
int Arr[50];
int Arr1[50];
- ol_memory_register_flags_t Flags = {};
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT, olMemUnregister(Device, Arr1));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr));
+ ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT, olMemUnregister(Device, Arr1, Flags));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
}
TEST_P(olMemRegisterTest, PartialOverlapPtrRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = {};
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT,
olMemRegister(Device, Arr + 2, sizeof(Arr), Flags, &PinnedPtr));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
}
+
+TEST_P(olMemRegisterTest, SuccessMapNotify) {
+ int Arr[50];
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ void *PinnedPtr = nullptr;
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
+}
+
+TEST_P(olMemRegisterTest, SuccessMultipleMapNotify) {
+ int Arr[50];
+ void *PinnedPtr = nullptr;
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
+ ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
+}
+
+TEST_P(olMemRegisterTest, InvalidSizeMapNotify) {
+ int Arr[50];
+ void *PinnedPtr = nullptr;
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ASSERT_ERROR(OL_ERRC_INVALID_SIZE, olMemRegister(Device, Arr, 0, Flags, &PinnedPtr));
+}
+
+TEST_P(olMemRegisterTest, InvalidPtrMapNotify) {
+ int Arr[50];
+ void *PinnedPtr = nullptr;
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+ olMemRegister(Device, nullptr, sizeof(Arr), Flags, &PinnedPtr));
+}
+
+TEST_P(olMemRegisterTest, InvalidPtrUnMapNotify) {
+ int Arr[50];
+ void *PinnedPtr = nullptr;
+ ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+ olMemUnregister(Device, nullptr, Flags));
+ ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
+}
+
>From 66ee87086a25dfb90970df6cacc1a2caca9d40a3 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 27 Jan 2026 14:48:29 -0800
Subject: [PATCH 05/16] Fix formatting issues
---
offload/liboffload/src/OffloadImpl.cpp | 19 +++++--------
.../common/include/PluginInterface.h | 11 +++-----
.../common/src/PluginInterface.cpp | 17 ++++++-----
.../OffloadAPI/memory/olMemRegister.cpp | 28 +++++++++++--------
4 files changed, 36 insertions(+), 39 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 6689ee0281acd..962a0493726da 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1236,10 +1236,10 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
ol_memory_register_flags_t Flags, void **LockedPtr) {
- Expected<void *> LockedPtrOrErr = Device->Device->dataLock(Ptr, Size,
- Flags & OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY,
- Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
- Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
+ Expected<void *> LockedPtrOrErr = Device->Device->dataLock(
+ Ptr, Size, Flags & OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY,
+ Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
+ Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
if (!LockedPtrOrErr)
return LockedPtrOrErr.takeError();
@@ -1250,9 +1250,9 @@ Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
Error olMemUnregister_impl(ol_device_handle_t Device, void *Ptr,
ol_memory_register_flags_t Flags) {
- return Device->Device->dataUnlock(Ptr,
- Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
- Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
+ return Device->Device->dataUnlock(
+ Ptr, Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
+ Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
}
Error olQueryQueue_impl(ol_queue_handle_t Queue, bool *IsQueueWorkCompleted) {
@@ -1264,10 +1264,5 @@ Error olQueryQueue_impl(ol_queue_handle_t Queue, bool *IsQueueWorkCompleted) {
return Error::success();
}
-Error olGetHostDevice_impl(ol_device_handle_t *Device) {
- *Device = OffloadContext::get().HostDevice;
-return Error::success();
-}
-
} // namespace offload
} // namespace llvm
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 8765bf9734764..a06f36f194288 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -746,8 +746,7 @@ class PinnedAllocationMapTy {
/// Unlock the host buffer at \p HstPtr or unregister a user if other users
/// are still using the pinned allocation. If this was the last user, the
/// pinned allocation is removed from the map and the memory is unlocked.
- Error unlockHostBuffer(void *HstPtr,
- bool LockMappedMemory = true,
+ Error unlockHostBuffer(void *HstPtr, bool LockMappedMemory = true,
bool IgnoreLockErrors = false);
/// Lock or register a host buffer that was recently mapped by libomptarget.
@@ -892,16 +891,14 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
bool RegisterMappedBuffer = false,
bool LockMappedMemory = true,
bool IgnoreLockErrors = false) {
- return PinnedAllocs.lockHostBuffer(HstPtr, Size, RegisterMappedBuffer,
+ return PinnedAllocs.lockHostBuffer(HstPtr, Size, RegisterMappedBuffer,
LockMappedMemory, IgnoreLockErrors);
}
/// Unpin a host memory buffer that was previously pinned.
- Error dataUnlock(void *HstPtr,
- bool LockMappedMemory = true,
+ Error dataUnlock(void *HstPtr, bool LockMappedMemory = true,
bool IgnoreLockErrors = false) {
- return PinnedAllocs.unlockHostBuffer(HstPtr,
- LockMappedMemory,
+ return PinnedAllocs.unlockHostBuffer(HstPtr, LockMappedMemory,
IgnoreLockErrors);
}
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 731e552eb80bd..10b1e41981113 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1024,11 +1024,9 @@ Error PinnedAllocationMapTy::unregisterHostBuffer(void *HstPtr) {
return eraseEntry(*Entry);
}
-Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
- size_t Size,
- bool RegisterMappedBuffer,
- bool LockMappedMemory,
- bool IgnoreLockErrors) {
+Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
+ void *HstPtr, size_t Size, bool RegisterMappedBuffer, bool LockMappedMemory,
+ bool IgnoreLockErrors) {
assert(HstPtr && "Invalid pointer");
assert(Size && "Invalid size");
@@ -1052,14 +1050,14 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
// Check if it was externally pinned by a vendor-specific API.
auto IsPinnedOrErr = Device.isPinnedPtrImpl(HstPtr, BaseHstPtr,
- BaseDevAccessiblePtr, BaseSize);
+ BaseDevAccessiblePtr, BaseSize);
if (!IsPinnedOrErr)
return std::move(IsPinnedOrErr.takeError());
// If pinned, just insert the entry representing the whole pinned buffer.
- if (*IsPinnedOrErr){
+ if (*IsPinnedOrErr) {
if (auto Err = insertEntry(BaseHstPtr, BaseDevAccessiblePtr, BaseSize,
- /*Externallylocked=*/true))
+ /*Externallylocked=*/true))
return std::move(Err);
return BaseDevAccessiblePtr;
}
@@ -1134,7 +1132,8 @@ Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr,
}
Error PinnedAllocationMapTy::lockMappedHostBuffer(void *HstPtr, size_t Size) {
- auto Result = lockHostBuffer(HstPtr, Size, true, LockMappedBuffers, IgnoreLockMappedFailures);
+ auto Result = lockHostBuffer(HstPtr, Size, true, LockMappedBuffers,
+ IgnoreLockMappedFailures);
if (!Result)
return Result.takeError();
diff --git a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
index c9467ee41f322..6015a83069f33 100644
--- a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
@@ -83,43 +83,49 @@ TEST_P(olMemRegisterTest, PartialOverlapPtrRegister) {
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
}
-TEST_P(olMemRegisterTest, SuccessMapNotify) {
+TEST_P(olMemRegisterTest, SuccessMappedRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ol_memory_register_flags_t Flags =
+ OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
}
-TEST_P(olMemRegisterTest, SuccessMultipleMapNotify) {
+TEST_P(olMemRegisterTest, SuccessMultipleMappedRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ol_memory_register_flags_t Flags =
+ OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
}
-TEST_P(olMemRegisterTest, InvalidSizeMapNotify) {
+TEST_P(olMemRegisterTest, InvalidSizeMappedRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
- ASSERT_ERROR(OL_ERRC_INVALID_SIZE, olMemRegister(Device, Arr, 0, Flags, &PinnedPtr));
+ ol_memory_register_flags_t Flags =
+ OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
+ olMemRegister(Device, Arr, 0, Flags, &PinnedPtr));
}
-TEST_P(olMemRegisterTest, InvalidPtrMapNotify) {
+TEST_P(olMemRegisterTest, InvalidPtrMappedRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ol_memory_register_flags_t Flags =
+ OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
olMemRegister(Device, nullptr, sizeof(Arr), Flags, &PinnedPtr));
}
-TEST_P(olMemRegisterTest, InvalidPtrUnMapNotify) {
+TEST_P(olMemRegisterTest, InvalidPtrMappedUnRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ ol_memory_register_flags_t Flags =
+ OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
olMemUnregister(Device, nullptr, Flags));
>From f34846e5ded6ce4ee8b37b4bacabc4a810c2656a Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 27 Jan 2026 19:25:58 -0800
Subject: [PATCH 06/16] Fix formatting
---
offload/liboffload/src/OffloadImpl.cpp | 2 +-
offload/unittests/OffloadAPI/memory/olMemRegister.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 962a0493726da..8700de7e815bd 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1235,7 +1235,7 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
}
Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
- ol_memory_register_flags_t Flags, void **LockedPtr) {
+ ol_memory_register_flags_t Flags, void **LockedPtr) {
Expected<void *> LockedPtrOrErr = Device->Device->dataLock(
Ptr, Size, Flags & OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY,
Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
diff --git a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
index 6015a83069f33..f3f62a2225fd2 100644
--- a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
@@ -57,7 +57,8 @@ TEST_P(olMemRegisterTest, InvalidPtrUnRegister) {
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olMemUnregister(Device, nullptr, Flags));
+ ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
+ olMemUnregister(Device, nullptr, Flags));
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
}
@@ -131,4 +132,3 @@ TEST_P(olMemRegisterTest, InvalidPtrMappedUnRegister) {
olMemUnregister(Device, nullptr, Flags));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
}
-
>From a595f38c095118bd2b887003a47e58fb9ebfe7da Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Mon, 2 Feb 2026 11:09:00 -0800
Subject: [PATCH 07/16] Address PR comments
---
offload/liboffload/API/Memory.td | 1 -
offload/liboffload/src/OffloadImpl.cpp | 6 ++--
.../common/include/PluginInterface.h | 17 ++++-------
.../common/src/PluginInterface.cpp | 29 +++++--------------
4 files changed, 15 insertions(+), 38 deletions(-)
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 55fe9ab1b5d1b..2c93ae474ac91 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -30,7 +30,6 @@ def ol_memory_register_flag_t : Enum {
let etors =[
Etor<"REGISTER_MAPPED_MEMORY", "Memory may already been locked outside of the API">,
Etor<"LOCK_MEMORY", "Lock the memory">,
- Etor<"IGNORE_LOCK_FAILURE", "Ignore memory locking errors">,
];
}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 8700de7e815bd..6f0f2a4ca46a7 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1238,8 +1238,7 @@ Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
ol_memory_register_flags_t Flags, void **LockedPtr) {
Expected<void *> LockedPtrOrErr = Device->Device->dataLock(
Ptr, Size, Flags & OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY,
- Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
- Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
+ Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY);
if (!LockedPtrOrErr)
return LockedPtrOrErr.takeError();
@@ -1251,8 +1250,7 @@ Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
Error olMemUnregister_impl(ol_device_handle_t Device, void *Ptr,
ol_memory_register_flags_t Flags) {
return Device->Device->dataUnlock(
- Ptr, Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY,
- Flags & OL_MEMORY_REGISTER_FLAG_IGNORE_LOCK_FAILURE);
+ Ptr, Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY);
}
Error olQueryQueue_impl(ol_queue_handle_t Queue, bool *IsQueueWorkCompleted) {
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index a06f36f194288..1356d9a2e3db6 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -740,14 +740,12 @@ class PinnedAllocationMapTy {
/// buffer. The buffer must be unlocked using the unlockHostBuffer function.
Expected<void *> lockHostBuffer(void *HstPtr, size_t Size,
bool RegisterMappedBuffer = false,
- bool LockMappedMemory = true,
- bool IgnoreLockErrors = false);
+ bool LockMemory = true);
/// Unlock the host buffer at \p HstPtr or unregister a user if other users
/// are still using the pinned allocation. If this was the last user, the
/// pinned allocation is removed from the map and the memory is unlocked.
- Error unlockHostBuffer(void *HstPtr, bool LockMappedMemory = true,
- bool IgnoreLockErrors = false);
+ Error unlockHostBuffer(void *HstPtr, bool LockMemory = true);
/// Lock or register a host buffer that was recently mapped by libomptarget.
/// This behavior is applied if LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS is
@@ -889,17 +887,14 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// pinned allocation.
Expected<void *> dataLock(void *HstPtr, int64_t Size,
bool RegisterMappedBuffer = false,
- bool LockMappedMemory = true,
- bool IgnoreLockErrors = false) {
+ bool LockMemory = true) {
return PinnedAllocs.lockHostBuffer(HstPtr, Size, RegisterMappedBuffer,
- LockMappedMemory, IgnoreLockErrors);
+ LockMemory);
}
/// Unpin a host memory buffer that was previously pinned.
- Error dataUnlock(void *HstPtr, bool LockMappedMemory = true,
- bool IgnoreLockErrors = false) {
- return PinnedAllocs.unlockHostBuffer(HstPtr, LockMappedMemory,
- IgnoreLockErrors);
+ Error dataUnlock(void *HstPtr, bool LockMemory = true) {
+ return PinnedAllocs.unlockHostBuffer(HstPtr, LockMemory);
}
/// Lock the host buffer \p HstPtr with \p Size bytes with the vendor-specific
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 10b1e41981113..35cabd9f25746 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1025,8 +1025,7 @@ Error PinnedAllocationMapTy::unregisterHostBuffer(void *HstPtr) {
}
Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
- void *HstPtr, size_t Size, bool RegisterMappedBuffer, bool LockMappedMemory,
- bool IgnoreLockErrors) {
+ void *HstPtr, size_t Size, bool RegisterMappedBuffer, bool LockMemory) {
assert(HstPtr && "Invalid pointer");
assert(Size && "Invalid size");
@@ -1064,21 +1063,15 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
}
// Not externally pinned. Do nothing if locking of mapped buffers is disabled.
- if (!LockMappedMemory)
+ if (!LockMemory)
return nullptr;
// No intersecting registered allocation found in the map. First, lock the
// host buffer and retrieve the device accessible pointer.
auto DevAccessiblePtrOrErr = Device.dataLockImpl(HstPtr, Size);
- if (!DevAccessiblePtrOrErr) {
- // Errors may be tolerated.
- if (!IgnoreLockErrors)
+ if (!DevAccessiblePtrOrErr)
return std::move(DevAccessiblePtrOrErr.takeError());
- consumeError(DevAccessiblePtrOrErr.takeError());
- return nullptr;
- }
-
// Now insert the new entry into the map.
if (auto Err = insertEntry(HstPtr, *DevAccessiblePtrOrErr, Size))
return std::move(Err);
@@ -1087,9 +1080,7 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
return *DevAccessiblePtrOrErr;
}
-Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr,
- bool LockMappedMemory,
- bool IgnoreLockErrors) {
+Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr, bool LockMemory) {
assert(HstPtr && "Invalid pointer");
std::lock_guard<std::shared_mutex> Lock(Mutex);
@@ -1098,12 +1089,7 @@ Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr,
// No entry but automatic locking of mapped buffers is disabled, so
// nothing to do.
- if (!Entry && !LockMappedMemory)
- return Plugin::success();
-
- // No entry, automatic locking is enabled, but the locking may have failed, so
- // do nothing.
- if (!Entry && IgnoreLockErrors)
+ if (!Entry && !LockMemory)
return Plugin::success();
if (!Entry)
@@ -1132,8 +1118,7 @@ Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr,
}
Error PinnedAllocationMapTy::lockMappedHostBuffer(void *HstPtr, size_t Size) {
- auto Result = lockHostBuffer(HstPtr, Size, true, LockMappedBuffers,
- IgnoreLockMappedFailures);
+ auto Result = lockHostBuffer(HstPtr, Size, true, LockMappedBuffers);
if (!Result)
return Result.takeError();
@@ -1141,7 +1126,7 @@ Error PinnedAllocationMapTy::lockMappedHostBuffer(void *HstPtr, size_t Size) {
}
Error PinnedAllocationMapTy::unlockUnmappedHostBuffer(void *HstPtr) {
- return unlockHostBuffer(HstPtr, LockMappedBuffers, IgnoreLockMappedFailures);
+ return unlockHostBuffer(HstPtr, LockMappedBuffers);
}
Error GenericDeviceTy::synchronize(__tgt_async_info *AsyncInfo,
>From 516c76e597f17ae4ee3f341cec7550bd62ae5d42 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Mon, 2 Feb 2026 11:33:19 -0800
Subject: [PATCH 08/16] Address PR comments
---
offload/liboffload/API/Memory.td | 1 -
offload/liboffload/src/OffloadImpl.cpp | 3 +-
.../common/include/PluginInterface.h | 5 +-
.../common/src/PluginInterface.cpp | 115 ++++++++++++++----
.../OffloadAPI/memory/olMemRegister.cpp | 10 +-
5 files changed, 100 insertions(+), 34 deletions(-)
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 2c93ae474ac91..010b375116b0c 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -28,7 +28,6 @@ def ol_memory_register_flag_t : Enum {
let desc = "Memory registering/locking flags";
let is_bit_field = 1;
let etors =[
- Etor<"REGISTER_MAPPED_MEMORY", "Memory may already been locked outside of the API">,
Etor<"LOCK_MEMORY", "Lock the memory">,
];
}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 6f0f2a4ca46a7..bd07da0d06007 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1237,8 +1237,7 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
ol_memory_register_flags_t Flags, void **LockedPtr) {
Expected<void *> LockedPtrOrErr = Device->Device->dataLock(
- Ptr, Size, Flags & OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY,
- Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY);
+ Ptr, Size, Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY);
if (!LockedPtrOrErr)
return LockedPtrOrErr.takeError();
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 1356d9a2e3db6..4d2f034197540 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -739,7 +739,6 @@ class PinnedAllocationMapTy {
/// allowed. The function returns the device accessible pointer of the pinned
/// buffer. The buffer must be unlocked using the unlockHostBuffer function.
Expected<void *> lockHostBuffer(void *HstPtr, size_t Size,
- bool RegisterMappedBuffer = false,
bool LockMemory = true);
/// Unlock the host buffer at \p HstPtr or unregister a user if other users
@@ -886,10 +885,8 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// pointer that devices should use for memory transfers involving the host
/// pinned allocation.
Expected<void *> dataLock(void *HstPtr, int64_t Size,
- bool RegisterMappedBuffer = false,
bool LockMemory = true) {
- return PinnedAllocs.lockHostBuffer(HstPtr, Size, RegisterMappedBuffer,
- LockMemory);
+ return PinnedAllocs.lockHostBuffer(HstPtr, Size, LockMemory);
}
/// Unpin a host memory buffer that was previously pinned.
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 35cabd9f25746..897e6f286e626 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1025,7 +1025,7 @@ Error PinnedAllocationMapTy::unregisterHostBuffer(void *HstPtr) {
}
Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
- void *HstPtr, size_t Size, bool RegisterMappedBuffer, bool LockMemory) {
+ void *HstPtr, size_t Size, bool LockMemory) {
assert(HstPtr && "Invalid pointer");
assert(Size && "Invalid size");
@@ -1043,23 +1043,21 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
utils::getPtrDiff(HstPtr, Entry->HstPtr));
}
- if (RegisterMappedBuffer) {
- size_t BaseSize;
- void *BaseHstPtr, *BaseDevAccessiblePtr;
+ size_t BaseSize;
+ void *BaseHstPtr, *BaseDevAccessiblePtr;
- // Check if it was externally pinned by a vendor-specific API.
- auto IsPinnedOrErr = Device.isPinnedPtrImpl(HstPtr, BaseHstPtr,
- BaseDevAccessiblePtr, BaseSize);
- if (!IsPinnedOrErr)
- return std::move(IsPinnedOrErr.takeError());
+ // Check if it was externally pinned by a vendor-specific API.
+ auto IsPinnedOrErr = Device.isPinnedPtrImpl(HstPtr, BaseHstPtr,
+ BaseDevAccessiblePtr, BaseSize);
+ if (!IsPinnedOrErr)
+ return std::move(IsPinnedOrErr.takeError());
- // If pinned, just insert the entry representing the whole pinned buffer.
- if (*IsPinnedOrErr) {
- if (auto Err = insertEntry(BaseHstPtr, BaseDevAccessiblePtr, BaseSize,
- /*Externallylocked=*/true))
- return std::move(Err);
- return BaseDevAccessiblePtr;
- }
+ // If pinned, just insert the entry representing the whole pinned buffer.
+ if (*IsPinnedOrErr) {
+ if (auto Err = insertEntry(BaseHstPtr, BaseDevAccessiblePtr, BaseSize,
+ /*Externallylocked=*/true))
+ return std::move(Err);
+ return BaseDevAccessiblePtr;
}
// Not externally pinned. Do nothing if locking of mapped buffers is disabled.
@@ -1070,7 +1068,7 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
// host buffer and retrieve the device accessible pointer.
auto DevAccessiblePtrOrErr = Device.dataLockImpl(HstPtr, Size);
if (!DevAccessiblePtrOrErr)
- return std::move(DevAccessiblePtrOrErr.takeError());
+ return std::move(DevAccessiblePtrOrErr.takeError());
// Now insert the new entry into the map.
if (auto Err = insertEntry(HstPtr, *DevAccessiblePtrOrErr, Size))
@@ -1118,15 +1116,88 @@ Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr, bool LockMemory) {
}
Error PinnedAllocationMapTy::lockMappedHostBuffer(void *HstPtr, size_t Size) {
- auto Result = lockHostBuffer(HstPtr, Size, true, LockMappedBuffers);
- if (!Result)
- return Result.takeError();
+ assert(HstPtr && "Invalid pointer");
+ assert(Size && "Invalid size");
- return Plugin::success();
+ std::lock_guard<std::shared_mutex> Lock(Mutex);
+
+ // If previously registered, just register a new user on the entry.
+ const EntryTy *Entry = findIntersecting(HstPtr);
+ if (Entry)
+ return registerEntryUse(*Entry, HstPtr, Size);
+
+ size_t BaseSize;
+ void *BaseHstPtr, *BaseDevAccessiblePtr;
+
+ // Check if it was externally pinned by a vendor-specific API.
+ auto IsPinnedOrErr = Device.isPinnedPtrImpl(HstPtr, BaseHstPtr,
+ BaseDevAccessiblePtr, BaseSize);
+ if (!IsPinnedOrErr)
+ return IsPinnedOrErr.takeError();
+
+ // If pinned, just insert the entry representing the whole pinned buffer.
+ if (*IsPinnedOrErr)
+ return insertEntry(BaseHstPtr, BaseDevAccessiblePtr, BaseSize,
+ /*Externallylocked=*/true);
+
+ // Not externally pinned. Do nothing if locking of mapped buffers is disabled.
+ if (!LockMappedBuffers)
+ return Plugin::success();
+
+ // Otherwise, lock the buffer and insert the new entry.
+ auto DevAccessiblePtrOrErr = Device.dataLockImpl(HstPtr, Size);
+ if (!DevAccessiblePtrOrErr) {
+ // Errors may be tolerated.
+ if (!IgnoreLockMappedFailures)
+ return DevAccessiblePtrOrErr.takeError();
+
+ consumeError(DevAccessiblePtrOrErr.takeError());
+ return Plugin::success();
+ }
+
+ return insertEntry(HstPtr, *DevAccessiblePtrOrErr, Size);
}
Error PinnedAllocationMapTy::unlockUnmappedHostBuffer(void *HstPtr) {
- return unlockHostBuffer(HstPtr, LockMappedBuffers);
+ assert(HstPtr && "Invalid pointer");
+
+ std::lock_guard<std::shared_mutex> Lock(Mutex);
+
+ // Check whether there is any intersecting entry.
+ const EntryTy *Entry = findIntersecting(HstPtr);
+
+ // No entry but automatic locking of mapped buffers is disabled, so
+ // nothing to do.
+ if (!Entry && !LockMappedBuffers)
+ return Plugin::success();
+
+ // No entry, automatic locking is enabled, but the locking may have failed, so
+ // do nothing.
+ if (!Entry && IgnoreLockMappedFailures)
+ return Plugin::success();
+
+ // No entry, but the automatic locking is enabled, so this is an error.
+ if (!Entry)
+ return Plugin::error(ErrorCode::INVALID_ARGUMENT,
+ "locked buffer not found");
+
+ // There is entry, so unregister a user and check whether it was the last one.
+ auto LastUseOrErr = unregisterEntryUse(*Entry);
+ if (!LastUseOrErr)
+ return LastUseOrErr.takeError();
+
+ // If it is not the last one, there is nothing to do.
+ if (!(*LastUseOrErr))
+ return Plugin::success();
+
+ // Otherwise, if it was the last and the buffer was locked by the plugin,
+ // unlock it.
+ if (!Entry->ExternallyLocked)
+ if (auto Err = Device.dataUnlockImpl(Entry->HstPtr))
+ return Err;
+
+ // Finally erase the entry from the map.
+ return eraseEntry(*Entry);
}
Error GenericDeviceTy::synchronize(__tgt_async_info *AsyncInfo,
diff --git a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
index f3f62a2225fd2..572e4b2202e04 100644
--- a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
@@ -87,7 +87,7 @@ TEST_P(olMemRegisterTest, PartialOverlapPtrRegister) {
TEST_P(olMemRegisterTest, SuccessMappedRegister) {
int Arr[50];
ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
@@ -97,7 +97,7 @@ TEST_P(olMemRegisterTest, SuccessMultipleMappedRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
@@ -108,7 +108,7 @@ TEST_P(olMemRegisterTest, InvalidSizeMappedRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
olMemRegister(Device, Arr, 0, Flags, &PinnedPtr));
}
@@ -117,7 +117,7 @@ TEST_P(olMemRegisterTest, InvalidPtrMappedRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
olMemRegister(Device, nullptr, sizeof(Arr), Flags, &PinnedPtr));
}
@@ -126,7 +126,7 @@ TEST_P(olMemRegisterTest, InvalidPtrMappedUnRegister) {
int Arr[50];
void *PinnedPtr = nullptr;
ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_REGISTER_MAPPED_MEMORY;
+ OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
olMemUnregister(Device, nullptr, Flags));
>From 34289347a7cfbf3b49b29c0e5e9671cee3970c47 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 3 Feb 2026 14:28:43 -0800
Subject: [PATCH 09/16] Address PR comments
---
offload/liboffload/API/Memory.td | 5 +++--
offload/liboffload/src/OffloadImpl.cpp | 6 +++---
.../plugins-nextgen/common/include/PluginInterface.h | 12 ++++++------
.../plugins-nextgen/common/src/PluginInterface.cpp | 10 +++++-----
4 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 010b375116b0c..0b4747e3c38e8 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -28,7 +28,8 @@ def ol_memory_register_flag_t : Enum {
let desc = "Memory registering/locking flags";
let is_bit_field = 1;
let etors =[
- Etor<"LOCK_MEMORY", "Lock the memory">,
+ Etor<"LOCK_MEMORY", "Page-lock the memory">,
+ Etor<"UNLOCK_MEMORY", "Page-unlock the memory">,
];
}
@@ -181,7 +182,7 @@ def olMemUnregister : Function {
let params = [
Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
Param<"void *", "Ptr", "host pointer", PARAM_IN>,
- Param<"ol_memory_register_flags_t", "Flags", "flags controlling various aspects of registration", PARAM_IN>,
+ Param<"ol_memory_register_flags_t", "Flags", "flags controlling various aspects of unregistration", PARAM_IN>,
];
let returns = [];
}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index bd07da0d06007..855cd82af138c 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1236,7 +1236,7 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
ol_memory_register_flags_t Flags, void **LockedPtr) {
- Expected<void *> LockedPtrOrErr = Device->Device->dataLock(
+ Expected<void *> LockedPtrOrErr = Device->Device->registerMemory(
Ptr, Size, Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY);
if (!LockedPtrOrErr)
return LockedPtrOrErr.takeError();
@@ -1248,8 +1248,8 @@ Error olMemRegister_impl(ol_device_handle_t Device, void *Ptr, size_t Size,
Error olMemUnregister_impl(ol_device_handle_t Device, void *Ptr,
ol_memory_register_flags_t Flags) {
- return Device->Device->dataUnlock(
- Ptr, Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY);
+ return Device->Device->unregisterMemory(
+ Ptr, Flags & OL_MEMORY_REGISTER_FLAG_UNLOCK_MEMORY);
}
Error olQueryQueue_impl(ol_queue_handle_t Queue, bool *IsQueueWorkCompleted) {
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 4d2f034197540..da31dd631a709 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -738,13 +738,13 @@ class PinnedAllocationMapTy {
/// with an already existing one. A partial overlapping with extension is not
/// allowed. The function returns the device accessible pointer of the pinned
/// buffer. The buffer must be unlocked using the unlockHostBuffer function.
- Expected<void *> lockHostBuffer(void *HstPtr, size_t Size,
+ Expected<void *> registerMemory(void *HstPtr, size_t Size,
bool LockMemory = true);
/// Unlock the host buffer at \p HstPtr or unregister a user if other users
/// are still using the pinned allocation. If this was the last user, the
/// pinned allocation is removed from the map and the memory is unlocked.
- Error unlockHostBuffer(void *HstPtr, bool LockMemory = true);
+ Error unregisterMemory(void *HstPtr, bool UnlockMemory = true);
/// Lock or register a host buffer that was recently mapped by libomptarget.
/// This behavior is applied if LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS is
@@ -884,14 +884,14 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// Pin host memory to optimize transfers and return the device accessible
/// pointer that devices should use for memory transfers involving the host
/// pinned allocation.
- Expected<void *> dataLock(void *HstPtr, int64_t Size,
+ Expected<void *> registerMemory(void *HstPtr, int64_t Size,
bool LockMemory = true) {
- return PinnedAllocs.lockHostBuffer(HstPtr, Size, LockMemory);
+ return PinnedAllocs.registerMemory(HstPtr, Size, LockMemory);
}
/// Unpin a host memory buffer that was previously pinned.
- Error dataUnlock(void *HstPtr, bool LockMemory = true) {
- return PinnedAllocs.unlockHostBuffer(HstPtr, LockMemory);
+ Error unregisterMemory(void *HstPtr, bool UnlockMemory = true) {
+ return PinnedAllocs.unregisterMemory(HstPtr, UnlockMemory);
}
/// Lock the host buffer \p HstPtr with \p Size bytes with the vendor-specific
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 897e6f286e626..ec29ac2830576 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1024,7 +1024,7 @@ Error PinnedAllocationMapTy::unregisterHostBuffer(void *HstPtr) {
return eraseEntry(*Entry);
}
-Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
+Expected<void *> PinnedAllocationMapTy::registerMemory(
void *HstPtr, size_t Size, bool LockMemory) {
assert(HstPtr && "Invalid pointer");
assert(Size && "Invalid size");
@@ -1078,7 +1078,7 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(
return *DevAccessiblePtrOrErr;
}
-Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr, bool LockMemory) {
+Error PinnedAllocationMapTy::unregisterMemory(void *HstPtr, bool UnlockMemory) {
assert(HstPtr && "Invalid pointer");
std::lock_guard<std::shared_mutex> Lock(Mutex);
@@ -1087,7 +1087,7 @@ Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr, bool LockMemory) {
// No entry but automatic locking of mapped buffers is disabled, so
// nothing to do.
- if (!Entry && !LockMemory)
+ if (!Entry && !UnlockMemory)
return Plugin::success();
if (!Entry)
@@ -1849,7 +1849,7 @@ int32_t GenericPluginTy::data_delete(int32_t DeviceId, void *TgtPtr,
int32_t GenericPluginTy::data_lock(int32_t DeviceId, void *Ptr, int64_t Size,
void **LockedPtr) {
- auto LockedPtrOrErr = getDevice(DeviceId).dataLock(Ptr, Size);
+ auto LockedPtrOrErr = getDevice(DeviceId).registerMemory(Ptr, Size);
if (!LockedPtrOrErr) {
auto Err = LockedPtrOrErr.takeError();
REPORT() << "Failure to lock memory " << Ptr << ": "
@@ -1868,7 +1868,7 @@ int32_t GenericPluginTy::data_lock(int32_t DeviceId, void *Ptr, int64_t Size,
}
int32_t GenericPluginTy::data_unlock(int32_t DeviceId, void *Ptr) {
- auto Err = getDevice(DeviceId).dataUnlock(Ptr);
+ auto Err = getDevice(DeviceId).unregisterMemory(Ptr);
if (Err) {
REPORT() << "Failure to unlock memory " << Ptr << ": "
<< toString(std::move(Err));
>From 3c936d94a5c4b1f544c993cfe869e9714f0ee290 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 3 Feb 2026 16:38:07 -0800
Subject: [PATCH 10/16] Fix formatting issues
---
.../common/include/PluginInterface.h | 2 +-
.../common/src/PluginInterface.cpp | 5 +-
.../OffloadAPI/memory/olMemRegister.cpp | 70 +++++++++----------
3 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index da31dd631a709..7261fea758709 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -885,7 +885,7 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// pointer that devices should use for memory transfers involving the host
/// pinned allocation.
Expected<void *> registerMemory(void *HstPtr, int64_t Size,
- bool LockMemory = true) {
+ bool LockMemory = true) {
return PinnedAllocs.registerMemory(HstPtr, Size, LockMemory);
}
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index ec29ac2830576..d45d550e1ed0a 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1024,8 +1024,9 @@ Error PinnedAllocationMapTy::unregisterHostBuffer(void *HstPtr) {
return eraseEntry(*Entry);
}
-Expected<void *> PinnedAllocationMapTy::registerMemory(
- void *HstPtr, size_t Size, bool LockMemory) {
+Expected<void *> PinnedAllocationMapTy::registerMemory(void *HstPtr,
+ size_t Size,
+ bool LockMemory) {
assert(HstPtr && "Invalid pointer");
assert(Size && "Invalid size");
diff --git a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
index 572e4b2202e04..d7ea972ce4922 100644
--- a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
@@ -15,24 +15,26 @@ OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemRegisterTest);
TEST_P(olMemRegisterTest, SuccessRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsReg = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsUnreg = OL_MEMORY_REGISTER_FLAG_UNLOCK_MEMORY;
void *PinnedPtr = nullptr;
- ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
}
TEST_P(olMemRegisterTest, SuccessMultipleRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsReg = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsUnreg = OL_MEMORY_REGISTER_FLAG_UNLOCK_MEMORY;
void *PinnedPtr = nullptr;
void *PinnedPtr1 = nullptr;
- ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr1));
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr1));
ASSERT_NE(PinnedPtr1, nullptr);
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr1, Flags));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr1, FlagsUnreg));
}
TEST_P(olMemRegisterTest, InvalidSizeRegister) {
@@ -53,80 +55,78 @@ TEST_P(olMemRegisterTest, InvalidPtrRegister) {
TEST_P(olMemRegisterTest, InvalidPtrUnRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsReg = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsUnreg = OL_MEMORY_REGISTER_FLAG_UNLOCK_MEMORY;
void *PinnedPtr = nullptr;
- ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
- olMemUnregister(Device, nullptr, Flags));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
+ olMemUnregister(Device, nullptr, FlagsUnreg));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
}
TEST_P(olMemRegisterTest, UnregisteredPtrUnRegister) {
int Arr[50];
int Arr1[50];
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsReg = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsUnreg = OL_MEMORY_REGISTER_FLAG_UNLOCK_MEMORY;
void *PinnedPtr = nullptr;
- ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT, olMemUnregister(Device, Arr1, Flags));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
+ ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT, olMemUnregister(Device, Arr1, FlagsUnreg));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
}
TEST_P(olMemRegisterTest, PartialOverlapPtrRegister) {
int Arr[50];
- ol_memory_register_flags_t Flags = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsReg = OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t FlagsUnreg = OL_MEMORY_REGISTER_FLAG_UNLOCK_MEMORY;
void *PinnedPtr = nullptr;
- ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
+ ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT,
- olMemRegister(Device, Arr + 2, sizeof(Arr), Flags, &PinnedPtr));
- ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, Flags));
+ olMemRegister(Device, Arr + 2, sizeof(Arr), FlagsReg, &PinnedPtr));
+ ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
}
-TEST_P(olMemRegisterTest, SuccessMappedRegister) {
+TEST_P(olMemRegisterTest, SuccessRegisterNoLock) {
int Arr[50];
- ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t Flags = {0};
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
}
-TEST_P(olMemRegisterTest, SuccessMultipleMappedRegister) {
+TEST_P(olMemRegisterTest, SuccessMultipleRegisterNoLock) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t Flags = {0};
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
}
-TEST_P(olMemRegisterTest, InvalidSizeMappedRegister) {
+TEST_P(olMemRegisterTest, InvalidSizeRegisterNoLock) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t Flags = {0};
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
olMemRegister(Device, Arr, 0, Flags, &PinnedPtr));
}
-TEST_P(olMemRegisterTest, InvalidPtrMappedRegister) {
+TEST_P(olMemRegisterTest, InvalidPtrRegisterNoLock) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t Flags = {0};
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
olMemRegister(Device, nullptr, sizeof(Arr), Flags, &PinnedPtr));
}
-TEST_P(olMemRegisterTest, InvalidPtrMappedUnRegister) {
+TEST_P(olMemRegisterTest, InvalidPtrUnRegisterNoLock) {
int Arr[50];
void *PinnedPtr = nullptr;
- ol_memory_register_flags_t Flags =
- OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY;
+ ol_memory_register_flags_t Flags = {0};
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), Flags, &PinnedPtr));
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
olMemUnregister(Device, nullptr, Flags));
>From d281583d5c86e0896851b0dc9e677a468dfaa93e Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 3 Feb 2026 16:42:46 -0800
Subject: [PATCH 11/16] Fix formatting
---
offload/unittests/OffloadAPI/memory/olMemRegister.cpp | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
index d7ea972ce4922..94d706ac030dc 100644
--- a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
@@ -31,7 +31,8 @@ TEST_P(olMemRegisterTest, SuccessMultipleRegister) {
void *PinnedPtr1 = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr1));
+ ASSERT_SUCCESS(
+ olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr1));
ASSERT_NE(PinnedPtr1, nullptr);
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr1, FlagsUnreg));
@@ -73,7 +74,8 @@ TEST_P(olMemRegisterTest, UnregisteredPtrUnRegister) {
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT, olMemUnregister(Device, Arr1, FlagsUnreg));
+ ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT,
+ olMemUnregister(Device, Arr1, FlagsUnreg));
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
}
@@ -84,8 +86,9 @@ TEST_P(olMemRegisterTest, PartialOverlapPtrRegister) {
void *PinnedPtr = nullptr;
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
- ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT,
- olMemRegister(Device, Arr + 2, sizeof(Arr), FlagsReg, &PinnedPtr));
+ ASSERT_ERROR(
+ OL_ERRC_INVALID_ARGUMENT,
+ olMemRegister(Device, Arr + 2, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
}
>From 7317ca5ac00c5dbe2ea419d89c6c4069fededbfd Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 3 Feb 2026 17:16:39 -0800
Subject: [PATCH 12/16] Refactoring to eliminate functions that were combined
---
.../common/include/PluginInterface.h | 60 +++-------
.../common/src/PluginInterface.cpp | 112 +++++-------------
.../OffloadAPI/memory/olMemRegister.cpp | 2 +-
3 files changed, 43 insertions(+), 131 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 7261fea758709..05fdc2613c54d 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -620,12 +620,6 @@ class PinnedAllocationMapTy {
/// Reference to the corresponding device.
GenericDeviceTy &Device;
- /// Indicate whether mapped host buffers should be locked automatically.
- bool LockMappedBuffers;
-
- /// Indicate whether failures when locking mapped buffers should be ignored.
- bool IgnoreLockMappedFailures;
-
/// Find an allocation that intersects with \p HstPtr pointer. Assume the
/// map's mutex is acquired.
const EntryTy *findIntersecting(const void *HstPtr) const {
@@ -691,34 +685,7 @@ class PinnedAllocationMapTy {
public:
/// Create the map of pinned allocations corresponding to a specific device.
- PinnedAllocationMapTy(GenericDeviceTy &Device) : Device(Device) {
-
- // Envar that indicates whether mapped host buffers should be locked
- // automatically. The possible values are boolean (on/off) and a special:
- // off: Mapped host buffers are not locked.
- // on: Mapped host buffers are locked in a best-effort approach.
- // Failure to lock the buffers are silent.
- // mandatory: Mapped host buffers are always locked and failures to lock
- // a buffer results in a fatal error.
- StringEnvar OMPX_LockMappedBuffers("LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS",
- "off");
-
- bool Enabled;
- if (StringParser::parse(OMPX_LockMappedBuffers.get().data(), Enabled)) {
- // Parsed as a boolean value. Enable the feature if necessary.
- LockMappedBuffers = Enabled;
- IgnoreLockMappedFailures = true;
- } else if (OMPX_LockMappedBuffers.get() == "mandatory") {
- // Enable the feature and failures are fatal.
- LockMappedBuffers = true;
- IgnoreLockMappedFailures = false;
- } else {
- // Disable by default.
- ODBG(OLDT_Alloc) << "Invalid value LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS="
- << OMPX_LockMappedBuffers.get();
- LockMappedBuffers = false;
- }
- }
+ PinnedAllocationMapTy(GenericDeviceTy &Device) : Device(Device) {}
/// Register a buffer that was recently allocated as a locked host buffer.
/// None of the already registered pinned allocations should intersect with
@@ -746,15 +713,6 @@ class PinnedAllocationMapTy {
/// pinned allocation is removed from the map and the memory is unlocked.
Error unregisterMemory(void *HstPtr, bool UnlockMemory = true);
- /// Lock or register a host buffer that was recently mapped by libomptarget.
- /// This behavior is applied if LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS is
- /// enabled. Even if not enabled, externally locked buffers are registered
- /// in order to optimize their transfers.
- Error lockMappedHostBuffer(void *HstPtr, size_t Size);
-
- /// Unlock or unregister a host buffer that was unmapped by libomptarget.
- Error unlockUnmappedHostBuffer(void *HstPtr);
-
/// Return the device accessible pointer associated to the host pinned
/// allocation which the \p HstPtr belongs, if any. Return null in case the
/// \p HstPtr does not belong to any host pinned allocation. The device
@@ -907,14 +865,20 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// as source/destination of memory transfers. We can use this information to
/// lock the host buffer and optimize its memory transfers.
Error notifyDataMapped(void *HstPtr, int64_t Size) {
- return PinnedAllocs.lockMappedHostBuffer(HstPtr, Size);
+ auto Err = PinnedAllocs.registerMemory(HstPtr, Size, LockMappedBuffers);
+ if (!Err && !IgnoreLockMappedFailures)
+ return Err.takeError();
+ return Plugin::success();
}
/// Mark the host buffer with address \p HstPtr as unmapped. This means that
/// libomptarget removed an existing mapping. If the plugin locked the buffer
/// in notifyDataMapped, this function should unlock it.
Error notifyDataUnmapped(void *HstPtr) {
- return PinnedAllocs.unlockUnmappedHostBuffer(HstPtr);
+ auto Err = PinnedAllocs.unregisterMemory(HstPtr, LockMappedBuffers);
+ if (IgnoreLockMappedFailures)
+ return Plugin::success();
+ return Err;
}
/// Check whether the host buffer with address \p HstPtr is pinned by the
@@ -1210,6 +1174,12 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
BoolEnvar OMPX_ReuseBlocksForHighTripCount =
BoolEnvar("LIBOMPTARGET_REUSE_BLOCKS_FOR_HIGH_TRIP_COUNT", true);
+ /// Indicate whether mapped host buffers should be locked automatically.
+ bool LockMappedBuffers;
+
+ /// Indicate whether failures when locking mapped buffers should be ignored.
+ bool IgnoreLockMappedFailures;
+
protected:
/// Environment variables defined by the LLVM OpenMP implementation
/// regarding the initial number of streams and events.
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index d45d550e1ed0a..15261a3df46fa 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -733,6 +733,33 @@ GenericDeviceTy::GenericDeviceTy(GenericPluginTy &Plugin, int32_t DeviceId,
#undef bindOmptCallback
#endif
+
+ // Envar that indicates whether mapped host buffers should be locked
+ // automatically. The possible values are boolean (on/off) and a special:
+ // off: Mapped host buffers are not locked.
+ // on: Mapped host buffers are locked in a best-effort approach.
+ // Failure to lock the buffers are silent.
+ // mandatory: Mapped host buffers are always locked and failures to lock
+ // a buffer results in a fatal error.
+ StringEnvar OMPX_LockMappedBuffers("LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS",
+ "off");
+
+ bool Enabled;
+ if (StringParser::parse(OMPX_LockMappedBuffers.get().data(), Enabled)) {
+ // Parsed as a boolean value. Enable the feature if necessary.
+ LockMappedBuffers = Enabled;
+ IgnoreLockMappedFailures = true;
+ } else if (OMPX_LockMappedBuffers.get() == "mandatory") {
+ // Enable the feature and failures are fatal.
+ LockMappedBuffers = true;
+ IgnoreLockMappedFailures = false;
+ } else {
+ // Disable by default.
+ ODBG(OLDT_Alloc) << "Invalid value LIBOMPTARGET_LOCK_MAPPED_HOST_BUFFERS="
+ << OMPX_LockMappedBuffers.get();
+ LockMappedBuffers = false;
+ }
+
}
Error GenericDeviceTy::init(GenericPluginTy &Plugin) {
@@ -1116,91 +1143,6 @@ Error PinnedAllocationMapTy::unregisterMemory(void *HstPtr, bool UnlockMemory) {
return eraseEntry(*Entry);
}
-Error PinnedAllocationMapTy::lockMappedHostBuffer(void *HstPtr, size_t Size) {
- assert(HstPtr && "Invalid pointer");
- assert(Size && "Invalid size");
-
- std::lock_guard<std::shared_mutex> Lock(Mutex);
-
- // If previously registered, just register a new user on the entry.
- const EntryTy *Entry = findIntersecting(HstPtr);
- if (Entry)
- return registerEntryUse(*Entry, HstPtr, Size);
-
- size_t BaseSize;
- void *BaseHstPtr, *BaseDevAccessiblePtr;
-
- // Check if it was externally pinned by a vendor-specific API.
- auto IsPinnedOrErr = Device.isPinnedPtrImpl(HstPtr, BaseHstPtr,
- BaseDevAccessiblePtr, BaseSize);
- if (!IsPinnedOrErr)
- return IsPinnedOrErr.takeError();
-
- // If pinned, just insert the entry representing the whole pinned buffer.
- if (*IsPinnedOrErr)
- return insertEntry(BaseHstPtr, BaseDevAccessiblePtr, BaseSize,
- /*Externallylocked=*/true);
-
- // Not externally pinned. Do nothing if locking of mapped buffers is disabled.
- if (!LockMappedBuffers)
- return Plugin::success();
-
- // Otherwise, lock the buffer and insert the new entry.
- auto DevAccessiblePtrOrErr = Device.dataLockImpl(HstPtr, Size);
- if (!DevAccessiblePtrOrErr) {
- // Errors may be tolerated.
- if (!IgnoreLockMappedFailures)
- return DevAccessiblePtrOrErr.takeError();
-
- consumeError(DevAccessiblePtrOrErr.takeError());
- return Plugin::success();
- }
-
- return insertEntry(HstPtr, *DevAccessiblePtrOrErr, Size);
-}
-
-Error PinnedAllocationMapTy::unlockUnmappedHostBuffer(void *HstPtr) {
- assert(HstPtr && "Invalid pointer");
-
- std::lock_guard<std::shared_mutex> Lock(Mutex);
-
- // Check whether there is any intersecting entry.
- const EntryTy *Entry = findIntersecting(HstPtr);
-
- // No entry but automatic locking of mapped buffers is disabled, so
- // nothing to do.
- if (!Entry && !LockMappedBuffers)
- return Plugin::success();
-
- // No entry, automatic locking is enabled, but the locking may have failed, so
- // do nothing.
- if (!Entry && IgnoreLockMappedFailures)
- return Plugin::success();
-
- // No entry, but the automatic locking is enabled, so this is an error.
- if (!Entry)
- return Plugin::error(ErrorCode::INVALID_ARGUMENT,
- "locked buffer not found");
-
- // There is entry, so unregister a user and check whether it was the last one.
- auto LastUseOrErr = unregisterEntryUse(*Entry);
- if (!LastUseOrErr)
- return LastUseOrErr.takeError();
-
- // If it is not the last one, there is nothing to do.
- if (!(*LastUseOrErr))
- return Plugin::success();
-
- // Otherwise, if it was the last and the buffer was locked by the plugin,
- // unlock it.
- if (!Entry->ExternallyLocked)
- if (auto Err = Device.dataUnlockImpl(Entry->HstPtr))
- return Err;
-
- // Finally erase the entry from the map.
- return eraseEntry(*Entry);
-}
-
Error GenericDeviceTy::synchronize(__tgt_async_info *AsyncInfo,
bool ReleaseQueue) {
if (!AsyncInfo)
diff --git a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
index 94d706ac030dc..60f49c641798a 100644
--- a/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
+++ b/offload/unittests/OffloadAPI/memory/olMemRegister.cpp
@@ -75,7 +75,7 @@ TEST_P(olMemRegisterTest, UnregisteredPtrUnRegister) {
ASSERT_SUCCESS(olMemRegister(Device, Arr, sizeof(Arr), FlagsReg, &PinnedPtr));
ASSERT_NE(PinnedPtr, nullptr);
ASSERT_ERROR(OL_ERRC_INVALID_ARGUMENT,
- olMemUnregister(Device, Arr1, FlagsUnreg));
+ olMemUnregister(Device, Arr1, FlagsUnreg));
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
}
>From c6b7c16d019b538a997075a207fa68f4620c617d Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Tue, 3 Feb 2026 17:21:01 -0800
Subject: [PATCH 13/16] Fix formatting
---
offload/plugins-nextgen/common/include/PluginInterface.h | 2 +-
offload/plugins-nextgen/common/src/PluginInterface.cpp | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 05fdc2613c54d..562bb2f77ace2 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -865,7 +865,7 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// as source/destination of memory transfers. We can use this information to
/// lock the host buffer and optimize its memory transfers.
Error notifyDataMapped(void *HstPtr, int64_t Size) {
- auto Err = PinnedAllocs.registerMemory(HstPtr, Size, LockMappedBuffers);
+ auto Err = PinnedAllocs.registerMemory(HstPtr, Size, LockMappedBuffers);
if (!Err && !IgnoreLockMappedFailures)
return Err.takeError();
return Plugin::success();
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index 15261a3df46fa..99af126b68299 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -759,7 +759,6 @@ GenericDeviceTy::GenericDeviceTy(GenericPluginTy &Plugin, int32_t DeviceId,
<< OMPX_LockMappedBuffers.get();
LockMappedBuffers = false;
}
-
}
Error GenericDeviceTy::init(GenericPluginTy &Plugin) {
>From 16c105d29243d7403a8b41925fa6a1805728ebe9 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 11 Feb 2026 11:53:58 -0800
Subject: [PATCH 14/16] Address PR comments
---
offload/liboffload/API/Memory.td | 7 ++++---
.../common/include/PluginInterface.h | 16 +++++++++-------
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 0b4747e3c38e8..1f40d3c3dea28 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -152,7 +152,8 @@ def olMemRegister : Function {
"Pins host memory to optimize transfers and returns the device accessible",
"stable pointer that devices should use for memory transfers involving the host",
"pinned allocation. If the buffer intersects with other existing buffer,",
- "a new user will be registered. A partial overlapping is not allowed.",
+ "if the buffer is locked outside of this API, or Flags doesn't contain LOCK_MEMORY
+ "flag a new user will be registered. A partial overlapping is not allowed.",
"The pinned pointer can be accessed both on host and device and",
"no guarantees are made about consistency.",
"The pinned pointer should be used to execute memory transfers",
@@ -176,8 +177,8 @@ def olMemUnregister : Function {
let desc = "Unregister and page-unlock host memory.";
let details = [
"Unpins host memory that was previously pinned or unregister the buffer",
- "if other users are still using the buffer. If no users are using the buffer",
- "the memory is unlocked."
+ "if other users are still using the buffer or Flags doesn't contain UNLOCK_MEMORY flag"
+ "Otherwise the memory is unlocked."
];
let params = [
Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 562bb2f77ace2..5eb022a9efc9c 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -702,15 +702,17 @@ class PinnedAllocationMapTy {
Error unregisterHostBuffer(void *HstPtr);
/// Lock the host buffer at \p HstPtr or register a new user if it intersects
- /// with an already existing one. A partial overlapping with extension is not
+ /// with an already existing one, locked outside of this API or passed
+ /// LockMemory parameter as false. A partial overlapping with extension is not
/// allowed. The function returns the device accessible pointer of the pinned
/// buffer. The buffer must be unlocked using the unlockHostBuffer function.
Expected<void *> registerMemory(void *HstPtr, size_t Size,
bool LockMemory = true);
/// Unlock the host buffer at \p HstPtr or unregister a user if other users
- /// are still using the pinned allocation. If this was the last user, the
- /// pinned allocation is removed from the map and the memory is unlocked.
+ /// are still using the pinned allocation or passed UnlockMemory parameter as
+ /// false. If this was the last user, the pinned allocation is removed from
+ /// the map and the memory is unlocked.
Error unregisterMemory(void *HstPtr, bool UnlockMemory = true);
/// Return the device accessible pointer associated to the host pinned
@@ -839,15 +841,15 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// Deallocate data from the device or involving the device.
Error dataDelete(void *TgtPtr, TargetAllocTy Kind);
- /// Pin host memory to optimize transfers and return the device accessible
- /// pointer that devices should use for memory transfers involving the host
- /// pinned allocation.
+ /// Pin or register host memory to optimize transfers and return the device
+ /// accessible pointer that devices should use for memory transfers involving
+ /// the host pinned allocation.
Expected<void *> registerMemory(void *HstPtr, int64_t Size,
bool LockMemory = true) {
return PinnedAllocs.registerMemory(HstPtr, Size, LockMemory);
}
- /// Unpin a host memory buffer that was previously pinned.
+ /// Unpin or unregister a host memory buffer that was previously pinned.
Error unregisterMemory(void *HstPtr, bool UnlockMemory = true) {
return PinnedAllocs.unregisterMemory(HstPtr, UnlockMemory);
}
>From e48b8d8b5cf86223f8abcb50fe2582ba1d323bb5 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Wed, 11 Feb 2026 12:11:39 -0800
Subject: [PATCH 15/16] Fix formatting
---
offload/plugins-nextgen/common/include/PluginInterface.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 5eb022a9efc9c..03a05e19dcea5 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -702,7 +702,7 @@ class PinnedAllocationMapTy {
Error unregisterHostBuffer(void *HstPtr);
/// Lock the host buffer at \p HstPtr or register a new user if it intersects
- /// with an already existing one, locked outside of this API or passed
+ /// with an already existing one, locked outside of this API or passed
/// LockMemory parameter as false. A partial overlapping with extension is not
/// allowed. The function returns the device accessible pointer of the pinned
/// buffer. The buffer must be unlocked using the unlockHostBuffer function.
@@ -711,7 +711,7 @@ class PinnedAllocationMapTy {
/// Unlock the host buffer at \p HstPtr or unregister a user if other users
/// are still using the pinned allocation or passed UnlockMemory parameter as
- /// false. If this was the last user, the pinned allocation is removed from
+ /// false. If this was the last user, the pinned allocation is removed from
/// the map and the memory is unlocked.
Error unregisterMemory(void *HstPtr, bool UnlockMemory = true);
@@ -841,8 +841,8 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
/// Deallocate data from the device or involving the device.
Error dataDelete(void *TgtPtr, TargetAllocTy Kind);
- /// Pin or register host memory to optimize transfers and return the device
- /// accessible pointer that devices should use for memory transfers involving
+ /// Pin or register host memory to optimize transfers and return the device
+ /// accessible pointer that devices should use for memory transfers involving
/// the host pinned allocation.
Expected<void *> registerMemory(void *HstPtr, int64_t Size,
bool LockMemory = true) {
>From 63e4c0a8fc9d8157ff00ff76c885d0fd297d9915 Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Fri, 13 Feb 2026 11:12:52 -0800
Subject: [PATCH 16/16] Address PR comments
---
offload/liboffload/API/Memory.td | 20 +++++++++---------
.../common/include/PluginInterface.h | 21 ++++++++++---------
2 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 1f40d3c3dea28..4a62bbc8ea1a1 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -147,14 +147,14 @@ def olMemFill : Function {
}
def olMemRegister : Function {
- let desc = "Register and page-lock host memory so it can be accessible by the device.";
+ let desc = "Register and optionally page-lock host memory so it can be accessible by the device.";
let details = [
- "Pins host memory to optimize transfers and returns the device accessible",
- "stable pointer that devices should use for memory transfers involving the host",
- "pinned allocation. If the buffer intersects with other existing buffer,",
+ "Registers host memory and optionally page-locks it to optimize transfers and returns",
+ "the device accessible stable pointer that devices should use for memory transfers",
+ "involving the host pinned allocation. If the buffer intersects with other existing buffer,",
"if the buffer is locked outside of this API, or Flags doesn't contain LOCK_MEMORY
- "flag a new user will be registered. A partial overlapping is not allowed.",
- "The pinned pointer can be accessed both on host and device and",
+ "flag a new user will be registered. Partial overlapping with an already registered range is",
+ "not allowed. The pinned pointer can be accessed both on host and device and",
"no guarantees are made about consistency.",
"The pinned pointer should be used to execute memory transfers",
"as it is a stable pointer for memory access."
@@ -174,11 +174,11 @@ def olMemRegister : Function {
}
def olMemUnregister : Function {
- let desc = "Unregister and page-unlock host memory.";
+ let desc = "Unregister host memory and optionally page-unlock it.";
let details = [
- "Unpins host memory that was previously pinned or unregister the buffer",
- "if other users are still using the buffer or Flags doesn't contain UNLOCK_MEMORY flag"
- "Otherwise the memory is unlocked."
+ "Unregisters host memory and optionally page-unlocks it.",
+ "If other users are still using the buffer or Flags doesn't contain UNLOCK_MEMORY flag"
+ "the memory is unregistered, otherwise the memory is unlocked."
];
let params = [
Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index 03a05e19dcea5..4c15294999d78 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -701,18 +701,19 @@ class PinnedAllocationMapTy {
/// not be unlocked by this function.
Error unregisterHostBuffer(void *HstPtr);
- /// Lock the host buffer at \p HstPtr or register a new user if it intersects
- /// with an already existing one, locked outside of this API or passed
- /// LockMemory parameter as false. A partial overlapping with extension is not
- /// allowed. The function returns the device accessible pointer of the pinned
- /// buffer. The buffer must be unlocked using the unlockHostBuffer function.
+ /// Registers and optionally page-locks host memory at \p HstPtr . Registers
+ /// a new user if it intersects with an already existing one, locked outside
+ /// of this API or passed LockMemory parameter as false. A partial overlapping
+ /// with extension is not allowed. The function returns the device accessible
+ /// pointer of the pinned buffer. The buffer must be unlocked using the
+ /// unlockHostBuffer function.
Expected<void *> registerMemory(void *HstPtr, size_t Size,
bool LockMemory = true);
- /// Unlock the host buffer at \p HstPtr or unregister a user if other users
- /// are still using the pinned allocation or passed UnlockMemory parameter as
- /// false. If this was the last user, the pinned allocation is removed from
- /// the map and the memory is unlocked.
+ /// Unregisters and optionally unlocks host memory at \p HstPtr . Unregister a
+ /// user if other users are still using the pinned allocation or passed
+ /// UnlockMemory parameter as false. If this was the last user, the pinned
+ /// allocation is removed from the map and the memory is unlocked.
Error unregisterMemory(void *HstPtr, bool UnlockMemory = true);
/// Return the device accessible pointer associated to the host pinned
@@ -849,7 +850,7 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
return PinnedAllocs.registerMemory(HstPtr, Size, LockMemory);
}
- /// Unpin or unregister a host memory buffer that was previously pinned.
+ /// Unregisters and optionally page-unlocks a host memory buffer.
Error unregisterMemory(void *HstPtr, bool UnlockMemory = true) {
return PinnedAllocs.unregisterMemory(HstPtr, UnlockMemory);
}
More information about the llvm-commits
mailing list