[OFFLOAD] Extend olMemRegister API to handle cases when a memory block may have been mapped outside of liboffload. (#172226)
This PR adds extends liboffload olMemRegister API to handle a case when a memory block may have been mapped before calling olMemRegister to support some use cases in libomptarget
This commit is contained in:
parent
de03ec740b
commit
1c6d774baa
@ -24,6 +24,15 @@ 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<"LOCK_MEMORY", "Page-lock the memory">,
|
||||
Etor<"UNLOCK_MEMORY", "Page-unlock the memory">,
|
||||
];
|
||||
}
|
||||
|
||||
def olMemAlloc : Function {
|
||||
let desc = "Creates a memory allocation on the specified device.";
|
||||
let details = [
|
||||
@ -138,13 +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,",
|
||||
"a new user will be registered. A partial overlapping is not allowed.",
|
||||
"The pinned pointer can be accessed both on host and device and",
|
||||
"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. 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."
|
||||
@ -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 = [
|
||||
@ -164,15 +174,16 @@ 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. If no users are using the buffer",
|
||||
"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>,
|
||||
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 unregistration", PARAM_IN>,
|
||||
];
|
||||
let returns = [];
|
||||
}
|
||||
|
||||
@ -1176,8 +1176,9 @@ 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->registerMemory(
|
||||
Ptr, Size, Flags & OL_MEMORY_REGISTER_FLAG_LOCK_MEMORY);
|
||||
if (!LockedPtrOrErr)
|
||||
return LockedPtrOrErr.takeError();
|
||||
|
||||
@ -1186,8 +1187,10 @@ 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->unregisterMemory(
|
||||
Ptr, Flags & OL_MEMORY_REGISTER_FLAG_UNLOCK_MEMORY);
|
||||
}
|
||||
|
||||
Error olQueryQueue_impl(ol_queue_handle_t Queue, bool *IsQueueWorkCompleted) {
|
||||
|
||||
@ -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
|
||||
@ -734,25 +701,20 @@ public:
|
||||
/// 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. 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);
|
||||
/// 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. If this was the last user, the
|
||||
/// pinned allocation is removed from the map and the memory is unlocked.
|
||||
Error unlockHostBuffer(void *HstPtr);
|
||||
|
||||
/// 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);
|
||||
/// 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
|
||||
/// allocation which the \p HstPtr belongs, if any. Return null in case the
|
||||
@ -880,16 +842,17 @@ 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.
|
||||
Expected<void *> dataLock(void *HstPtr, int64_t Size) {
|
||||
return PinnedAllocs.lockHostBuffer(HstPtr, Size);
|
||||
/// 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.
|
||||
Error dataUnlock(void *HstPtr) {
|
||||
return PinnedAllocs.unlockHostBuffer(HstPtr);
|
||||
/// Unregisters and optionally page-unlocks a host memory buffer.
|
||||
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
|
||||
@ -905,14 +868,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
|
||||
@ -1208,6 +1177,12 @@ private:
|
||||
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.
|
||||
|
||||
@ -733,6 +733,32 @@ 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) {
|
||||
@ -1024,8 +1050,9 @@ Error PinnedAllocationMapTy::unregisterHostBuffer(void *HstPtr) {
|
||||
return eraseEntry(*Entry);
|
||||
}
|
||||
|
||||
Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
|
||||
size_t Size) {
|
||||
Expected<void *> PinnedAllocationMapTy::registerMemory(void *HstPtr,
|
||||
size_t Size,
|
||||
bool LockMemory) {
|
||||
assert(HstPtr && "Invalid pointer");
|
||||
assert(Size && "Invalid size");
|
||||
|
||||
@ -1043,11 +1070,32 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
|
||||
utils::getPtrDiff(HstPtr, Entry->HstPtr));
|
||||
}
|
||||
|
||||
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 (!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)
|
||||
return DevAccessiblePtrOrErr.takeError();
|
||||
return std::move(DevAccessiblePtrOrErr.takeError());
|
||||
|
||||
// Now insert the new entry into the map.
|
||||
if (auto Err = insertEntry(HstPtr, *DevAccessiblePtrOrErr, Size))
|
||||
@ -1057,12 +1105,18 @@ Expected<void *> PinnedAllocationMapTy::lockHostBuffer(void *HstPtr,
|
||||
return *DevAccessiblePtrOrErr;
|
||||
}
|
||||
|
||||
Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr) {
|
||||
Error PinnedAllocationMapTy::unregisterMemory(void *HstPtr, bool UnlockMemory) {
|
||||
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 && !UnlockMemory)
|
||||
return Plugin::success();
|
||||
|
||||
if (!Entry)
|
||||
return Plugin::error(ErrorCode::INVALID_ARGUMENT,
|
||||
"cannot find locked buffer");
|
||||
@ -1088,91 +1142,6 @@ Error PinnedAllocationMapTy::unlockHostBuffer(void *HstPtr) {
|
||||
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)
|
||||
@ -1822,7 +1791,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 << ": "
|
||||
@ -1841,7 +1810,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));
|
||||
|
||||
@ -15,29 +15,32 @@ OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemRegisterTest);
|
||||
|
||||
TEST_P(olMemRegisterTest, SuccessRegister) {
|
||||
int Arr[50];
|
||||
ol_memory_register_flags_t Flags = {};
|
||||
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));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
|
||||
}
|
||||
|
||||
TEST_P(olMemRegisterTest, SuccessMultipleRegister) {
|
||||
int Arr[50];
|
||||
ol_memory_register_flags_t Flags = {};
|
||||
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));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr1));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr1, FlagsUnreg));
|
||||
}
|
||||
|
||||
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 +48,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 +56,82 @@ TEST_P(olMemRegisterTest, InvalidPtrRegister) {
|
||||
|
||||
TEST_P(olMemRegisterTest, InvalidPtrUnRegister) {
|
||||
int Arr[50];
|
||||
ol_memory_register_flags_t Flags = {};
|
||||
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));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr));
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
|
||||
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_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));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr));
|
||||
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_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), FlagsReg, &PinnedPtr));
|
||||
ASSERT_NE(PinnedPtr, nullptr);
|
||||
ASSERT_ERROR(
|
||||
OL_ERRC_INVALID_ARGUMENT,
|
||||
olMemRegister(Device, Arr + 2, sizeof(Arr), FlagsReg, &PinnedPtr));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, PinnedPtr, FlagsUnreg));
|
||||
}
|
||||
|
||||
TEST_P(olMemRegisterTest, SuccessRegisterNoLock) {
|
||||
int Arr[50];
|
||||
ol_memory_register_flags_t Flags = {0};
|
||||
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, Arr, Flags));
|
||||
}
|
||||
|
||||
TEST_P(olMemRegisterTest, SuccessMultipleRegisterNoLock) {
|
||||
int Arr[50];
|
||||
void *PinnedPtr = nullptr;
|
||||
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, InvalidSizeRegisterNoLock) {
|
||||
int Arr[50];
|
||||
void *PinnedPtr = nullptr;
|
||||
ol_memory_register_flags_t Flags = {0};
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_SIZE,
|
||||
olMemRegister(Device, Arr, 0, Flags, &PinnedPtr));
|
||||
}
|
||||
|
||||
TEST_P(olMemRegisterTest, InvalidPtrRegisterNoLock) {
|
||||
int Arr[50];
|
||||
void *PinnedPtr = nullptr;
|
||||
ol_memory_register_flags_t Flags = {0};
|
||||
ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER,
|
||||
olMemRegister(Device, nullptr, sizeof(Arr), Flags, &PinnedPtr));
|
||||
}
|
||||
|
||||
TEST_P(olMemRegisterTest, InvalidPtrUnRegisterNoLock) {
|
||||
int Arr[50];
|
||||
void *PinnedPtr = nullptr;
|
||||
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));
|
||||
ASSERT_SUCCESS(olMemUnregister(Device, Arr, Flags));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user