From d9cb5925a7405499d66fd3978e9134d52cf63001 Mon Sep 17 00:00:00 2001
From: foreman
Date: Tue, 7 Mar 2017 14:17:43 -0500
Subject: [PATCH] P4 to Git Change 1382437 by gandryey@gera-w8 on 2017/03/07
13:57:15
SWDEV-115242 - [ROCm CQE][OCLonLC][QR][G] ocltst - OCLImage2DFromBuffer results in Segmentation fault
- don't use asImage() virtual method, since coherency layer may require a transfer during object destruction
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.cpp#15 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.hpp#6 edit
[ROCm/clr commit: 6950c861adf4c4d1d2c3ea1a18f939145db6f054]
---
.../rocclr/runtime/device/rocm/rocblit.cpp | 119 +++++++++++-------
.../rocclr/runtime/device/rocm/rocblit.hpp | 4 +
2 files changed, 78 insertions(+), 45 deletions(-)
diff --git a/projects/clr/rocclr/runtime/device/rocm/rocblit.cpp b/projects/clr/rocclr/runtime/device/rocm/rocblit.cpp
index db57bc622c..2179ed658a 100644
--- a/projects/clr/rocclr/runtime/device/rocm/rocblit.cpp
+++ b/projects/clr/rocclr/runtime/device/rocm/rocblit.cpp
@@ -949,7 +949,8 @@ KernelBlitManager::copyBufferToImage(
static const bool CopyRect = false;
// Flush DMA for ASYNC copy
static const bool FlushDMA = true;
- size_t imgRowPitch = size[0] * gpuMem(dstMemory).owner()->asImage()->getImageFormat().getElementSize();
+ amd::Image* dstImage = static_cast(dstMemory.owner());
+ size_t imgRowPitch = size[0] * dstImage->getImageFormat().getElementSize();
size_t imgSlicePitch = imgRowPitch * size[1];
if (setup_.disableCopyBufferToImage_) {
@@ -992,7 +993,8 @@ CalcRowSlicePitches(
cl_ulong* pitch, const cl_int* copySize,
size_t rowPitch, size_t slicePitch, const Memory& mem)
{
- uint32_t memFmtSize = mem.owner()->asImage()->getImageFormat().getElementSize();
+ amd::Image* image = static_cast(mem.owner());
+ uint32_t memFmtSize = image->getImageFormat().getElementSize();
bool img1Darray = (mem.owner()->getType() == CL_MEM_OBJECT_IMAGE1D_ARRAY) ? true : false;
if (rowPitch == 0) {
@@ -1015,7 +1017,7 @@ CalcRowSlicePitches(
}
}
-static void
+static inline void
setArgument(amd::Kernel* kernel, size_t index, size_t size, const void* value)
{
kernel->parameters().set(index, size, value);
@@ -1036,7 +1038,9 @@ KernelBlitManager::copyBufferToImageKernel(
Memory* dstView = &gpuMem(dstMemory);
bool releaseView = false;
bool result = false;
- amd::Image::Format newFormat(gpuMem(dstMemory).owner()->asImage()->getImageFormat());
+ amd::Image* dstImage = static_cast(dstMemory.owner());
+ amd::Image* srcImage = static_cast(srcMemory.owner());
+ amd::Image::Format newFormat(dstImage->getImageFormat());
// Find unsupported formats
for (uint i = 0; i < RejectedFormatDataTotal; ++i) {
@@ -1059,8 +1063,7 @@ KernelBlitManager::copyBufferToImageKernel(
// If the image format was rejected, then attempt to create a view
if (rejected &&
// todo ROC runtime has a problem with a view for this format
- (gpuMem(dstMemory).owner()->asImage()->
- getImageFormat().image_channel_data_type != CL_UNORM_INT_101010)) {
+ (dstImage->getImageFormat().image_channel_data_type != CL_UNORM_INT_101010)) {
dstView = createView(gpuMem(dstMemory), newFormat, CL_MEM_WRITE_ONLY);
if (dstView != NULL) {
rejected = false;
@@ -1084,14 +1087,14 @@ KernelBlitManager::copyBufferToImageKernel(
// Program the kernels workload depending on the blit dimensions
dim = 3;
- if (dstMemory.owner()->asImage()->getDims() == 1) {
+ if (dstImage->getDims() == 1) {
globalWorkSize[0] = amd::alignUp(size[0], 256);
globalWorkSize[1] = amd::alignUp(size[1], 1);
globalWorkSize[2] = amd::alignUp(size[2], 1);
localWorkSize[0] = 256;
localWorkSize[1] = localWorkSize[2] = 1;
}
- else if (dstMemory.owner()->asImage()->getDims() == 2) {
+ else if (dstImage->getDims() == 2) {
globalWorkSize[0] = amd::alignUp(size[0], 16);
globalWorkSize[1] = amd::alignUp(size[1], 16);
globalWorkSize[2] = amd::alignUp(size[2], 1);
@@ -1111,8 +1114,8 @@ KernelBlitManager::copyBufferToImageKernel(
setArgument(kernels_[blitType], 0, sizeof(cl_mem), &mem);
mem = as_cl(dstView->owner());
setArgument(kernels_[blitType], 1, sizeof(cl_mem), &mem);
- uint32_t memFmtSize = dstMemory.owner()->asImage()->getImageFormat().getElementSize();
- uint32_t components = dstMemory.owner()->asImage()->getImageFormat().getNumChannels();
+ uint32_t memFmtSize = dstImage->getImageFormat().getElementSize();
+ uint32_t components = dstImage->getImageFormat().getNumChannels();
// 1 element granularity for writes by default
cl_int granularity = 1;
@@ -1156,10 +1159,9 @@ KernelBlitManager::copyBufferToImageKernel(
globalWorkOffset, globalWorkSize, localWorkSize);
// Execute the blit
- address parameters = kernels_[blitType]->parameters().capture(dev());
+ address parameters = captureArguments(kernels_[blitType]);
result = gpu().submitKernelInternal(ndrange, *kernels_[blitType], parameters, NULL);
- kernels_[blitType]->parameters().release(const_cast(parameters), dev());
-
+ releaseArguments(parameters);
if (releaseView) {
// todo SRD programming could be changed to avoid a stall
gpu().releaseGpuMemoryFence();
@@ -1185,7 +1187,8 @@ KernelBlitManager::copyImageToBuffer(
static const bool CopyRect = false;
// Flush DMA for ASYNC copy
static const bool FlushDMA = true;
- size_t imgRowPitch = size[0] * gpuMem(srcMemory).owner()->asImage()->getImageFormat().getElementSize();
+ amd::Image* srcImage = static_cast(srcMemory.owner());
+ size_t imgRowPitch = size[0] * srcImage->getImageFormat().getElementSize();
size_t imgSlicePitch = imgRowPitch * size[1];
if (setup_.disableCopyImageToBuffer_) {
@@ -1240,7 +1243,8 @@ KernelBlitManager::copyImageToBufferKernel(
Memory* srcView = &gpuMem(srcMemory);
bool releaseView = false;
bool result = false;
- amd::Image::Format newFormat(gpuMem(srcMemory).owner()->asImage()->getImageFormat());
+ amd::Image* srcImage = static_cast(srcMemory.owner());
+ amd::Image::Format newFormat(srcImage->getImageFormat());
// Find unsupported formats
for (uint i = 0; i < RejectedFormatDataTotal; ++i) {
@@ -1263,8 +1267,7 @@ KernelBlitManager::copyImageToBufferKernel(
// If the image format was rejected, then attempt to create a view
if (rejected &&
// todo ROC runtime has a problem with a view for this format
- (gpuMem(srcMemory).owner()->asImage()->
- getImageFormat().image_channel_data_type != CL_UNORM_INT_101010)) {
+ (srcImage->getImageFormat().image_channel_data_type != CL_UNORM_INT_101010)) {
srcView = createView(gpuMem(srcMemory), newFormat, CL_MEM_READ_ONLY);
if (srcView != NULL) {
rejected = false;
@@ -1288,14 +1291,14 @@ KernelBlitManager::copyImageToBufferKernel(
// Program the kernels workload depending on the blit dimensions
dim = 3;
// Find the current blit type
- if (srcMemory.owner()->asImage()->getDims() == 1) {
+ if (srcImage->getDims() == 1) {
globalWorkSize[0] = amd::alignUp(size[0], 256);
globalWorkSize[1] = amd::alignUp(size[1], 1);
globalWorkSize[2] = amd::alignUp(size[2], 1);
localWorkSize[0] = 256;
localWorkSize[1] = localWorkSize[2] = 1;
}
- else if (srcMemory.owner()->asImage()->getDims() == 2) {
+ else if (srcImage->getDims() == 2) {
globalWorkSize[0] = amd::alignUp(size[0], 16);
globalWorkSize[1] = amd::alignUp(size[1], 16);
globalWorkSize[2] = amd::alignUp(size[2], 1);
@@ -1329,8 +1332,8 @@ KernelBlitManager::copyImageToBufferKernel(
(cl_int)size[1],
(cl_int)size[2], 0 };
setArgument(kernels_[blitType], 4, sizeof(srcOrg), srcOrg);
- uint32_t memFmtSize = srcMemory.owner()->asImage()->getImageFormat().getElementSize();
- uint32_t components = srcMemory.owner()->asImage()->getImageFormat().getNumChannels();
+ uint32_t memFmtSize = srcImage->getImageFormat().getElementSize();
+ uint32_t components = srcImage->getImageFormat().getNumChannels();
// 1 element granularity for writes by default
cl_int granularity = 1;
@@ -1365,9 +1368,9 @@ KernelBlitManager::copyImageToBufferKernel(
globalWorkOffset, globalWorkSize, localWorkSize);
// Execute the blit
- address parameters = kernels_[blitType]->parameters().capture(dev());
+ address parameters = captureArguments(kernels_[blitType]);
result = gpu().submitKernelInternal(ndrange, *kernels_[blitType], parameters, NULL);
- kernels_[blitType]->parameters().release(const_cast(parameters), dev());
+ releaseArguments(parameters);
if (releaseView) {
// todo SRD programming could be changed to avoid a stall
gpu().releaseGpuMemoryFence();
@@ -1392,7 +1395,9 @@ KernelBlitManager::copyImage(
Memory* dstView = &gpuMem(dstMemory);
bool releaseView = false;
bool result = false;
- amd::Image::Format newFormat(gpuMem(srcMemory).owner()->asImage()->getImageFormat());
+ amd::Image* srcImage = static_cast(srcMemory.owner());
+ amd::Image* dstImage = static_cast(dstMemory.owner());
+ amd::Image::Format newFormat(srcImage->getImageFormat());
// Find unsupported formats
for (uint i = 0; i < RejectedFormatDataTotal; ++i) {
@@ -1448,16 +1453,16 @@ KernelBlitManager::copyImage(
// Program the kernels workload depending on the blit dimensions
dim = 3;
// Find the current blit type
- if ((srcMemory.owner()->asImage()->getDims() == 1) ||
- (dstMemory.owner()->asImage()->getDims() == 1)) {
+ if ((srcImage->getDims() == 1) ||
+ (dstImage->getDims() == 1)) {
globalWorkSize[0] = amd::alignUp(size[0], 256);
globalWorkSize[1] = amd::alignUp(size[1], 1);
globalWorkSize[2] = amd::alignUp(size[2], 1);
localWorkSize[0] = 256;
localWorkSize[1] = localWorkSize[2] = 1;
}
- else if ((srcMemory.owner()->asImage()->getDims() == 2) ||
- (dstMemory.owner()->asImage()->getDims() == 2)) {
+ else if ((srcImage->getDims() == 2) ||
+ (dstImage->getDims() == 2)) {
globalWorkSize[0] = amd::alignUp(size[0], 16);
globalWorkSize[1] = amd::alignUp(size[1], 16);
globalWorkSize[2] = amd::alignUp(size[2], 1);
@@ -1507,9 +1512,9 @@ KernelBlitManager::copyImage(
globalWorkOffset, globalWorkSize, localWorkSize);
// Execute the blit
- address parameters = kernels_[blitType]->parameters().capture(dev());
+ address parameters = captureArguments(kernels_[blitType]);
result = gpu().submitKernelInternal(ndrange, *kernels_[blitType], parameters, NULL);
- kernels_[blitType]->parameters().release(const_cast(parameters), dev());
+ releaseArguments(parameters);
if (releaseView) {
// todo SRD programming could be changed to avoid a stall
gpu().releaseGpuMemoryFence();
@@ -1527,7 +1532,8 @@ FindPinSize(
size_t& pinSize, const amd::Coord3D& size,
size_t& rowPitch, size_t& slicePitch, const Memory& mem)
{
- pinSize = size[0] * mem.owner()->asImage()->getImageFormat().getElementSize();
+ amd::Image* image = static_cast(mem.owner());
+ pinSize = size[0] * image->getImageFormat().getElementSize();
if ((rowPitch == 0) || (rowPitch == pinSize)) {
rowPitch = 0;
}
@@ -1536,7 +1542,7 @@ FindPinSize(
}
// Calculate the pin size, which should be equal to the copy size
- for (uint i = 1; i < mem.owner()->asImage()->getDims(); ++i) {
+ for (uint i = 1; i < image->getDims(); ++i) {
pinSize *= size[i];
if (i == 1) {
if ((slicePitch == 0) || (slicePitch == pinSize)) {
@@ -1782,10 +1788,9 @@ KernelBlitManager::copyBufferRect(
globalWorkOffset, globalWorkSize, localWorkSize);
// Execute the blit
- address parameters = kernels_[blitType]->parameters().capture(dev());
+ address parameters = captureArguments(kernels_[blitType]);
result = gpu().submitKernelInternal(ndrange, *kernels_[blitType], parameters, NULL);
- kernels_[blitType]->parameters().release(const_cast(parameters), dev());
-
+ releaseArguments(parameters);
synchronize();
return result;
@@ -2085,9 +2090,9 @@ KernelBlitManager::fillBuffer(
globalWorkOffset, &globalWorkSize, &localWorkSize);
// Execute the blit
- address parameters = kernels_[fillType]->parameters().capture(dev());
+ address parameters = captureArguments(kernels_[fillType]);
result = gpu().submitKernelInternal(ndrange, *kernels_[fillType], parameters, NULL);
- kernels_[fillType]->parameters().release(const_cast(parameters), dev());
+ releaseArguments(parameters);
}
synchronize();
@@ -2181,9 +2186,9 @@ KernelBlitManager::copyBuffer(
globalWorkOffset, &globalWorkSize, &localWorkSize);
// Execute the blit
- address parameters = kernels_[blitType]->parameters().capture(dev());
+ address parameters = captureArguments(kernels_[blitType]);
result = gpu().submitKernelInternal(ndrange, *kernels_[blitType], parameters, NULL);
- kernels_[blitType]->parameters().release(const_cast(parameters), dev());
+ releaseArguments(parameters);
}
else {
result = DmaBlitManager::copyBuffer(
@@ -2222,7 +2227,8 @@ KernelBlitManager::fillImage(
size_t globalWorkSize[3];
size_t localWorkSize[3];
Memory* memView = &gpuMem(memory);
- amd::Image::Format newFormat(gpuMem(memory).owner()->asImage()->getImageFormat());
+ amd::Image* image = static_cast(memory.owner());
+ amd::Image::Format newFormat(image->getImageFormat());
// Program the kernels workload depending on the fill dimensions
fillType = FillImage;
@@ -2278,14 +2284,14 @@ KernelBlitManager::fillImage(
// Perform workload split to allow multiple operations in a single thread
globalWorkSize[0] = (size[0] + TransferSplitSize - 1) / TransferSplitSize;
// Find the current blit type
- if (memView->owner()->asImage()->getDims() == 1) {
+ if (image->getDims() == 1) {
globalWorkSize[0] = amd::alignUp(globalWorkSize[0], 256);
globalWorkSize[1] = amd::alignUp(size[1], 1);
globalWorkSize[2] = amd::alignUp(size[2], 1);
localWorkSize[0] = 256;
localWorkSize[1] = localWorkSize[2] = 1;
}
- else if (memView->owner()->asImage()->getDims()== 2) {
+ else if (image->getDims()== 2) {
globalWorkSize[0] = amd::alignUp(globalWorkSize[0], 16);
globalWorkSize[1] = amd::alignUp(size[1], 16);
globalWorkSize[2] = amd::alignUp(size[2], 1);
@@ -2348,9 +2354,9 @@ KernelBlitManager::fillImage(
globalWorkOffset, globalWorkSize, localWorkSize);
// Execute the blit
- address parameters = kernels_[fillType]->parameters().capture(dev());
+ address parameters = captureArguments(kernels_[fillType]);
result = gpu().submitKernelInternal(ndrange, *kernels_[fillType], parameters, NULL);
- kernels_[fillType]->parameters().release(const_cast(parameters), dev());
+ releaseArguments(parameters);
if (releaseView) {
// todo SRD programming could be changed to avoid a stall
gpu().releaseGpuMemoryFence();
@@ -2423,7 +2429,8 @@ KernelBlitManager::createView(
cl_mem_flags flags) const
{
assert((parent.owner()->asBuffer() == nullptr) && "View supports images only");
- amd::Image *image = parent.owner()->asImage()->createView(
+ amd::Image* parentImage = static_cast(parent.owner());
+ amd::Image* image = parentImage->createView(
parent.owner()->getContext(), format, &gpu(), 0, flags);
if (image == NULL) {
@@ -2450,4 +2457,26 @@ KernelBlitManager::createView(
return devImage;
}
+address
+KernelBlitManager::captureArguments(const amd::Kernel* kernel) const
+{
+ const size_t stackSize = kernel->signature().paramsSize();
+ const size_t svmInfoSize = kernel->signature().numParameters() * sizeof(bool);
+ address args = reinterpret_cast(amd::AlignedMemory::allocate(
+ stackSize + svmInfoSize, PARAMETERS_MIN_ALIGNMENT));
+ if (args == nullptr) {
+ LogWarning("Failed to allocate memory for arguments");
+ return nullptr;
+ }
+ memcpy(args, kernel->parameters().values(), kernel->signature().paramsSize());
+ memset(args + stackSize, 0, svmInfoSize);
+ return args;
+}
+
+void
+KernelBlitManager::releaseArguments(address args) const
+{
+ amd::AlignedMemory::deallocate(args);
+}
+
} // namespace pal
diff --git a/projects/clr/rocclr/runtime/device/rocm/rocblit.hpp b/projects/clr/rocclr/runtime/device/rocm/rocblit.hpp
index 7a22a42cb9..e425598893 100644
--- a/projects/clr/rocclr/runtime/device/rocm/rocblit.hpp
+++ b/projects/clr/rocclr/runtime/device/rocm/rocblit.hpp
@@ -407,6 +407,7 @@ public:
private:
static const size_t MaxXferBuffers = 2;
static const uint TransferSplitSize = 1;
+ static const uint MaxNumIssuedTransfers = 3;
//! Copies a buffer object to an image object
bool copyBufferToImageKernel(
@@ -444,6 +445,9 @@ private:
cl_mem_flags flags //!< Memory flags
) const;
+ address captureArguments(const amd::Kernel* kernel) const;
+ void releaseArguments(address args) const;
+
//! Disable copy constructor
KernelBlitManager(const KernelBlitManager&);