From 8a7bac704866600dcaf3b53d33d14f8c548bf53f Mon Sep 17 00:00:00 2001
From: foreman
Date: Fri, 13 Nov 2015 15:09:15 -0500
Subject: [PATCH] P4 to Git Change 1211165 by gandryey@gera-ubuntu14 on
2015/11/13 14:36:37
SWDEV-78467 - OpenCL LiquidFlash feature
- Add staging transfer support for invisible memory
- Don't fallback to USWC memory if persistent allocation failed
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#262 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuresource.cpp#231 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#390 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.hpp#137 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/command.cpp#73 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/command.hpp#80 edit
---
rocclr/runtime/device/device.hpp | 1 +
rocclr/runtime/device/gpu/gpuresource.cpp | 5 ++-
rocclr/runtime/device/gpu/gpuvirtual.cpp | 26 +++++++++++
rocclr/runtime/device/gpu/gpuvirtual.hpp | 1 +
rocclr/runtime/platform/command.cpp | 54 ++++++++++++++++++-----
rocclr/runtime/platform/command.hpp | 24 +++++-----
6 files changed, 90 insertions(+), 21 deletions(-)
diff --git a/rocclr/runtime/device/device.hpp b/rocclr/runtime/device/device.hpp
index ed23f9979c..db4fdd2229 100644
--- a/rocclr/runtime/device/device.hpp
+++ b/rocclr/runtime/device/device.hpp
@@ -1450,6 +1450,7 @@ public:
/// Optional extensions
virtual void submitSignal(amd::SignalCommand & cmd) = 0;
virtual void submitMakeBuffersResident(amd::MakeBuffersResidentCommand & cmd) = 0;
+ virtual void submitWriteBufferFromFile(amd::WriteBufferFromFileCommand& cmd) { ShouldNotReachHere(); }
//! Get the blit manager object
device::BlitManager& blitMgr() const { return *blitMgr_; }
diff --git a/rocclr/runtime/device/gpu/gpuresource.cpp b/rocclr/runtime/device/gpu/gpuresource.cpp
index b9b47eef54..155ed575ba 100644
--- a/rocclr/runtime/device/gpu/gpuresource.cpp
+++ b/rocclr/runtime/device/gpu/gpuresource.cpp
@@ -445,6 +445,7 @@ Resource::create(MemoryType memType, CreateParams* params)
desc.mipLevels = cal()->mipLevels_;
desc.systemMemory = NULL;
+ uint allocAttempt = 0;
do {
// Find a type for allocation
if (memoryType() == Persistent) {
@@ -515,7 +516,8 @@ Resource::create(MemoryType memType, CreateParams* params)
if (memoryType() == Local) {
cal_.type_ = Persistent;
}
- else if (memoryType() == Persistent) {
+ // Don't switch to USWC if persistent memory was explicitly asked
+ else if ((allocAttempt > 0) && (memoryType() == Persistent)) {
cal_.type_ = RemoteUSWC;
}
// Remote cacheable to uncacheable
@@ -525,6 +527,7 @@ Resource::create(MemoryType memType, CreateParams* params)
else {
break;
}
+ allocAttempt++;
}
}
while (!calRes);
diff --git a/rocclr/runtime/device/gpu/gpuvirtual.cpp b/rocclr/runtime/device/gpu/gpuvirtual.cpp
index 68e5628454..680eee3404 100644
--- a/rocclr/runtime/device/gpu/gpuvirtual.cpp
+++ b/rocclr/runtime/device/gpu/gpuvirtual.cpp
@@ -3491,4 +3491,30 @@ VirtualGPU::assignDebugTrapHandler(const DebugToolInfo& dbgSetting,
}
+void
+VirtualGPU::submitWriteBufferFromFile(amd::WriteBufferFromFileCommand& cmd)
+{
+ size_t copySize = cmd.size()[0];
+ size_t fileOffset = cmd.fileOffset();
+ size_t dstOffset = cmd.origin()[0];
+ Memory* mem = dev().getGpuMemory(&cmd.memory());
+ uint idx = 0;
+ while (copySize > 0) {
+ Memory* staging = dev().getGpuMemory(&cmd.staging(idx));
+ size_t dstSize = amd::WriteBufferFromFileCommand::StagingBufferSize;
+ dstSize = std::min(dstSize, copySize);
+ void* dstBuffer = staging->cpuMap(*this);
+ if (!cmd.file()->readBlock(dstBuffer, fileOffset, 0, dstSize)) {
+ return;
+ }
+ staging->cpuUnmap(*this);
+
+ bool result = blitMgr().copyBuffer(*staging, *mem,
+ fileOffset, dstOffset, dstSize, false);
+ flushDMA(getGpuEvent(staging->gslResource())->engineId_);
+ dstOffset += dstSize;
+ copySize -= dstSize;
+ }
+}
+
} // namespace gpu
diff --git a/rocclr/runtime/device/gpu/gpuvirtual.hpp b/rocclr/runtime/device/gpu/gpuvirtual.hpp
index a2964d24c5..1aabaf5f04 100644
--- a/rocclr/runtime/device/gpu/gpuvirtual.hpp
+++ b/rocclr/runtime/device/gpu/gpuvirtual.hpp
@@ -243,6 +243,7 @@ public:
virtual void submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd);
virtual void submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd);
virtual void submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd);
+ virtual void submitWriteBufferFromFile(amd::WriteBufferFromFileCommand& cmd);
void releaseMemory(gslMemObject gslResource, bool wait = true);
void releaseKernel(CALimage calImage);
diff --git a/rocclr/runtime/platform/command.cpp b/rocclr/runtime/platform/command.cpp
index 217b46ea69..6a250dffc1 100644
--- a/rocclr/runtime/platform/command.cpp
+++ b/rocclr/runtime/platform/command.cpp
@@ -573,27 +573,61 @@ ThreadTraceMemObjectsCommand::validateMemory()
return true;
}
+void
+WriteBufferFromFileCommand::releaseResources()
+{
+ for (uint i = 0; i < NumStagingBuffers; ++i) {
+ if (NULL != staging_[i]) {
+ staging_[i]->release();
+ }
+ }
+
+ // Call the parent
+ OneMemoryArgCommand::releaseResources();
+}
+
void
WriteBufferFromFileCommand::submit(device::VirtualDevice& device)
{
device::Memory* mem = memory_->getDeviceMemory(queue()->device());
- void* dstBuffer = mem->cpuMap(device);
- // Make HD transfer to the host accessible memory
- if (!file()->readBlock(dstBuffer, fileOffset(), origin()[0], size()[0])) {
- return;
+ if (memory_->getMemFlags() & (CL_MEM_USE_HOST_PTR |
+ CL_MEM_ALLOC_HOST_PTR | CL_MEM_USE_PERSISTENT_MEM_AMD)) {
+ void* dstBuffer = mem->cpuMap(device);
+ // Make HD transfer to the host accessible memory
+ if (!file()->readBlock(dstBuffer, fileOffset(), origin()[0], size()[0])) {
+ return;
+ }
+ mem->cpuUnmap(device);
+ }
+ else {
+ device.submitWriteBufferFromFile(*this);
}
- mem->cpuUnmap(device);
}
bool
WriteBufferFromFileCommand::validateMemory()
{
- if (!(memory_->getMemFlags() & (CL_MEM_USE_HOST_PTR |
- CL_MEM_ALLOC_HOST_PTR | CL_MEM_USE_PERSISTENT_MEM_AMD))) {
- return false;
- }
-
if (queue()->device().info().type_ & CL_DEVICE_TYPE_GPU) {
+ // Check if the destination buffer has direct host access
+ if (!(memory_->getMemFlags() & (CL_MEM_USE_HOST_PTR |
+ CL_MEM_ALLOC_HOST_PTR | CL_MEM_USE_PERSISTENT_MEM_AMD))) {
+ // Allocate staging buffers
+ for (uint i = 0; i < NumStagingBuffers; ++i) {
+ staging_[i] = new (memory_->getContext())
+ Buffer(memory_->getContext(),
+ StagingBufferMemType, StagingBufferSize);
+ if (NULL == staging_[i] || !staging_[i]->create(nullptr)) {
+ return false;
+ }
+ device::Memory* mem = staging_[i]->getDeviceMemory(queue()->device());
+ if (NULL == mem) {
+ LogPrintfError("Can't allocate staging buffer - 0x%08X bytes!",
+ staging_[i]->getSize());
+ return false;
+ }
+ }
+ }
+
device::Memory* mem = memory_->getDeviceMemory(queue()->device());
if (NULL == mem) {
LogPrintfError("Can't allocate memory size - 0x%08X bytes!",
diff --git a/rocclr/runtime/platform/command.hpp b/rocclr/runtime/platform/command.hpp
index 4e9a6bd0ef..3ae4d4c379 100644
--- a/rocclr/runtime/platform/command.hpp
+++ b/rocclr/runtime/platform/command.hpp
@@ -1303,8 +1303,6 @@ public:
pfnFreeFunc_(pfnFreeFunc),
userData_(userData) { }
- virtual void releaseResources() { Command::releaseResources(); }
-
virtual void submit(device::VirtualDevice& device)
{
device.submitSvmFreeMemory(*this);
@@ -1338,8 +1336,6 @@ public:
src_(src),
srcSize_(srcSize) { }
- virtual void releaseResources() { Command::releaseResources(); }
-
virtual void submit(device::VirtualDevice& device)
{
device.submitSvmCopyMemory(*this);
@@ -1382,8 +1378,6 @@ public:
memcpy(pattern_, pattern, patternSize);
}
- virtual void releaseResources() { Command::releaseResources(); }
-
virtual void submit(device::VirtualDevice& device)
{
device.submitSvmFillMemory(*this);
@@ -1425,8 +1419,6 @@ public:
{
}
- virtual void releaseResources() { Command::releaseResources(); }
-
virtual void submit(device::VirtualDevice& device)
{
device.submitSvmMapMemory(*this);
@@ -1459,8 +1451,6 @@ public:
svmMem_(svmMem)
{}
- virtual void releaseResources() { Command::releaseResources(); }
-
virtual void submit(device::VirtualDevice& device)
{
device.submitSvmUnmapMemory(*this);
@@ -1477,11 +1467,17 @@ public:
*/
class WriteBufferFromFileCommand : public OneMemoryArgCommand
{
+public:
+ static const uint NumStagingBuffers = 2;
+ static const size_t StagingBufferSize = 4 * Mi;
+ static const uint StagingBufferMemType = CL_MEM_USE_PERSISTENT_MEM_AMD;
+
private:
const Coord3D origin_; //!< Origin of the region to write to
const Coord3D size_; //!< Size of the region to write to
LiquidFlashFile* file_; //!< The file object for data read
size_t fileOffset_; //!< Offset in the file for data read
+ amd::Memory* staging_[NumStagingBuffers]; //!< Staging buffers for transfer
public:
WriteBufferFromFileCommand(
@@ -1498,8 +1494,13 @@ public:
{
// Sanity checks
assert(size.c[0] > 0 && "invalid");
+ for (uint i = 0; i < NumStagingBuffers; ++i) {
+ staging_[i] = NULL;
+ }
}
+ virtual void releaseResources();
+
virtual void submit(device::VirtualDevice& device);
//! Return the memory object to write to
@@ -1516,6 +1517,9 @@ public:
//! Return the region size
const Coord3D& size() const { return size_; }
+ //! Return the staging buffer for transfer
+ Memory& staging(uint i) const { return *staging_[i]; }
+
bool validateMemory();
};