From 2cd56dc9f090e617a16c99f228b23045c4379dcf Mon Sep 17 00:00:00 2001
From: foreman
Date: Tue, 22 Sep 2015 13:43:05 -0400
Subject: [PATCH] P4 to Git Change 1193093 by xcui@merged_opencl_jxcwin on
2015/09/22 13:29:55
SWDEV-59579 - refactory the Coare-grained SVM and fine grain buffer SVM code path, so that if the device SVM running on supports fine grain system, then the SVM API operation will be on system memory, no need to go through GPU backend. In addition, added support for PX system with CZ on windows 10, which supports SVM fine grain system.
Affected files ...
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_svm.cpp#13 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#256 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.cpp#525 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.hpp#150 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#380 edit
---
rocclr/runtime/device/device.hpp | 4 +-
rocclr/runtime/device/gpu/gpudevice.cpp | 45 +++++--
rocclr/runtime/device/gpu/gpudevice.hpp | 3 +-
rocclr/runtime/device/gpu/gpuvirtual.cpp | 159 ++++++++++++++---------
4 files changed, 132 insertions(+), 79 deletions(-)
diff --git a/rocclr/runtime/device/device.hpp b/rocclr/runtime/device/device.hpp
index 74d551b895..337964b1e2 100644
--- a/rocclr/runtime/device/device.hpp
+++ b/rocclr/runtime/device/device.hpp
@@ -1541,7 +1541,7 @@ public:
inline bool isFineGrainedSystem() const {
return (info().svmCapabilities_ & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM) != 0 ? true : false;
}
-
+
//! Return this device's type.
cl_device_type type() const {
return info().type_ & ~(CL_DEVICE_TYPE_DEFAULT | CL_HSA_ENABLED_AMD
@@ -1623,7 +1623,7 @@ public:
/**
* @copydoc amd::Context::hostAlloc
*/
- virtual void* hostAlloc(size_t size, size_t alignment, bool atomics = false) const
+ virtual void* hostAlloc(size_t size, size_t alignment, bool atomics = false, void* ptr = NULL, bool commit = false) const
{
ShouldNotCallThis();
return NULL;
diff --git a/rocclr/runtime/device/gpu/gpudevice.cpp b/rocclr/runtime/device/gpu/gpudevice.cpp
index f7181fcee0..ca0bf0c63a 100644
--- a/rocclr/runtime/device/gpu/gpudevice.cpp
+++ b/rocclr/runtime/device/gpu/gpudevice.cpp
@@ -2174,10 +2174,14 @@ Device::fillHwSampler(
}
void*
-Device::hostAlloc(size_t size, size_t alignment, bool atomics) const
+Device::hostAlloc(size_t size, size_t alignment, bool atomics, void* ptr, bool commit) const
{
//for discrete gpu, we only reserve,no commit yet.
- return amd::Os::reserveMemory(NULL, size, alignment, amd::Os::MEM_PROT_NONE);
+ void* allocPtr = amd::Os::reserveMemory((address)ptr, size, alignment, amd::Os::MEM_PROT_NONE);
+ if (commit) {
+ amd::Os::commitMemory(allocPtr, size, amd::Os::MEM_PROT_RW);
+ }
+ return allocPtr;
}
void
@@ -2198,7 +2202,13 @@ Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_me
size = amd::alignUp(size, alignment);
amd::Memory* mem = NULL;
+ freeCPUMem_ = false;
if (NULL == svmPtr) {
+ if (isFineGrainedSystem()) {
+ freeCPUMem_ = true;
+ return hostAlloc(size, alignment, false, NULL, true);
+ }
+
//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) {
@@ -2211,10 +2221,12 @@ Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_me
mem->release();
return NULL;
}
+ //if the device supports SVM FGS, return the committed CPU address directly.
gpu::Memory* gpuMem = getGpuMemory(mem);
+
//add the information to context so that we can use it later.
amd::SvmManager::AddSvmBuffer(mem->getSvmPtr(), mem);
-
+ svmPtr = mem->getSvmPtr();
}
else {
//find the existing amd::mem object
@@ -2222,20 +2234,31 @@ Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_me
if (NULL == mem) {
return NULL;
}
- gpu::Memory* gpuMem = getGpuMemory(mem);
+ //commit the CPU memory for FGS device.
+ if (isFineGrainedSystem()) {
+ mem->commitSvmMemory();
+ }
+ else {
+ gpu::Memory* gpuMem = getGpuMemory(mem);
+ }
+ svmPtr = mem->getSvmPtr();
}
-
- return mem->getSvmPtr();
+ return svmPtr;
}
void
Device::svmFree(void *ptr) const
{
- amd::Memory * svmMem = NULL;
- svmMem = amd::SvmManager::FindSvmBuffer(ptr);
- if (NULL != svmMem) {
- svmMem->release();
- amd::SvmManager::RemoveSvmBuffer(ptr);
+ if (freeCPUMem_) {
+ hostFree(ptr, 0);
+ }
+ else {
+ amd::Memory * svmMem = NULL;
+ svmMem = amd::SvmManager::FindSvmBuffer(ptr);
+ if (NULL != svmMem) {
+ svmMem->release();
+ amd::SvmManager::RemoveSvmBuffer(ptr);
+ }
}
}
diff --git a/rocclr/runtime/device/gpu/gpudevice.hpp b/rocclr/runtime/device/gpu/gpudevice.hpp
index 9a7c43853a..6b041794cd 100644
--- a/rocclr/runtime/device/gpu/gpudevice.hpp
+++ b/rocclr/runtime/device/gpu/gpudevice.hpp
@@ -553,7 +553,7 @@ public:
) const;
//! host memory alloc
- virtual void* hostAlloc(size_t size, size_t alignment, bool atomics = false) const;
+ virtual void* hostAlloc(size_t size, size_t alignment, bool atomics = false, void* ptr = NULL, bool commit = false) const;
//! SVM allocation
virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const;
@@ -623,6 +623,7 @@ private:
SrdManager* srdManager_; //!< SRD manager object
static AppProfile appProfile_; //!< application profile
+ mutable bool freeCPUMem_; //!< flag to mark GPU free SVM CPU mem
};
/*@}*/} // namespace gpu
diff --git a/rocclr/runtime/device/gpu/gpuvirtual.cpp b/rocclr/runtime/device/gpu/gpuvirtual.cpp
index 6cc3eae985..895e84b4c2 100644
--- a/rocclr/runtime/device/gpu/gpuvirtual.cpp
+++ b/rocclr/runtime/device/gpu/gpuvirtual.cpp
@@ -1013,35 +1013,43 @@ VirtualGPU::submitSvmCopyMemory(amd::SvmCopyMemoryCommand& vcmd)
profilingBegin(vcmd);
cl_command_type type = vcmd.type();
- amd::Memory* srcMem = amd::SvmManager::FindSvmBuffer(vcmd.src());
- amd::Memory* dstMem = amd::SvmManager::FindSvmBuffer(vcmd.dst());
- if (NULL == srcMem || NULL == dstMem) {
- vcmd.setStatus(CL_INVALID_OPERATION);
- return;
+ //no op for FGS supported device
+ if (!dev().isFineGrainedSystem()) {
+
+ amd::Memory* srcMem = amd::SvmManager::FindSvmBuffer(vcmd.src());
+ amd::Memory* dstMem = amd::SvmManager::FindSvmBuffer(vcmd.dst());
+ if (NULL == srcMem || NULL == dstMem) {
+ vcmd.setStatus(CL_INVALID_OPERATION);
+ return;
+ }
+
+ amd::Coord3D srcOrigin(0, 0, 0);
+ amd::Coord3D dstOrigin(0, 0, 0);
+ amd::Coord3D size(vcmd.srcSize(), 1, 1);
+ amd::BufferRect srcRect;
+ amd::BufferRect dstRect;
+
+ srcOrigin.c[0] = static_cast(vcmd.src()) - static_cast(srcMem->getSvmPtr());
+ dstOrigin.c[0] = static_cast(vcmd.dst()) - static_cast(dstMem->getSvmPtr());
+
+ if (!(srcMem->validateRegion(srcOrigin, size)) || !(dstMem->validateRegion(dstOrigin, size))) {
+ vcmd.setStatus(CL_INVALID_OPERATION);
+ return;
+ }
+
+ bool entire = srcMem->isEntirelyCovered(srcOrigin, size) &&
+ dstMem->isEntirelyCovered(dstOrigin, size);
+
+ if (!copyMemory(type, *srcMem, *dstMem, entire,
+ srcOrigin, dstOrigin, size, srcRect, dstRect)) {
+ vcmd.setStatus(CL_INVALID_OPERATION);
+ }
}
+ else {
+ //direct memcpy for FGS enabled system
+ memcpy(vcmd.dst(), vcmd.src(), vcmd.srcSize());
- amd::Coord3D srcOrigin(0, 0, 0);
- amd::Coord3D dstOrigin(0, 0, 0);
- amd::Coord3D size(vcmd.srcSize(), 1, 1);
- amd::BufferRect srcRect;
- amd::BufferRect dstRect;
-
- srcOrigin.c[0] = static_cast(vcmd.src()) - static_cast(srcMem->getSvmPtr());
- dstOrigin.c[0] = static_cast(vcmd.dst()) - static_cast(dstMem->getSvmPtr());
-
- if (!(srcMem->validateRegion(srcOrigin, size)) || !(dstMem->validateRegion(dstOrigin, size))) {
- vcmd.setStatus(CL_INVALID_OPERATION);
- return;
}
-
- bool entire = srcMem->isEntirelyCovered(srcOrigin, size) &&
- dstMem->isEntirelyCovered(dstOrigin, size);
-
- if (!copyMemory(type, *srcMem, *dstMem, entire,
- srcOrigin, dstOrigin, size, srcRect, dstRect)) {
- vcmd.setStatus(CL_INVALID_OPERATION);
- }
-
profilingEnd(vcmd);
}
@@ -1353,25 +1361,28 @@ VirtualGPU::submitSvmMapMemory(amd::SvmMapMemoryCommand& vcmd)
profilingBegin(vcmd, true);
- // Make sure we have memory for the command execution
- gpu::Memory* memory = dev().getGpuMemory(vcmd.getSvmMem());
+ //no op for FGS supported device
+ if (!dev().isFineGrainedSystem()) {
+ // Make sure we have memory for the command execution
+ gpu::Memory* memory = dev().getGpuMemory(vcmd.getSvmMem());
- memory->saveMapInfo(vcmd.origin(), vcmd.size(),
- vcmd.mapFlags(), vcmd.isEntireMemory());
+ memory->saveMapInfo(vcmd.origin(), vcmd.size(),
+ vcmd.mapFlags(), vcmd.isEntireMemory());
- if (memory->mapMemory() != NULL) {
- if (vcmd.mapFlags() & (CL_MAP_READ | CL_MAP_WRITE)) {
- amd::Coord3D dstOrigin(0, 0, 0);
- assert(memory->cal()->buffer_ && "SVM memory can't be an image");
- if (!blitMgr().copyBuffer(*memory, *memory->mapMemory(),
- vcmd.origin(), dstOrigin, vcmd.size(), vcmd.isEntireMemory())) {
- LogError("submitSVMMapMemory() - copy failed");
- vcmd.setStatus(CL_MAP_FAILURE);
+ if (memory->mapMemory() != NULL) {
+ if (vcmd.mapFlags() & (CL_MAP_READ | CL_MAP_WRITE)) {
+ amd::Coord3D dstOrigin(0, 0, 0);
+ assert(memory->cal()->buffer_ && "SVM memory can't be an image");
+ if (!blitMgr().copyBuffer(*memory, *memory->mapMemory(),
+ vcmd.origin(), dstOrigin, vcmd.size(), vcmd.isEntireMemory())) {
+ LogError("submitSVMMapMemory() - copy failed");
+ vcmd.setStatus(CL_MAP_FAILURE);
+ }
}
}
- }
- else {
- LogError("Unhandled svm map!");
+ else {
+ LogError("Unhandled svm map!");
+ }
}
profilingEnd(vcmd);
@@ -1384,18 +1395,21 @@ VirtualGPU::submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& vcmd)
amd::ScopedLock lock(execution());
profilingBegin(vcmd, true);
- gpu::Memory* memory = dev().getGpuMemory(vcmd.getSvmMem());
+ //no op for FGS supported device
+ if (!dev().isFineGrainedSystem()) {
- if (memory->mapMemory() != NULL) {
- if (memory->isUnmapWrite()) {
- amd::Coord3D srcOrigin(0, 0, 0);
- // Target is a remote resource, so copy
- assert(memory->cal()->buffer_ && "SVM memory can't be an image");
- if (!blitMgr().copyBuffer(*memory->mapMemory(), *memory, srcOrigin,
- memory->writeMapInfo()->origin_, memory->writeMapInfo()->region_,
- memory->writeMapInfo()->entire_)) {
- LogError("submitSvmUnmapMemory() - copy failed");
- vcmd.setStatus(CL_OUT_OF_RESOURCES);
+ gpu::Memory* memory = dev().getGpuMemory(vcmd.getSvmMem());
+ if (memory->mapMemory() != NULL) {
+ if (memory->isUnmapWrite()) {
+ amd::Coord3D srcOrigin(0, 0, 0);
+ // Target is a remote resource, so copy
+ assert(memory->cal()->buffer_ && "SVM memory can't be an image");
+ if (!blitMgr().copyBuffer(*memory->mapMemory(), *memory, srcOrigin,
+ memory->writeMapInfo()->origin_, memory->writeMapInfo()->region_,
+ memory->writeMapInfo()->entire_)) {
+ LogError("submitSvmUnmapMemory() - copy failed");
+ vcmd.setStatus(CL_OUT_OF_RESOURCES);
+ }
}
}
}
@@ -1411,23 +1425,38 @@ VirtualGPU::submitSvmFillMemory(amd::SvmFillMemoryCommand& vcmd)
profilingBegin(vcmd, true);
- amd::Memory* dstMemory = amd::SvmManager::FindSvmBuffer(vcmd.dst());
- assert(dstMemory&&"No svm Buffer to fill with!");
- size_t offset = reinterpret_cast(vcmd.dst())
- - reinterpret_cast(dstMemory->getSvmPtr());
- assert((offset >= 0)&&"wrong svm ptr to fill with!");
+ size_t patternSize = vcmd.patternSize();
+ size_t fillSize = patternSize * vcmd.times();
+ size_t offset = 0;
- gpu::Memory* memory = dev().getGpuMemory(dstMemory);
- size_t fillSize = vcmd.patternSize() * vcmd.times();
+ if (!dev().isFineGrainedSystem()) {
+ amd::Memory* dstMemory = amd::SvmManager::FindSvmBuffer(vcmd.dst());
+ assert(dstMemory&&"No svm Buffer to fill with!");
+ offset = reinterpret_cast(vcmd.dst())
+ - reinterpret_cast(dstMemory->getSvmPtr());
+ assert((offset >= 0) && "wrong svm ptr to fill with!");
- amd::Coord3D origin(offset, 0, 0);
- amd::Coord3D size(fillSize, 1, 1);
- assert((dstMemory->validateRegion(origin, size))&&"The incorrect fill size!");
+ gpu::Memory* memory = dev().getGpuMemory(dstMemory);
- if (!fillMemory(vcmd.type(), dstMemory, vcmd.pattern(),
- vcmd.patternSize(), origin, size)) {
- vcmd.setStatus(CL_INVALID_OPERATION);
+ amd::Coord3D origin(offset, 0, 0);
+ amd::Coord3D size(fillSize, 1, 1);
+ assert((dstMemory->validateRegion(origin, size)) && "The incorrect fill size!");
+
+ if (!fillMemory(vcmd.type(), dstMemory, vcmd.pattern(),
+ vcmd.patternSize(), origin, size)) {
+ vcmd.setStatus(CL_INVALID_OPERATION);
+ }
}
+ else {
+ // for FGS capable device, fill CPU memory directly
+ for (size_t i = 0; i < vcmd.times(); i++) {
+ memcpy(reinterpret_cast(vcmd.dst()) + offset,
+ reinterpret_cast(vcmd.pattern()),
+ patternSize);
+ offset += patternSize;
+ }
+ }
+
profilingEnd(vcmd);
}