Add support for write combined in unified memory

Related-To: NEO-3374
Change-Id: I610ad2d71b056f2bc5b8f4bda72e7f08a45cf59d
Signed-off-by: Krzysztof Gibala <krzysztof.gibala@intel.com>
This commit is contained in:
Krzysztof Gibala
2019-12-10 15:33:57 +01:00
committed by sys_ocldev
parent 2c84c143e6
commit 03252ee9fe
4 changed files with 121 additions and 5 deletions

View File

@ -95,9 +95,17 @@ void *SVMAllocsManager::createSVMAlloc(uint32_t rootDeviceIndex, size_t size, co
void *SVMAllocsManager::createUnifiedMemoryAllocation(uint32_t rootDeviceIndex, size_t size, const UnifiedMemoryProperties &memoryProperties) {
size_t alignedSize = alignUp<size_t>(size, MemoryConstants::pageSize64k);
GraphicsAllocation::AllocationType allocationType = GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY;
if (memoryProperties.memoryType == InternalMemoryType::DEVICE_UNIFIED_MEMORY) {
if (memoryProperties.allocationFlags.allocFlags.allocWriteCombined) {
allocationType = GraphicsAllocation::AllocationType::WRITE_COMBINED;
} else {
allocationType = GraphicsAllocation::AllocationType::BUFFER;
}
}
AllocationProperties unifiedMemoryProperties{rootDeviceIndex, true,
alignedSize,
memoryProperties.memoryType == InternalMemoryType::DEVICE_UNIFIED_MEMORY ? GraphicsAllocation::AllocationType::BUFFER : GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY,
allocationType,
false};
GraphicsAllocation *unifiedMemoryAllocation = memoryManager->allocateGraphicsMemoryWithProperties(unifiedMemoryProperties);

View File

@ -3457,6 +3457,11 @@ void *clHostMemAllocINTEL(
return nullptr;
}
if (isValueSet(unifiedMemoryProperties.allocationFlags.allAllocFlags, CL_MEM_ALLOC_WRITE_COMBINED_INTEL)) {
err.set(CL_INVALID_VALUE);
return nullptr;
}
return neoContext->getSVMAllocsManager()->createUnifiedMemoryAllocation(neoContext->getDevice(0)->getRootDeviceIndex(), size, unifiedMemoryProperties);
}
@ -3531,6 +3536,11 @@ void *clSharedMemAllocINTEL(
}
unifiedMemoryProperties.device = device;
if (isValueSet(unifiedMemoryProperties.allocationFlags.allAllocFlags, CL_MEM_ALLOC_WRITE_COMBINED_INTEL)) {
err.set(CL_INVALID_VALUE);
return nullptr;
}
return neoContext->getSVMAllocsManager()->createSharedUnifiedMemoryAllocation(neoContext->getDevice(0)->getRootDeviceIndex(), size, unifiedMemoryProperties, neoContext->getSpecialQueue());
}

View File

