[Openmp-commits] [openmp] [openmp] Fixed Support for VA for record-replay. (PR #70396)
via Openmp-commits
openmp-commits at lists.llvm.org
Thu Oct 26 17:26:50 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Konstantinos Parasyris (koparasy)
<details>
<summary>Changes</summary>
The commit was discussed in phabricator (https://reviews.llvm.org/D157186). Additionally this should fix issue #<!-- -->69905.
Record replay currently fails on AMD as it conflicts with the heap memory allocator introduced in #<!-- -->69806. The workaround is setting `LIBOMPTARGET_HEAP_SIZE=0` during both record and replay run.
---
Patch is 28.28 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/70396.diff
14 Files Affected:
- (modified) openmp/libomptarget/include/Utilities.h (+5)
- (modified) openmp/libomptarget/include/omptarget.h (+1-1)
- (modified) openmp/libomptarget/include/rtl.h (+2-1)
- (modified) openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp (+10)
- (modified) openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp (+94-26)
- (modified) openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h (+15)
- (modified) openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp (+10)
- (modified) openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.h (+82)
- (modified) openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp (+117)
- (modified) openmp/libomptarget/src/device.cpp (+3-2)
- (modified) openmp/libomptarget/src/interface.cpp (+3-2)
- (modified) openmp/libomptarget/src/omptarget.cpp (+10-11)
- (modified) openmp/libomptarget/src/private.h (+1-1)
- (modified) openmp/libomptarget/tools/kernelreplay/llvm-omp-kernel-replay.cpp (+6-4)
``````````diff
diff --git a/openmp/libomptarget/include/Utilities.h b/openmp/libomptarget/include/Utilities.h
index 82593e206e4d032..84d38d05911f712 100644
--- a/openmp/libomptarget/include/Utilities.h
+++ b/openmp/libomptarget/include/Utilities.h
@@ -253,6 +253,11 @@ template <typename Ty> Ty *alignPtr(Ty *Ptr, int64_t Alignment) {
return std::align(Alignment, sizeof(char), Ptr, Space);
}
+/// Round up \p V to a \p Boundary.
+template <typename Ty> inline Ty roundUp(Ty V, Ty Boundary) {
+ return (V + Boundary - 1) / Boundary * Boundary;
+}
+
} // namespace target
} // namespace omp
} // namespace llvm
diff --git a/openmp/libomptarget/include/omptarget.h b/openmp/libomptarget/include/omptarget.h
index e1f0f77849fa206..de4a1935c28632e 100644
--- a/openmp/libomptarget/include/omptarget.h
+++ b/openmp/libomptarget/include/omptarget.h
@@ -439,7 +439,7 @@ void __tgt_set_info_flag(uint32_t);
int __tgt_print_device_info(int64_t DeviceId);
int __tgt_activate_record_replay(int64_t DeviceId, uint64_t MemorySize,
- bool IsRecord, bool SaveOutput);
+ void *VAddr, bool IsRecord, bool SaveOutput);
#ifdef __cplusplus
}
diff --git a/openmp/libomptarget/include/rtl.h b/openmp/libomptarget/include/rtl.h
index 782a46e27bf47e6..2272577684f0c6c 100644
--- a/openmp/libomptarget/include/rtl.h
+++ b/openmp/libomptarget/include/rtl.h
@@ -73,7 +73,8 @@ struct RTLInfoTy {
typedef int32_t(data_notify_mapped_ty)(int32_t, void *, int64_t);
typedef int32_t(data_notify_unmapped_ty)(int32_t, void *);
typedef int32_t(set_device_offset_ty)(int32_t);
- typedef int32_t(activate_record_replay_ty)(int32_t, uint64_t, bool, bool);
+ typedef int32_t(activate_record_replay_ty)(int32_t, uint64_t, void *, bool,
+ bool);
int32_t Idx = -1; // RTL index, index is the number of devices
// of other RTLs that were registered before,
diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp
index 756c5003b0d542c..ff16464ebaec856 100644
--- a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -2581,6 +2581,16 @@ struct AMDGPUDeviceTy : public GenericDeviceTy, AMDGenericDeviceTy {
DeviceMemoryPoolSize = Value;
return Plugin::success();
}
+ Error getDeviceMemorySize(uint64_t &Value) override {
+ for (AMDGPUMemoryPoolTy *Pool : AllMemoryPools) {
+ if (Pool->isGlobal()) {
+ hsa_status_t Status =
+ Pool->getAttrRaw(HSA_AMD_MEMORY_POOL_INFO_SIZE, Value);
+ return Plugin::check(Status, "Error in getting device memory size: %s");
+ }
+ }
+ return Plugin::error("getDeviceMemorySize:: no global pool");
+ }
/// AMDGPU-specific function to get device attributes.
template <typename Ty> Error getDeviceAttr(uint32_t Kind, Ty &Value) {
diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp
index 0243f0205dbf0e5..ab331b5ff882a02 100644
--- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp
+++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp
@@ -49,40 +49,88 @@ struct RecordReplayTy {
void *MemoryStart;
void *MemoryPtr;
size_t MemorySize;
+ size_t TotalSize;
GenericDeviceTy *Device;
std::mutex AllocationLock;
RRStatusTy Status;
bool ReplaySaveOutput;
- uint64_t DeviceMemorySize;
-
- // Record/replay pre-allocates the largest possible device memory using the
- // default kind.
- // TODO: Expand allocation to include other kinds (device, host, shared) and
- // possibly use a MemoryManager to track (de-)allocations for
- // storing/retrieving when recording/replaying.
- Error preallocateDeviceMemory(uint64_t DeviceMemorySize) {
- // Pre-allocate memory on device. Starts with 64GB and subtracts in steps
- // of 1GB until allocation succeeds.
- const size_t MAX_MEMORY_ALLOCATION = DeviceMemorySize;
+
+ void *suggestAddress(uint64_t MaxMemoryAllocation) {
+ // Get a valid pointer address for this system
+ void *Addr =
+ Device->allocate(1024, /* HstPtr */ nullptr, TARGET_ALLOC_DEFAULT);
+ Device->free(Addr);
+ // Align Address to MaxMemoryAllocation
+ Addr = (void *)alignPtr((Addr), MaxMemoryAllocation);
+ return Addr;
+ }
+
+ Error preAllocateVAMemory(uint64_t MaxMemoryAllocation, void *VAddr) {
+ size_t ASize = MaxMemoryAllocation;
+
+ if (!VAddr && isRecording()) {
+ VAddr = suggestAddress(MaxMemoryAllocation);
+ }
+
+ DP("Request %ld bytes allocated at %p\n", MaxMemoryAllocation, VAddr);
+
+ if (auto Err = Device->memoryVAMap(&MemoryStart, VAddr, &ASize))
+ return Err;
+
+ if (isReplaying() && VAddr != MemoryStart) {
+ return Plugin::error("Record-Replay cannot assign the"
+ "requested recorded address (%p, %p)",
+ VAddr, MemoryStart);
+ }
+
+ INFO(OMP_INFOTYPE_PLUGIN_KERNEL, Device->getDeviceId(),
+ "Allocated %" PRIu64 " bytes at %p for replay.\n", ASize, MemoryStart);
+
+ MemoryPtr = MemoryStart;
+ MemorySize = 0;
+ TotalSize = ASize;
+ return Plugin::success();
+ }
+
+ Error preAllocateHeuristic(uint64_t MaxMemoryAllocation, void *VAddr) {
+ const size_t MAX_MEMORY_ALLOCATION = MaxMemoryAllocation;
constexpr size_t STEP = 1024 * 1024 * 1024ULL;
MemoryStart = nullptr;
- for (size_t Try = MAX_MEMORY_ALLOCATION; Try > 0; Try -= STEP) {
- MemoryStart =
- Device->allocate(Try, /* HstPtr */ nullptr, TARGET_ALLOC_DEFAULT);
+ for (TotalSize = MAX_MEMORY_ALLOCATION; TotalSize > 0; TotalSize -= STEP) {
+ MemoryStart = Device->allocate(TotalSize, /* HstPtr */ nullptr,
+ TARGET_ALLOC_DEFAULT);
if (MemoryStart)
break;
}
+ INFO(OMP_INFOTYPE_PLUGIN_KERNEL, Device->getDeviceId(),
+ "Allocated %" PRIu64 " bytes at %p for replay.\n", TotalSize,
+ MemoryStart);
+
if (!MemoryStart)
return Plugin::error("Allocating record/replay memory");
+ if (VAddr && VAddr != MemoryStart)
+ return Plugin::error("Cannot allocate recorded address");
+
MemoryPtr = MemoryStart;
MemorySize = 0;
return Plugin::success();
}
+ Error preallocateDeviceMemory(uint64_t DeviceMemorySize, void *ReqVAddr) {
+ if (Device->supportVAManagement())
+ return preAllocateVAMemory(DeviceMemorySize, ReqVAddr);
+
+ uint64_t DevMemSize;
+ if (Device->getDeviceMemorySize(DevMemSize))
+ return Plugin::error("Cannot determine Device Memory Size");
+
+ return preAllocateHeuristic(DevMemSize, ReqVAddr);
+ }
+
void dumpDeviceMemory(StringRef Filename) {
ErrorOr<std::unique_ptr<WritableMemoryBuffer>> DeviceMemoryMB =
WritableMemoryBuffer::getNewUninitMemBuffer(MemorySize);
@@ -114,8 +162,7 @@ struct RecordReplayTy {
bool isSaveOutputEnabled() const { return ReplaySaveOutput; }
RecordReplayTy()
- : Status(RRStatusTy::RRDeactivated), ReplaySaveOutput(false),
- DeviceMemorySize(-1) {}
+ : Status(RRStatusTy::RRDeactivated), ReplaySaveOutput(false) {}
void saveImage(const char *Name, const DeviceImageTy &Image) {
SmallString<128> ImageName = {Name, ".image"};
@@ -197,6 +244,7 @@ struct RecordReplayTy {
JsonKernelInfo["LoopTripCount"] = LoopTripCount;
JsonKernelInfo["DeviceMemorySize"] = MemorySize;
JsonKernelInfo["DeviceId"] = Device->getDeviceId();
+ JsonKernelInfo["BumpAllocVAStart"] = (intptr_t)MemoryStart;
json::Array JsonArgPtrs;
for (int I = 0; I < NumArgs; ++I)
@@ -240,31 +288,37 @@ struct RecordReplayTy {
Alloc = MemoryPtr;
MemoryPtr = (char *)MemoryPtr + AlignedSize;
MemorySize += AlignedSize;
- DP("Memory Allocator return " DPxMOD "\n", DPxPTR(Alloc));
+ DP("Memory Allocator return %p \n", Alloc);
return Alloc;
}
- Error init(GenericDeviceTy *Device, uint64_t MemSize, RRStatusTy Status,
- bool SaveOutput) {
+ Error init(GenericDeviceTy *Device, uint64_t MemSize, void *VAddr,
+ RRStatusTy Status, bool SaveOutput) {
this->Device = Device;
this->Status = Status;
- this->DeviceMemorySize = MemSize;
this->ReplaySaveOutput = SaveOutput;
- if (auto Err = preallocateDeviceMemory(MemSize))
+ if (auto Err = preallocateDeviceMemory(MemSize, VAddr))
return Err;
INFO(OMP_INFOTYPE_PLUGIN_KERNEL, Device->getDeviceId(),
"Record Replay Initialized (%p)"
" as starting address, %lu Memory Size"
" and set on status %s\n",
- MemoryStart, MemSize,
+ MemoryStart, TotalSize,
Status == RRStatusTy::RRRecording ? "Recording" : "Replaying");
return Plugin::success();
}
- void deinit() { Device->free(MemoryStart); }
+ void deinit() {
+ if (Device->supportVAManagement()) {
+ if (auto Err = Device->memoryVAUnMap(MemoryStart, TotalSize))
+ report_fatal_error("Error on releasing virtual memory space");
+ } else {
+ Device->free(MemoryStart);
+ }
+ }
} RecordReplay;
@@ -1204,6 +1258,19 @@ Error GenericDeviceTy::queryAsync(__tgt_async_info *AsyncInfo) {
return queryAsyncImpl(*AsyncInfo);
}
+Error GenericDeviceTy::memoryVAMap(void **Addr, void *VAddr, size_t *RSize) {
+ return Plugin::error("Device does not suppport VA Management");
+}
+
+Error GenericDeviceTy::memoryVAUnMap(void *VAddr, size_t Size) {
+ return Plugin::error("Device does not suppport VA Management");
+}
+
+Error GenericDeviceTy::getDeviceMemorySize(uint64_t &DSize) {
+ return Plugin::error(
+ "Mising getDeviceMemorySize impelmentation (required by RR-heuristic");
+}
+
Expected<void *> GenericDeviceTy::dataAlloc(int64_t Size, void *HostPtr,
TargetAllocTy Kind) {
void *Alloc = nullptr;
@@ -1572,8 +1639,8 @@ int32_t __tgt_rtl_is_data_exchangable(int32_t SrcDeviceId,
return Plugin::get().isDataExchangable(SrcDeviceId, DstDeviceId);
}
-int32_t __tgt_rtl_initialize_record_replay(int32_t DeviceId,
- uint64_t MemorySize, bool isRecord,
+int32_t __tgt_rtl_initialize_record_replay(int32_t DeviceId, int64_t MemorySize,
+ void *VAddr, bool isRecord,
bool SaveOutput) {
GenericPluginTy &Plugin = Plugin::get();
GenericDeviceTy &Device = Plugin.getDevice(DeviceId);
@@ -1581,7 +1648,8 @@ int32_t __tgt_rtl_initialize_record_replay(int32_t DeviceId,
isRecord ? RecordReplayTy::RRStatusTy::RRRecording
: RecordReplayTy::RRStatusTy::RRReplaying;
- if (auto Err = RecordReplay.init(&Device, MemorySize, Status, SaveOutput)) {
+ if (auto Err =
+ RecordReplay.init(&Device, MemorySize, VAddr, Status, SaveOutput)) {
REPORT("WARNING RR did not intialize RR-properly with %lu bytes"
"(Error: %s)\n",
MemorySize, toString(std::move(Err)).data());
diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h
index ddcf3b3cc9b9537..b3261b52e1af3ba 100644
--- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h
+++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h
@@ -647,6 +647,21 @@ struct GenericDeviceTy : public DeviceAllocatorTy {
Error queryAsync(__tgt_async_info *AsyncInfo);
virtual Error queryAsyncImpl(__tgt_async_info &AsyncInfo) = 0;
+ /// Check whether the architecture supports VA management
+ virtual bool supportVAManagement() const { return false; }
+
+ /// Get the total device memory size
+ virtual Error getDeviceMemorySize(uint64_t &DSize);
+
+ /// Allocates \p RSize bytes (rounded up to page size) and hints the driver to
+ /// map it to \p VAddr. The obtained address is stored in \p Addr. At return
+ /// \p RSize contains the actual size which can be equal or larget than the
+ /// requested size.
+ virtual Error memoryVAMap(void **Addr, void *VAddr, size_t *RSize);
+
+ /// De-allocates device memory and unmaps the virtual address \p VAddr
+ virtual Error memoryVAUnMap(void *VAddr, size_t Size);
+
/// Allocate data on the device or involving the device.
Expected<void *> dataAlloc(int64_t Size, void *HostPtr, TargetAllocTy Kind);
diff --git a/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp b/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp
index 2271b3aa90ddd15..3d0de0d5b2caff6 100644
--- a/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp
+++ b/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp
@@ -81,6 +81,16 @@ DLWRAP(cuEventDestroy, 1)
DLWRAP_FINALIZE()
+DLWRAP(cuMemUnmap, 2)
+DLWRAP(cuMemRelease, 1)
+DLWRAP(cuMemAddressFree, 2)
+DLWRAP(cuMemGetInfo, 2)
+DLWRAP(cuMemAddressReserve, 5)
+DLWRAP(cuMemMap, 5)
+DLWRAP(cuMemCreate, 4)
+DLWRAP(cuMemSetAccess, 4)
+DLWRAP(cuMemGetAllocationGranularity, 3)
+
#ifndef DYNAMIC_CUDA_PATH
#define DYNAMIC_CUDA_PATH "libcuda.so"
#endif
diff --git a/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.h b/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.h
index 459236f7ecbd025..3e0307759924b21 100644
--- a/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.h
+++ b/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.h
@@ -26,6 +26,71 @@ typedef struct CUevent_st *CUevent;
#define CU_DEVICE_INVALID ((CUdevice)-2)
+typedef unsigned long long CUmemGenericAllocationHandle_v1;
+typedef CUmemGenericAllocationHandle_v1 CUmemGenericAllocationHandle;
+
+#define CU_DEVICE_INVALID ((CUdevice)-2)
+
+typedef enum CUmemAllocationGranularity_flags_enum {
+ CU_MEM_ALLOC_GRANULARITY_MINIMUM = 0x0,
+ CU_MEM_ALLOC_GRANULARITY_RECOMMENDED = 0x1
+} CUmemAllocationGranularity_flags;
+
+typedef enum CUmemAccess_flags_enum {
+ CU_MEM_ACCESS_FLAGS_PROT_NONE = 0x0,
+ CU_MEM_ACCESS_FLAGS_PROT_READ = 0x1,
+ CU_MEM_ACCESS_FLAGS_PROT_READWRITE = 0x3,
+ CU_MEM_ACCESS_FLAGS_PROT_MAX = 0x7FFFFFFF
+} CUmemAccess_flags;
+
+typedef enum CUmemLocationType_enum {
+ CU_MEM_LOCATION_TYPE_INVALID = 0x0,
+ CU_MEM_LOCATION_TYPE_DEVICE = 0x1,
+ CU_MEM_LOCATION_TYPE_MAX = 0x7FFFFFFF
+} CUmemLocationType;
+
+typedef struct CUmemLocation_st {
+ CUmemLocationType type;
+ int id;
+} CUmemLocation_v1;
+typedef CUmemLocation_v1 CUmemLocation;
+
+typedef struct CUmemAccessDesc_st {
+ CUmemLocation location;
+ CUmemAccess_flags flags;
+} CUmemAccessDesc_v1;
+
+typedef CUmemAccessDesc_v1 CUmemAccessDesc;
+
+typedef enum CUmemAllocationType_enum {
+ CU_MEM_ALLOCATION_TYPE_INVALID = 0x0,
+ CU_MEM_ALLOCATION_TYPE_PINNED = 0x1,
+ CU_MEM_ALLOCATION_TYPE_MAX = 0x7FFFFFFF
+} CUmemAllocationType;
+
+typedef enum CUmemAllocationHandleType_enum {
+ CU_MEM_HANDLE_TYPE_NONE = 0x0,
+ CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR = 0x1,
+ CU_MEM_HANDLE_TYPE_WIN32 = 0x2,
+ CU_MEM_HANDLE_TYPE_WIN32_KMT = 0x4,
+ CU_MEM_HANDLE_TYPE_MAX = 0x7FFFFFFF
+} CUmemAllocationHandleType;
+
+typedef struct CUmemAllocationProp_st {
+ CUmemAllocationType type;
+ CUmemAllocationHandleType requestedHandleTypes;
+ CUmemLocation location;
+
+ void *win32HandleMetaData;
+ struct {
+ unsigned char compressionType;
+ unsigned char gpuDirectRDMACapable;
+ unsigned short usage;
+ unsigned char reserved[4];
+ } allocFlags;
+} CUmemAllocationProp_v1;
+typedef CUmemAllocationProp_v1 CUmemAllocationProp;
+
typedef enum cudaError_enum {
CUDA_SUCCESS = 0,
CUDA_ERROR_INVALID_VALUE = 1,
@@ -268,4 +333,21 @@ CUresult cuStreamWaitEvent(CUstream, CUevent, unsigned int);
CUresult cuEventSynchronize(CUevent);
CUresult cuEventDestroy(CUevent);
+CUresult cuMemUnmap(CUdeviceptr ptr, size_t size);
+CUresult cuMemRelease(CUmemGenericAllocationHandle handle);
+CUresult cuMemAddressFree(CUdeviceptr ptr, size_t size);
+CUresult cuMemGetInfo(size_t *free, size_t *total);
+CUresult cuMemAddressReserve(CUdeviceptr *ptr, size_t size, size_t alignment,
+ CUdeviceptr addr, unsigned long long flags);
+CUresult cuMemMap(CUdeviceptr ptr, size_t size, size_t offset,
+ CUmemGenericAllocationHandle handle,
+ unsigned long long flags);
+CUresult cuMemCreate(CUmemGenericAllocationHandle *handle, size_t size,
+ const CUmemAllocationProp *prop, unsigned long long flags);
+CUresult cuMemSetAccess(CUdeviceptr ptr, size_t size,
+ const CUmemAccessDesc *desc, size_t count);
+CUresult cuMemGetAllocationGranularity(size_t *granularity,
+ const CUmemAllocationProp *prop,
+ CUmemAllocationGranularity_flags option);
+
#endif
diff --git a/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp
index 431e34ca75cd652..9151541749917f5 100644
--- a/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp
+++ b/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp
@@ -519,6 +519,116 @@ struct CUDADeviceTy : public GenericDeviceTy {
return Plugin::check(Res, "Error in cuStreamSynchronize: %s");
}
+ /// CUDA support VA management
+ bool supportVAManagement() const override { return true; }
+
+ /// Allocates \p RSize bytes (rounded up to page size) and hints the cuda
+ /// driver to map it to \p VAddr. The obtained address is stored in \p Addr.
+ /// At return \p RSize contains the actual size
+ Error memoryVAMap(void **Addr, void *VAddr, size_t *RSize) override {
+ CUdeviceptr DVAddr = reinterpret_cast<CUdeviceptr>(VAddr);
+ auto IHandle = DeviceMMaps.find(DVAddr);
+ size_t Size = *RSize;
+
+ if (Size == 0)
+ return Plugin::error("Memory Map Size must be larger than 0");
+
+ // Check if we have already mapped this address
+ if (IHandle != DeviceMMaps.end())
+ return Plugin::error("Address already memory mapped");
+
+ CUmemAllocationProp Prop = {};
+ size_t Granularity = 0;
+
+ size_t Free, Total;
+ CUresult Res = cuMemGetInfo(&Free, &Total);
+ if (auto Err = Plugin::check(Res, "Error in cuMemGetInfo: %s"))
+ return Err;
+
+ if (Size >= Free) {
+ *Addr = nullptr;
+ return Plugin::error(
+ "Canot map memory size larger than the available device memory");
+ }
+
+ // currently NVidia only supports pinned device types
+ Prop.type = CU_MEM_ALLOCATION_TYPE_PINNED;
+ Prop.location.type = CU_MEM_LOCATION_TYPE_DEVICE;
+
+ Prop.location.id = DeviceId;
+ cuMemGetAllocationGranularity(&Granularity, &Prop,
+ CU_MEM_ALLOC_GRANULARITY_MINIMUM);
+ if (auto Err =
+ Plugin::check(Res, "Error in cuMemGetAllocationGranularity: %s"))
+ return Err;
+
+ if (Granularity == 0)
+ return Plugin::error("Wrong device Page size");
+
+ // Ceil to page size.
+ Size = roundUp(Size, Granularity);
+
+ // Create a handler of our allocation
+ CUmemGenericAllocationHandle AHandle;
+ Res = cuMemCreate(&AHandle, Size, &Prop, 0);
+ if (auto Err = Plugin::check(Res, "Error in cuMemCreate: %s"))
+ return Err;
+
+ CUdeviceptr DevPtr = 0;
+ Res = cuMemAddressReserve(&DevPtr, Size, 0, DVAddr, 0);
+ if (auto Err = Plugin::check(Res, "Error in cuMemAddressReserve: %s"))
+ return Err;
+
+ Res = cuMemMap(DevPtr, Size, 0, AHandle, 0);
+ if (auto Err = Plugin::check(Res, "Error in cuMemMap: %s"))
+ return Err;
+
+ CUmemAccessDesc ADesc = {};
+ ADesc.location.type = CU_MEM_LOCATION_TYPE_DEVICE;
+ ADesc.location.id = DeviceId;
+ ADesc.flags = CU_MEM_ACCESS_FLAGS_PROT_READWRITE;
+
+ // Sets address
+ Res = cuMemSetAccess(DevPtr, Size, &ADesc, 1);
+ if (auto Err = Plugin::check(Res, "Error in cuMemSetAccess: %s"))
+ return Err;
+
+ *Addr = reinterpret_cast<void *>(DevPtr);
+ *RSize = Size;
+ DeviceMMaps.insert({DevPtr, AHandle});
+ return Plugin::success();
+ }
+
+ /// De-allocates device memory and Unmaps the Virtual Addr
+ Error memoryVAUnMap(void *VAddr, size_t Size) override {
+ CUdeviceptr DVAddr = reinterpret_cast<CUdevicept...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/70396
More information about the Openmp-commits
mailing list