enable create subBuffer from pooled buffer
Allow creating subBuffer from buffer from buffer pool allocator by redirecting the call to the pool buffer and adjusting offset Related-To: NEO-7332 Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
This commit is contained in:
parent
f06df021b5
commit
d1a6054af9
|
@ -786,14 +786,16 @@ cl_mem CL_API_CALL clCreateSubBuffer(cl_mem buffer,
|
|||
break;
|
||||
}
|
||||
|
||||
if (parentBuffer->isSubBuffer() == true) {
|
||||
if (!parentBuffer->getContext()->getBufferPoolAllocator().isPoolBuffer(parentBuffer->getAssociatedMemObject()) || parentBuffer->isSubBufferFromPool) {
|
||||
retVal = CL_INVALID_MEM_OBJECT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cl_mem_flags parentFlags = parentBuffer->getFlags();
|
||||
cl_mem_flags_intel parentFlagsIntel = parentBuffer->getFlagsIntel();
|
||||
|
||||
if (parentBuffer->isSubBuffer() == true) {
|
||||
retVal = CL_INVALID_MEM_OBJECT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check whether flag is valid. */
|
||||
if (((flags & CL_MEM_HOST_READ_ONLY) && (flags & CL_MEM_HOST_NO_ACCESS)) ||
|
||||
((flags & CL_MEM_HOST_READ_ONLY) && (flags & CL_MEM_HOST_WRITE_ONLY)) ||
|
||||
|
|
|
@ -514,7 +514,7 @@ Buffer *Context::BufferPoolAllocator::allocateBufferFromPool(const MemoryPropert
|
|||
}
|
||||
|
||||
bool Context::BufferPoolAllocator::isPoolBuffer(const MemObj *buffer) const {
|
||||
return this->mainStorage == buffer;
|
||||
return buffer != nullptr && this->mainStorage == buffer;
|
||||
}
|
||||
|
||||
void Context::BufferPoolAllocator::tryFreeFromPoolBuffer(MemObj *possiblePoolBuffer, size_t offset, size_t size) {
|
||||
|
|
|
@ -613,6 +613,14 @@ Buffer *Buffer::createSubBuffer(cl_mem_flags flags,
|
|||
const cl_buffer_region *region,
|
||||
cl_int &errcodeRet) {
|
||||
DEBUG_BREAK_IF(nullptr == createFunction);
|
||||
if (this->context->getBufferPoolAllocator().isPoolBuffer(associatedMemObject)) {
|
||||
Buffer *poolBuffer = static_cast<Buffer *>(associatedMemObject);
|
||||
auto regionWithAdditionalOffset = *region;
|
||||
regionWithAdditionalOffset.origin += this->offset;
|
||||
auto buffer = poolBuffer->createSubBuffer(flags, flagsIntel, ®ionWithAdditionalOffset, errcodeRet);
|
||||
buffer->isSubBufferFromPool = true;
|
||||
return buffer;
|
||||
}
|
||||
MemoryProperties memoryProperties =
|
||||
ClMemoryPropertiesHelper::createMemoryProperties(flags, flagsIntel, 0, &this->context->getDevice(0)->getDevice());
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ class Buffer : public MemObj {
|
|||
constexpr static cl_ulong maskMagic = 0xFFFFFFFFFFFFFFFFLL;
|
||||
constexpr static cl_ulong objectMagic = MemObj::objectMagic | 0x02;
|
||||
bool forceDisallowCPUCopy = false;
|
||||
bool isSubBufferFromPool = false;
|
||||
|
||||
~Buffer() override;
|
||||
|
||||
|
|
|
@ -156,6 +156,9 @@ class MemObj : public BaseObject<_cl_mem> {
|
|||
}
|
||||
return associatedMemObject->getHighestRootMemObj();
|
||||
}
|
||||
MemObj *getAssociatedMemObject() {
|
||||
return associatedMemObject;
|
||||
}
|
||||
|
||||
protected:
|
||||
void getOsSpecificMemObjectInfo(const cl_mem_info ¶mName, size_t *srcParamSize, void **srcParam);
|
||||
|
|
|
@ -325,8 +325,6 @@ TEST_F(aggregatedSmallBuffersEnabledApiTest, givenSubBufferNotFromPoolAndAggrega
|
|||
}
|
||||
|
||||
TEST_F(aggregatedSmallBuffersEnabledApiTest, givenCopyHostPointerWhenCreatingBufferThenUsePoolAndCopyHostPointer) {
|
||||
DebugManagerStateRestore restore;
|
||||
DebugManager.flags.ExperimentalSmallBufferPoolAllocator.set(1);
|
||||
flags |= CL_MEM_COPY_HOST_PTR;
|
||||
unsigned char dataToCopy[PoolAllocator::smallBufferThreshold];
|
||||
dataToCopy[0] = 123;
|
||||
|
@ -355,4 +353,90 @@ TEST_F(aggregatedSmallBuffersEnabledApiTest, givenCopyHostPointerWhenCreatingBuf
|
|||
|
||||
EXPECT_EQ(clReleaseContext(context), CL_SUCCESS);
|
||||
}
|
||||
|
||||
using aggregatedSmallBuffersSubBufferApiTest = aggregatedSmallBuffersEnabledApiTest;
|
||||
|
||||
TEST_F(aggregatedSmallBuffersSubBufferApiTest, givenBufferFromPoolWhenCreateSubBufferCalledThenItSucceeds) {
|
||||
cl_mem notUsedBuffer = clCreateBuffer(clContext, flags, size, hostPtr, &retVal);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
EXPECT_NE(notUsedBuffer, nullptr);
|
||||
|
||||
cl_mem buffer = clCreateBuffer(clContext, flags, size, hostPtr, &retVal);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
ASSERT_NE(buffer, nullptr);
|
||||
MockBuffer *mockBuffer = static_cast<MockBuffer *>(buffer);
|
||||
EXPECT_GT(mockBuffer->offset, 0u);
|
||||
|
||||
cl_buffer_region region{};
|
||||
region.size = 1;
|
||||
region.origin = size / 2;
|
||||
cl_mem subBuffer = clCreateSubBuffer(buffer, flags, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &retVal);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
ASSERT_NE(subBuffer, nullptr);
|
||||
MockBuffer *mockSubBuffer = static_cast<MockBuffer *>(subBuffer);
|
||||
EXPECT_EQ(mockSubBuffer->offset, mockBuffer->offset + region.origin);
|
||||
MockBufferPoolAllocator *mockBufferPoolAllocator = static_cast<MockBufferPoolAllocator *>(&context->getBufferPoolAllocator());
|
||||
EXPECT_EQ(mockSubBuffer->associatedMemObject, mockBufferPoolAllocator->mainStorage);
|
||||
|
||||
retVal = clReleaseMemObject(subBuffer);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
|
||||
retVal = clReleaseMemObject(buffer);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
|
||||
retVal = clReleaseMemObject(notUsedBuffer);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
|
||||
EXPECT_EQ(clReleaseContext(context), CL_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_F(aggregatedSmallBuffersSubBufferApiTest, givenBufferFromPoolWhenCreateSubBufferCalledWithRegionOutsideBufferThenItFails) {
|
||||
cl_mem buffer = clCreateBuffer(clContext, flags, size, hostPtr, &retVal);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
ASSERT_NE(buffer, nullptr);
|
||||
|
||||
cl_buffer_region region{};
|
||||
region.size = size + 1;
|
||||
region.origin = 0;
|
||||
cl_mem subBuffer = clCreateSubBuffer(buffer, flags, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &retVal);
|
||||
EXPECT_EQ(retVal, CL_INVALID_VALUE);
|
||||
EXPECT_EQ(subBuffer, nullptr);
|
||||
|
||||
region.size = 1;
|
||||
region.origin = PoolAllocator::smallBufferThreshold;
|
||||
subBuffer = clCreateSubBuffer(buffer, flags, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &retVal);
|
||||
EXPECT_EQ(retVal, CL_INVALID_VALUE);
|
||||
EXPECT_EQ(subBuffer, nullptr);
|
||||
|
||||
retVal = clReleaseMemObject(buffer);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
|
||||
EXPECT_EQ(clReleaseContext(context), CL_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_F(aggregatedSmallBuffersSubBufferApiTest, givenSubBufferFromBufferFromPoolWhenCreateSubBufferCalledThenItFails) {
|
||||
cl_mem buffer = clCreateBuffer(clContext, flags, size, hostPtr, &retVal);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
ASSERT_NE(buffer, nullptr);
|
||||
|
||||
cl_buffer_region region{};
|
||||
region.size = 1;
|
||||
region.origin = size / 2;
|
||||
cl_mem subBuffer = clCreateSubBuffer(buffer, flags, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &retVal);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
ASSERT_NE(subBuffer, nullptr);
|
||||
|
||||
region.origin = 0;
|
||||
cl_mem subSubBuffer = clCreateSubBuffer(subBuffer, flags, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &retVal);
|
||||
EXPECT_EQ(retVal, CL_INVALID_MEM_OBJECT);
|
||||
EXPECT_EQ(subSubBuffer, nullptr);
|
||||
|
||||
retVal = clReleaseMemObject(subBuffer);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
|
||||
retVal = clReleaseMemObject(buffer);
|
||||
EXPECT_EQ(retVal, CL_SUCCESS);
|
||||
|
||||
EXPECT_EQ(clReleaseContext(context), CL_SUCCESS);
|
||||
}
|
||||
} // namespace Ult
|
Loading…
Reference in New Issue