@ -230,6 +230,17 @@ TEST(clUnifiedSharedMemoryTests, whenHostMemAllocWithInvalidPropertiesTokenThenE
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST(clUnifiedSharedMemoryTests, whenHostMemAllocWithInvalidWriteCombinedTokenThenErrorIsReturned) {
MockContext mockContext;
cl_int retVal = CL_SUCCESS;
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_WRITE_COMBINED_INTEL, 0};
auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, properties, 4, 0, &retVal);
EXPECT_EQ(nullptr, unifiedMemoryHostAllocation);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST(clUnifiedSharedMemoryTests, whenDeviceMemAllocWithInvalidPropertiesTokenThenErrorIsReturned) {
MockContext mockContext;
cl_int retVal = CL_SUCCESS;
@ -253,6 +264,17 @@ TEST(clUnifiedSharedMemoryTests, whenSharedMemAllocWithInvalidPropertiesTokenThe
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST(clUnifiedSharedMemoryTests, whenSharedMemAllocWithInvalidWriteCombinedTokenThenErrorIsReturned) {
MockContext mockContext;
cl_int retVal = CL_SUCCESS;
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_WRITE_COMBINED_INTEL, 0};
auto unifiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, 4, 0, &retVal);
EXPECT_EQ(nullptr, unifiedMemorySharedAllocation);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST(clUnifiedSharedMemoryTests, givenUnifiedMemoryAllocWithoutPropertiesWhenGetMemAllocFlagsThenDefaultValueIsReturned) {
uint64_t defaultValue = CL_MEM_ALLOC_DEFAULT_INTEL;
MockContext mockContext;
@ -277,7 +299,7 @@ TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocTypeIsCalledWithValidUnifiedMe
size_t paramValueSize = sizeof(cl_mem_properties_intel);
cl_mem_properties_intel paramValue = 0;
size_t paramValueSizeRet = 0;
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_WRITE_COMBINED_INTEL, 0};
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_DEFAULT_INTEL, 0};
auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, properties, 4, 0, &retVal);
@ -313,7 +335,7 @@ TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocTypeIsCalledWithValidUnifiedMe
size_t paramValueSize = sizeof(cl_mem_properties_intel);
cl_mem_properties_intel paramValue = 0;
size_t paramValueSizeRet = 0;
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_WRITE_COMBINED_INTEL, 0};
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_DEFAULT_INTEL, 0};
auto unifiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, 4, 0, &retVal);
@ -760,3 +782,56 @@ TEST_F(clUnifiedSharedMemoryEventTests, whenClEnqueueMemFillINTELIsCalledWithEve
EXPECT_EQ(expectedCmd, actualCmd);
clMemFreeINTEL(this->context, unfiedMemorySharedAllocation);
}
TEST(clUnifiedSharedMemoryTests, givenDefaulMemPropertiesWhenClDeviceMemAllocIntelIsCalledThenItAllocatesDeviceUnifiedMemoryAllocationWithProperAllocationTypeAndSize) {
MockContext mockContext;
cl_int retVal = CL_SUCCESS;
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_DEFAULT_INTEL, 0};
auto allocationSize = 4000u;
auto unfiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, allocationSize, 0, &retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, unfiedMemoryDeviceAllocation);
auto allocationsManager = mockContext.getSVMAllocsManager();
EXPECT_EQ(1u, allocationsManager->getNumAllocs());
auto graphicsAllocation = allocationsManager->getSVMAlloc(unfiedMemoryDeviceAllocation);
EXPECT_EQ(graphicsAllocation->size, allocationSize);
EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::DEVICE_UNIFIED_MEMORY);
EXPECT_EQ(GraphicsAllocation::AllocationType::BUFFER, graphicsAllocation->gpuAllocation->getAllocationType());
EXPECT_EQ(graphicsAllocation->gpuAllocation->getGpuAddress(), castToUint64(unfiedMemoryDeviceAllocation));
EXPECT_EQ(alignUp(allocationSize, MemoryConstants::pageSize64k), graphicsAllocation->gpuAllocation->getUnderlyingBufferSize());
retVal = clMemFreeINTEL(&mockContext, unfiedMemoryDeviceAllocation);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST(clUnifiedSharedMemoryTests, givenValidMemPropertiesWhenClDeviceMemAllocIntelIsCalledThenItAllocatesDeviceUnifiedMemoryAllocationWithProperAllocationTypeAndSize) {
MockContext mockContext;
cl_int retVal = CL_SUCCESS;
auto allocationSize = 4000u;
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_FLAGS_INTEL, CL_MEM_ALLOC_WRITE_COMBINED_INTEL, 0};
auto unfiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, allocationSize, 0, &retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, unfiedMemoryDeviceAllocation);
auto allocationsManager = mockContext.getSVMAllocsManager();
EXPECT_EQ(1u, allocationsManager->getNumAllocs());
auto graphicsAllocation = allocationsManager->getSVMAlloc(unfiedMemoryDeviceAllocation);
EXPECT_EQ(graphicsAllocation->size, allocationSize);
EXPECT_EQ(graphicsAllocation->memoryType, InternalMemoryType::DEVICE_UNIFIED_MEMORY);
EXPECT_EQ(graphicsAllocation->gpuAllocation->getAllocationType(), GraphicsAllocation::AllocationType::WRITE_COMBINED);
EXPECT_EQ(graphicsAllocation->gpuAllocation->getGpuAddress(), castToUint64(unfiedMemoryDeviceAllocation));
EXPECT_EQ(alignUp(allocationSize, MemoryConstants::pageSize64k), graphicsAllocation->gpuAllocation->getUnderlyingBufferSize());
retVal = clMemFreeINTEL(&mockContext, unfiedMemoryDeviceAllocation);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST(clUnifiedSharedMemoryTests, givenInvalidMemPropertiesWhenClSharedMemAllocIntelIsCalledThenInvalidValueIsReturned) {
MockContext mockContext;
cl_int retVal = CL_SUCCESS;
cl_mem_properties_intel properties[] = {CL_MEM_ALLOC_WRITE_COMBINED_INTEL, 0};
auto unfiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, 4, 0, &retVal);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
EXPECT_EQ(nullptr, unfiedMemorySharedAllocation);
}

