diff --git a/projects/clr/rocclr/runtime/device/cpu/cpudevice.hpp b/projects/clr/rocclr/runtime/device/cpu/cpudevice.hpp index ff958cfd80..e52db18615 100644 --- a/projects/clr/rocclr/runtime/device/cpu/cpudevice.hpp +++ b/projects/clr/rocclr/runtime/device/cpu/cpudevice.hpp @@ -175,7 +175,7 @@ public: return workerThreadsAffinity_; } //! host memory alloc - virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags) const + virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const { return NULL; } diff --git a/projects/clr/rocclr/runtime/device/device.hpp b/projects/clr/rocclr/runtime/device/device.hpp index a7f0eb4965..c427ba2cfc 100644 --- a/projects/clr/rocclr/runtime/device/device.hpp +++ b/projects/clr/rocclr/runtime/device/device.hpp @@ -1624,7 +1624,7 @@ public: /** * @copydoc amd::Context::svmAlloc */ - virtual void* svmAlloc(Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags) const = 0; + virtual void* svmAlloc(Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const = 0; /** * @copydoc amd::Context::svmFree */ diff --git a/projects/clr/rocclr/runtime/device/gpu/gpudevice.cpp b/projects/clr/rocclr/runtime/device/gpu/gpudevice.cpp index cf9b951e01..91369c631a 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpudevice.cpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpudevice.cpp @@ -2467,7 +2467,7 @@ Device::hostFree(void* ptr, size_t size) const } void* -Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags) const +Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const { alignment = std::max(alignment, static_cast(info_.memBaseAddrAlign_)); @@ -2476,25 +2476,34 @@ Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_me alignment = (alignment < vmBigK) ? vmBigK : alignment; size = amd::alignUp(size, alignment); + amd::Memory* mem = NULL; + if (NULL == svmPtr) { + //create a hidden buffer, which will allocated on the device later + mem = new (context)amd::Buffer(context, flags, size, reinterpret_cast(1)); + if (mem == NULL) { + LogError("failed to create a svm mem object!"); + return NULL; + } + + if (!mem->create(NULL, false)) { + LogError("failed to create a svm hidden buffer!"); + mem->release(); + return NULL; + } + gpu::Memory* gpuMem = getGpuMemory(mem); + //add the information to context so that we can use it later. + amd::SvmManager::AddSvmBuffer(mem->getSvmPtr(), mem); - //create a hidden buffer, which will allocated on the device later - amd::Memory* mem = new (context) amd::Buffer(context, flags, size, reinterpret_cast(1)); - if (mem == NULL) { - LogError("failed to create a svm mem object!"); - return NULL; } - - if (!mem->create(NULL, false)) { - LogError("failed to create a svm hidden buffer!"); - mem->release(); - return NULL; + else { + //find the existing amd::mem object + mem = amd::SvmManager::FindSvmBuffer(svmPtr); + if (NULL == mem) { + return NULL; + } + gpu::Memory* gpuMem = getGpuMemory(mem); } - gpu::Memory* gpuMem = getGpuMemory(mem); - - //add the information to context so that we can use it later. - amd::SvmManager::AddSvmBuffer(mem->getSvmPtr(), mem); - return mem->getSvmPtr(); } diff --git a/projects/clr/rocclr/runtime/device/gpu/gpudevice.hpp b/projects/clr/rocclr/runtime/device/gpu/gpudevice.hpp index fd9fb46e19..3776d290a2 100644 --- a/projects/clr/rocclr/runtime/device/gpu/gpudevice.hpp +++ b/projects/clr/rocclr/runtime/device/gpu/gpudevice.hpp @@ -128,7 +128,7 @@ public: //! Get GPU device settings const gpu::Settings& settings() const { return reinterpret_cast(*settings_); } - virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags) const {return NULL;} + virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const { return NULL; } virtual void svmFree(void* ptr) const {return;} protected: @@ -547,7 +547,7 @@ public: virtual void* hostAlloc(size_t size, size_t alignment, bool atomics = false) const; //! SVM allocation - virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags) const; + virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const; //! Free host SVM memory void hostFree(void* ptr, size_t size) const; diff --git a/projects/clr/rocclr/runtime/device/hsa/hsadevice.cpp b/projects/clr/rocclr/runtime/device/hsa/hsadevice.cpp index 9f30a41ad1..4e0aa1b719 100644 --- a/projects/clr/rocclr/runtime/device/hsa/hsadevice.cpp +++ b/projects/clr/rocclr/runtime/device/hsa/hsadevice.cpp @@ -884,7 +884,7 @@ Device::hostFree(void* ptr, size_t size) const } void* -Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags) const +Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const { bool atomics = (flags & CL_MEM_SVM_ATOMICS) != 0; return hostAlloc(size, alignment, atomics); diff --git a/projects/clr/rocclr/runtime/device/hsa/hsadevice.hpp b/projects/clr/rocclr/runtime/device/hsa/hsadevice.hpp index 6bc103b343..e50206bbe2 100644 --- a/projects/clr/rocclr/runtime/device/hsa/hsadevice.hpp +++ b/projects/clr/rocclr/runtime/device/hsa/hsadevice.hpp @@ -149,7 +149,8 @@ public: amd::Context& context, //!< The context used to create a buffer size_t size, //!< size of svm spaces size_t alignment, //!< alignment requirement of svm spaces - cl_svm_mem_flags flags //!< flags of creation svm spaces + cl_svm_mem_flags flags, //!< flags of creation svm spaces + void* svmPtr //!< existing svm pointer for mGPU case ) const { ShouldNotReachHere(); return NULL; @@ -333,7 +334,7 @@ public: virtual void hostFree(void* ptr, size_t size = 0) const; - virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags = CL_MEM_READ_WRITE) const; + virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags = CL_MEM_READ_WRITE, void* svmPtr = NULL) const; virtual void svmFree(void* ptr) const; diff --git a/projects/clr/rocclr/runtime/platform/context.cpp b/projects/clr/rocclr/runtime/platform/context.cpp index 25124ab443..65804772b7 100644 --- a/projects/clr/rocclr/runtime/platform/context.cpp +++ b/projects/clr/rocclr/runtime/platform/context.cpp @@ -307,11 +307,8 @@ Context::svmAlloc(size_t size, size_t alignment, cl_svm_mem_flags flags) for (const auto& dev : svmAllocDevice_) { if (dev->type() == CL_DEVICE_TYPE_GPU) { - tempPtr = dev->svmAlloc(*this, size, alignment, flags); - if (dev == svmAllocDevice_.front()) { - svmPtrAlloced = tempPtr; - } - if ((svmPtrAlloced != tempPtr) || (NULL == tempPtr)) { + svmPtrAlloced = dev->svmAlloc(*this, size, alignment, flags, svmPtrAlloced); + if (svmPtrAlloced == NULL) { return NULL; } }