diff --git a/core/memory_manager/unified_memory_manager.cpp b/core/memory_manager/unified_memory_manager.cpp index 2d70ddd1a5..159c75fc58 100644 --- a/core/memory_manager/unified_memory_manager.cpp +++ b/core/memory_manager/unified_memory_manager.cpp @@ -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, 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); diff --git a/runtime/api/api.cpp b/runtime/api/api.cpp index 55b488a256..00d983e6c7 100644 --- a/runtime/api/api.cpp +++ b/runtime/api/api.cpp @@ -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()); } diff --git a/unit_tests/api/cl_unified_shared_memory_tests.inl b/unit_tests/api/cl_unified_shared_memory_tests.inl index e119610c6e..0fc5e4c867 100644 --- a/unit_tests/api/cl_unified_shared_memory_tests.inl +++ b/unit_tests/api/cl_unified_shared_memory_tests.inl @@ -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); +} diff --git a/unit_tests/memory_manager/unified_memory_manager_tests.cpp b/unit_tests/memory_manager/unified_memory_manager_tests.cpp index 589dc9776c..719c86b0bc 100644 --- a/unit_tests/memory_manager/unified_memory_manager_tests.cpp +++ b/unit_tests/memory_manager/unified_memory_manager_tests.cpp @@ -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());