View File

@ -165,9 +165,33 @@ TEST_F(SVMMemoryAllocatorTest, whenCoherentFlagIsPassedThenAllocationIsCoherent)
svmManager->freeSVMAlloc(ptr);
}
TEST_F(SVMLocalMemoryAllocatorTest, whenDeviceAllocationIsCreatedThenItIsStoredWithProperTypeInAllocationMap) {
TEST_F(SVMLocalMemoryAllocatorTest, whenDeviceAllocationIsCreatedThenItIsStoredWithWriteCombinedTypeInAllocationMap) {
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties;
unifiedMemoryProperties.memoryType = InternalMemoryType::DEVICE_UNIFIED_MEMORY;
unifiedMemoryProperties.allocationFlags.allocFlags.allocWriteCombined = true;
auto allocationSize = 4000u;
auto ptr = svmManager->createUnifiedMemoryAllocation(0, 4000u, unifiedMemoryProperties);
EXPECT_NE(nullptr, ptr);
auto allocation = svmManager->getSVMAlloc(ptr);
EXPECT_EQ(nullptr, allocation->cpuAllocation);
EXPECT_NE(nullptr, allocation->gpuAllocation);
EXPECT_EQ(InternalMemoryType::DEVICE_UNIFIED_MEMORY, allocation->memoryType);
EXPECT_EQ(allocationSize, allocation->size);
EXPECT_EQ(allocation->gpuAllocation->getMemoryPool(), MemoryPool::LocalMemory);
EXPECT_EQ(alignUp(allocationSize, MemoryConstants::pageSize64k), allocation->gpuAllocation->getUnderlyingBufferSize());
EXPECT_EQ(GraphicsAllocation::AllocationType::WRITE_COMBINED, allocation->gpuAllocation->getAllocationType());
svmManager->freeSVMAlloc(ptr);
}
TEST_F(SVMMemoryAllocatorTest, givenNoWriteCombinedFlagwhenDeviceAllocationIsCreatedThenItIsStoredWithProperTypeInAllocationMap) {
if (is32bit) {
GTEST_SKIP();
}
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties;
unifiedMemoryProperties.memoryType = InternalMemoryType::DEVICE_UNIFIED_MEMORY;
unifiedMemoryProperties.allocationFlags.allocFlags.allocWriteCombined = false;
auto allocationSize = 4096u;
auto ptr = svmManager->createUnifiedMemoryAllocation(0, 4096u, unifiedMemoryProperties);
EXPECT_NE(nullptr, ptr);
@ -176,7 +200,6 @@ TEST_F(SVMLocalMemoryAllocatorTest, whenDeviceAllocationIsCreatedThenItIsStoredW
EXPECT_NE(nullptr, allocation->gpuAllocation);
EXPECT_EQ(InternalMemoryType::DEVICE_UNIFIED_MEMORY, allocation->memoryType);
EXPECT_EQ(allocationSize, allocation->size);
EXPECT_EQ(allocation->gpuAllocation->getMemoryPool(), MemoryPool::LocalMemory);
EXPECT_EQ(alignUp(allocationSize, MemoryConstants::pageSize64k), allocation->gpuAllocation->getUnderlyingBufferSize());
EXPECT_EQ(GraphicsAllocation::AllocationType::BUFFER, allocation->gpuAllocation->getAllocationType());