diff --git a/core/memory_manager/unified_memory_manager.cpp b/core/memory_manager/unified_memory_manager.cpp index 7876d9146c..b474043256 100644 --- a/core/memory_manager/unified_memory_manager.cpp +++ b/core/memory_manager/unified_memory_manager.cpp @@ -92,7 +92,7 @@ void *SVMAllocsManager::createSVMAlloc(size_t size, const SvmAllocationPropertie } } -void *SVMAllocsManager::createUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties memoryProperties) { +void *SVMAllocsManager::createUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties &memoryProperties) { size_t alignedSize = alignUp(size, MemoryConstants::pageSize64k); AllocationProperties unifiedMemoryProperties{true, @@ -107,13 +107,14 @@ void *SVMAllocsManager::createUnifiedMemoryAllocation(size_t size, const Unified allocData.cpuAllocation = nullptr; allocData.size = size; allocData.memoryType = memoryProperties.memoryType; + allocData.allocationFlagsProperty = memoryProperties.allocationFlags; std::unique_lock lock(mtx); this->SVMAllocs.insert(allocData); return reinterpret_cast(unifiedMemoryAllocation->getGpuAddress()); } -void *SVMAllocsManager::createSharedUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties memoryProperties, void *cmdQ) { +void *SVMAllocsManager::createSharedUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties &memoryProperties, void *cmdQ) { auto supportDualStorageSharedMemory = memoryManager->isLocalMemorySupported(); if (DebugManager.flags.AllocateSharedAllocationsWithCpuAndGpuStorage.get() != -1) { @@ -125,6 +126,7 @@ void *SVMAllocsManager::createSharedUnifiedMemoryAllocation(size_t size, const U UNRECOVERABLE_IF(unifiedMemoryPointer == nullptr); auto unifiedMemoryAllocation = this->getSVMAlloc(unifiedMemoryPointer); unifiedMemoryAllocation->memoryType = memoryProperties.memoryType; + unifiedMemoryAllocation->allocationFlagsProperty = memoryProperties.allocationFlags; UNRECOVERABLE_IF(cmdQ == nullptr); auto pageFaultManager = this->memoryManager->getPageFaultManager(); diff --git a/core/memory_manager/unified_memory_manager.h b/core/memory_manager/unified_memory_manager.h index d4740cd68d..9a5630421e 100644 --- a/core/memory_manager/unified_memory_manager.h +++ b/core/memory_manager/unified_memory_manager.h @@ -23,6 +23,7 @@ struct SvmAllocationData { GraphicsAllocation *gpuAllocation = nullptr; size_t size = 0; InternalMemoryType memoryType = InternalMemoryType::SVM; + uint64_t allocationFlagsProperty; }; struct SvmMapOperation { @@ -70,12 +71,13 @@ class SVMAllocsManager { UnifiedMemoryProperties() = default; UnifiedMemoryProperties(InternalMemoryType memoryType) : memoryType(memoryType){}; InternalMemoryType memoryType = InternalMemoryType::NOT_SPECIFIED; + uint64_t allocationFlags = 0; }; SVMAllocsManager(MemoryManager *memoryManager); void *createSVMAlloc(size_t size, const SvmAllocationProperties svmProperties); - void *createUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties svmProperties); - void *createSharedUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties svmProperties, void *cmdQ); + void *createUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties &svmProperties); + void *createSharedUnifiedMemoryAllocation(size_t size, const UnifiedMemoryProperties &svmProperties, void *cmdQ); SvmAllocationData *getSVMAlloc(const void *ptr); bool freeSVMAlloc(void *ptr); size_t getNumAllocs() const { return SVMAllocs.getNumAllocs(); } diff --git a/runtime/api/api.cpp b/runtime/api/api.cpp index 04e0259eaf..06354a5215 100644 --- a/runtime/api/api.cpp +++ b/runtime/api/api.cpp @@ -3407,7 +3407,13 @@ void *clHostMemAllocINTEL( return nullptr; } - return neoContext->getSVMAllocsManager()->createUnifiedMemoryAllocation(size, SVMAllocsManager::UnifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY)); + SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY); + if (!MemObjHelper::parseUnifiedMemoryProperties(properties, unifiedMemoryProperties)) { + err.set(CL_INVALID_VALUE); + return nullptr; + } + + return neoContext->getSVMAllocsManager()->createUnifiedMemoryAllocation(size, unifiedMemoryProperties); } void *clDeviceMemAllocINTEL( @@ -3428,7 +3434,13 @@ void *clDeviceMemAllocINTEL( return nullptr; } - return neoContext->getSVMAllocsManager()->createUnifiedMemoryAllocation(size, SVMAllocsManager::UnifiedMemoryProperties(InternalMemoryType::DEVICE_UNIFIED_MEMORY)); + SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::DEVICE_UNIFIED_MEMORY); + if (!MemObjHelper::parseUnifiedMemoryProperties(properties, unifiedMemoryProperties)) { + err.set(CL_INVALID_VALUE); + return nullptr; + } + + return neoContext->getSVMAllocsManager()->createUnifiedMemoryAllocation(size, unifiedMemoryProperties); } void *clSharedMemAllocINTEL( @@ -3449,7 +3461,13 @@ void *clSharedMemAllocINTEL( return nullptr; } - return neoContext->getSVMAllocsManager()->createSharedUnifiedMemoryAllocation(size, SVMAllocsManager::UnifiedMemoryProperties(InternalMemoryType::SHARED_UNIFIED_MEMORY), neoContext->getSpecialQueue()); + SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::SHARED_UNIFIED_MEMORY); + if (!MemObjHelper::parseUnifiedMemoryProperties(properties, unifiedMemoryProperties)) { + err.set(CL_INVALID_VALUE); + return nullptr; + } + + return neoContext->getSVMAllocsManager()->createSharedUnifiedMemoryAllocation(size, unifiedMemoryProperties, neoContext->getSpecialQueue()); } cl_int clMemFreeINTEL( @@ -3525,6 +3543,10 @@ cl_int clGetMemAllocInfoINTEL( retVal = info.set(unifiedMemoryAllocation->size); return retVal; } + case CL_MEM_ALLOC_FLAGS_INTEL: { + retVal = info.set(unifiedMemoryAllocation->allocationFlagsProperty); + return retVal; + } default: { } } diff --git a/runtime/mem_obj/mem_obj_helper.h b/runtime/mem_obj/mem_obj_helper.h index 3b171ff6be..e832a59167 100644 --- a/runtime/mem_obj/mem_obj_helper.h +++ b/runtime/mem_obj/mem_obj_helper.h @@ -33,6 +33,7 @@ class MemObjHelper { static bool validateMemoryPropertiesForBuffer(const MemoryProperties &properties, cl_mem_flags flags, cl_mem_flags_intel flagsIntel); static bool validateMemoryPropertiesForImage(const MemoryProperties &properties, cl_mem parent); + static bool parseUnifiedMemoryProperties(cl_mem_properties_intel *properties, SVMAllocsManager::UnifiedMemoryProperties &unifiedMemoryProperties); static AllocationProperties getAllocationPropertiesWithImageInfo(ImageInfo &imgInfo, bool allocateMemory, const MemoryPropertiesFlags &memoryProperties); static bool checkMemFlagsForSubBuffer(cl_mem_flags flags); static SVMAllocsManager::SvmAllocationProperties getSvmAllocationProperties(cl_mem_flags flags); diff --git a/runtime/mem_obj/mem_obj_helper_common.inl b/runtime/mem_obj/mem_obj_helper_common.inl index edc28fd4ff..3135a11657 100644 --- a/runtime/mem_obj/mem_obj_helper_common.inl +++ b/runtime/mem_obj/mem_obj_helper_common.inl @@ -67,6 +67,23 @@ bool MemObjHelper::validateMemoryPropertiesForImage(const MemoryProperties &prop return validateExtraMemoryProperties(properties); } +bool MemObjHelper::parseUnifiedMemoryProperties(cl_mem_properties_intel *properties, SVMAllocsManager::UnifiedMemoryProperties &unifiedMemoryProperties) { + uint64_t unifiedMemoryTokenValue = properties ? *properties : 0; + + while (unifiedMemoryTokenValue != 0) { + switch (unifiedMemoryTokenValue) { + case CL_MEM_ALLOC_FLAGS_INTEL: + unifiedMemoryProperties.allocationFlags = properties[1]; + break; + default: + return false; + } + properties += 2; + unifiedMemoryTokenValue = *properties; + } + return true; +} + AllocationProperties MemObjHelper::getAllocationPropertiesWithImageInfo(ImageInfo &imgInfo, bool allocateMemory, const MemoryPropertiesFlags &memoryProperties) { AllocationProperties allocationProperties{allocateMemory, imgInfo, GraphicsAllocation::AllocationType::IMAGE}; MemoryPropertiesParser::fillPoliciesInProperties(allocationProperties, memoryProperties); @@ -103,4 +120,4 @@ const uint64_t MemObjHelper::validFlagsForImage = commonFlags | CL_MEM_NO_ACCESS const uint64_t MemObjHelper::validFlagsForImageIntel = commonFlagsIntel; -} // namespace NEO \ No newline at end of file +} // namespace NEO diff --git a/unit_tests/api/cl_unified_shared_memory_tests.inl b/unit_tests/api/cl_unified_shared_memory_tests.inl index a0476c4123..4ccad769e8 100644 --- a/unit_tests/api/cl_unified_shared_memory_tests.inl +++ b/unit_tests/api/cl_unified_shared_memory_tests.inl @@ -202,6 +202,112 @@ TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithValidUnif EXPECT_EQ(CL_SUCCESS, retVal); } +TEST(clUnifiedSharedMemoryTests, whenHostMemAllocWithInvalidPropertiesTokenThenErrorIsReturned) { + MockContext mockContext; + cl_int retVal = CL_SUCCESS; + cl_mem_properties_intel properties[] = {0x1234, 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; + cl_mem_properties_intel properties[] = {0x1234, CL_MEM_ALLOC_WRITE_COMBINED_INTEL, 0}; + + auto unifiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, 4, 0, &retVal); + + EXPECT_EQ(nullptr, unifiedMemoryDeviceAllocation); + EXPECT_EQ(CL_INVALID_VALUE, retVal); +} + +TEST(clUnifiedSharedMemoryTests, whenSharedMemAllocWithInvalidPropertiesTokenThenErrorIsReturned) { + MockContext mockContext; + cl_int retVal = CL_SUCCESS; + const uint64_t invalidToken = 0x1234; + cl_mem_properties_intel properties[] = {invalidToken, 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; + cl_int retVal = CL_SUCCESS; + size_t paramValueSize = sizeof(cl_mem_properties_intel); + cl_mem_properties_intel paramValue = 0; + size_t paramValueSizeRet = 0; + + auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, 4, 0, &retVal); + + retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemoryHostAllocation, CL_MEM_ALLOC_FLAGS_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); + EXPECT_EQ(defaultValue, paramValue); + EXPECT_EQ(CL_SUCCESS, retVal); + + retVal = clMemFreeINTEL(&mockContext, unifiedMemoryHostAllocation); + EXPECT_EQ(CL_SUCCESS, retVal); +} + +TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocTypeIsCalledWithValidUnifiedMemoryHostAllocationThenProperTypeIsReturned) { + MockContext mockContext; + cl_int retVal = CL_SUCCESS; + 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}; + + auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, properties, 4, 0, &retVal); + + retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemoryHostAllocation, CL_MEM_ALLOC_FLAGS_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); + EXPECT_EQ(properties[1], paramValue); + EXPECT_EQ(CL_SUCCESS, retVal); + + retVal = clMemFreeINTEL(&mockContext, unifiedMemoryHostAllocation); + EXPECT_EQ(CL_SUCCESS, retVal); +} + +TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocTypeIsCalledWithValidUnifiedMemoryDeviceAllocationThenProperTypeIsReturned) { + MockContext mockContext; + cl_int retVal = CL_SUCCESS; + 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}; + + auto unifiedMemoryDeviceAllocation = clDeviceMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, 4, 0, &retVal); + + retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemoryDeviceAllocation, CL_MEM_ALLOC_FLAGS_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); + EXPECT_EQ(properties[1], paramValue); + EXPECT_EQ(CL_SUCCESS, retVal); + + retVal = clMemFreeINTEL(&mockContext, unifiedMemoryDeviceAllocation); + EXPECT_EQ(CL_SUCCESS, retVal); +} + +TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocTypeIsCalledWithValidUnifiedMemorySharedAllocationThenProperTypeIsReturned) { + MockContext mockContext; + cl_int retVal = CL_SUCCESS; + 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}; + + auto unifiedMemorySharedAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), properties, 4, 0, &retVal); + + retVal = clGetMemAllocInfoINTEL(&mockContext, unifiedMemorySharedAllocation, CL_MEM_ALLOC_FLAGS_INTEL, paramValueSize, ¶mValue, ¶mValueSizeRet); + EXPECT_EQ(properties[1], paramValue); + EXPECT_EQ(CL_SUCCESS, retVal); + + retVal = clMemFreeINTEL(&mockContext, unifiedMemorySharedAllocation); + EXPECT_EQ(CL_SUCCESS, retVal); +} + TEST(clUnifiedSharedMemoryTests, whenClGetMemAllocInfoINTELisCalledWithValidUnifiedMemoryDeviceAllocationThenProperFieldsAreSet) { MockContext mockContext; cl_int retVal = CL_SUCCESS;