diff --git a/core/unified_memory/unified_memory.cpp b/core/unified_memory/unified_memory.cpp index 6b707cc1e9..c3cbcdd7ec 100644 --- a/core/unified_memory/unified_memory.cpp +++ b/core/unified_memory/unified_memory.cpp @@ -15,6 +15,9 @@ uint32_t UnifiedMemoryControls::generateMask() { if (this->indirectDeviceAllocationsAllowed) { resourceMask |= InternalMemoryType::DEVICE_UNIFIED_MEMORY; } + if (this->indirectSharedAllocationsAllowed) { + resourceMask |= InternalMemoryType::SHARED_UNIFIED_MEMORY; + } return resourceMask; } diff --git a/core/unified_memory/unified_memory.h b/core/unified_memory/unified_memory.h index 8338b4ef59..3ba4b3af0f 100644 --- a/core/unified_memory/unified_memory.h +++ b/core/unified_memory/unified_memory.h @@ -13,10 +13,12 @@ enum InternalMemoryType : uint32_t { SVM = 0b1, DEVICE_UNIFIED_MEMORY = 0b10, HOST_UNIFIED_MEMORY = 0b100, + SHARED_UNIFIED_MEMORY = 0b1000 }; struct UnifiedMemoryControls { uint32_t generateMask(); bool indirectDeviceAllocationsAllowed = false; bool indirectHostAllocationsAllowed = false; + bool indirectSharedAllocationsAllowed = false; }; diff --git a/core/unit_tests/unified_memory/unified_memory_tests.cpp b/core/unit_tests/unified_memory/unified_memory_tests.cpp index 9c87473dac..682ebee246 100644 --- a/core/unit_tests/unified_memory/unified_memory_tests.cpp +++ b/core/unit_tests/unified_memory/unified_memory_tests.cpp @@ -14,6 +14,7 @@ TEST(UnifiedMemoryTests, givenInternalMemoryTypesThenAllHaveOnlyOneBitSet) { EXPECT_EQ(1u, std::bitset<32>(InternalMemoryType::DEVICE_UNIFIED_MEMORY).count()); EXPECT_EQ(1u, std::bitset<32>(InternalMemoryType::HOST_UNIFIED_MEMORY).count()); + EXPECT_EQ(1u, std::bitset<32>(InternalMemoryType::SHARED_UNIFIED_MEMORY).count()); EXPECT_EQ(1u, std::bitset<32>(InternalMemoryType::SVM).count()); } @@ -29,4 +30,8 @@ TEST(UnifiedMemoryTests, givenUnifiedMemoryControlsWhenDedicatedFieldsAreSetThen controls.indirectDeviceAllocationsAllowed = false; EXPECT_EQ(InternalMemoryType::HOST_UNIFIED_MEMORY, controls.generateMask()); + + controls.indirectHostAllocationsAllowed = false; + controls.indirectSharedAllocationsAllowed = true; + EXPECT_EQ(InternalMemoryType::SHARED_UNIFIED_MEMORY, controls.generateMask()); } diff --git a/runtime/api/api.cpp b/runtime/api/api.cpp index 321dfdccda..df9588b006 100644 --- a/runtime/api/api.cpp +++ b/runtime/api/api.cpp @@ -3988,7 +3988,8 @@ cl_int CL_API_CALL clSetKernelExecInfo(cl_kernel kernel, switch (paramName) { case CL_KERNEL_EXEC_INFO_INDIRECT_DEVICE_ACCESS_INTEL: - case CL_KERNEL_EXEC_INFO_INDIRECT_HOST_ACCESS_INTEL: { + case CL_KERNEL_EXEC_INFO_INDIRECT_HOST_ACCESS_INTEL: + case CL_KERNEL_EXEC_INFO_INDIRECT_SHARED_ACCESS_INTEL: { auto propertyValue = *reinterpret_cast(paramValue); pKernel->setUnifiedMemoryProperty(paramName, propertyValue); } break; diff --git a/runtime/kernel/kernel.cpp b/runtime/kernel/kernel.cpp index 2b4fa1f2fc..276f94c4e8 100644 --- a/runtime/kernel/kernel.cpp +++ b/runtime/kernel/kernel.cpp @@ -950,6 +950,10 @@ void Kernel::setUnifiedMemoryProperty(cl_kernel_exec_info infoType, bool infoVal this->unifiedMemoryControls.indirectHostAllocationsAllowed = infoValue; return; } + if (infoType == CL_KERNEL_EXEC_INFO_INDIRECT_SHARED_ACCESS_INTEL) { + this->unifiedMemoryControls.indirectSharedAllocationsAllowed = infoValue; + return; + } } void Kernel::setUnifiedMemoryExecInfo(GraphicsAllocation *unifiedMemoryAllocation) { @@ -1015,7 +1019,8 @@ void Kernel::makeResident(CommandStreamReceiver &commandStreamReceiver) { gtpinNotifyMakeResident(this, &commandStreamReceiver); if (unifiedMemoryControls.indirectDeviceAllocationsAllowed || - unifiedMemoryControls.indirectHostAllocationsAllowed) { + unifiedMemoryControls.indirectHostAllocationsAllowed || + unifiedMemoryControls.indirectSharedAllocationsAllowed) { this->getContext().getSVMAllocsManager()->makeInternalAllocationsResident(commandStreamReceiver, unifiedMemoryControls.generateMask()); } } diff --git a/unit_tests/kernel/kernel_tests.cpp b/unit_tests/kernel/kernel_tests.cpp index c348cc03fd..63b681aa12 100644 --- a/unit_tests/kernel/kernel_tests.cpp +++ b/unit_tests/kernel/kernel_tests.cpp @@ -1660,6 +1660,26 @@ HWTEST_F(KernelResidencyTest, givenKernelUsingIndirectHostMemoryWhenMakeResident svmAllocationsManager->freeSVMAlloc(unifiedHostMemoryAllocation); } +HWTEST_F(KernelResidencyTest, givenKernelUsingIndirectSharedMemoryWhenMakeResidentIsCalledThenOnlySharedAllocationsAreMadeResident) { + MockKernelWithInternals mockKernel(*this->pDevice); + auto &commandStreamReceiver = this->pDevice->getUltCommandStreamReceiver(); + + auto svmAllocationsManager = mockKernel.mockContext->getSVMAllocsManager(); + auto unifiedSharedMemoryAllocation = svmAllocationsManager->createUnifiedMemoryAllocation(4096u, SVMAllocsManager::UnifiedMemoryProperties(InternalMemoryType::SHARED_UNIFIED_MEMORY)); + auto unifiedHostMemoryAllocation = svmAllocationsManager->createUnifiedMemoryAllocation(4096u, SVMAllocsManager::UnifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY)); + + mockKernel.mockKernel->makeResident(this->pDevice->getCommandStreamReceiver()); + EXPECT_EQ(0u, commandStreamReceiver.getResidencyAllocations().size()); + mockKernel.mockKernel->setUnifiedMemoryProperty(CL_KERNEL_EXEC_INFO_INDIRECT_SHARED_ACCESS_INTEL, true); + + mockKernel.mockKernel->makeResident(this->pDevice->getCommandStreamReceiver()); + EXPECT_EQ(1u, commandStreamReceiver.getResidencyAllocations().size()); + EXPECT_EQ(commandStreamReceiver.getResidencyAllocations()[0]->getGpuAddress(), castToUint64(unifiedSharedMemoryAllocation)); + + svmAllocationsManager->freeSVMAlloc(unifiedSharedMemoryAllocation); + svmAllocationsManager->freeSVMAlloc(unifiedHostMemoryAllocation); +} + HWTEST_F(KernelResidencyTest, givenKernelWhenSetKernelExecInfoWithUnifiedMemoryIsCalledThenAllocationIsStoredWithinKernel) { MockKernelWithInternals mockKernel(*this->pDevice); auto &commandStreamReceiver = this->pDevice->getUltCommandStreamReceiver(); @@ -1706,6 +1726,7 @@ HWTEST_F(KernelResidencyTest, givenKernelWhenclSetKernelExecInfoWithUnifiedMemor svmAllocationsManager->freeSVMAlloc(unifiedMemoryAllocation); svmAllocationsManager->freeSVMAlloc(unifiedMemoryAllocation2); } + HWTEST_F(KernelResidencyTest, givenKernelWhenclSetKernelExecInfoWithUnifiedMemoryDevicePropertyIsCalledThenKernelControlIsChanged) { MockKernelWithInternals mockKernel(*this->pDevice); cl_bool enableIndirectDeviceAccess = CL_TRUE; @@ -1730,6 +1751,18 @@ HWTEST_F(KernelResidencyTest, givenKernelWhenclSetKernelExecInfoWithUnifiedMemor EXPECT_FALSE(mockKernel.mockKernel->unifiedMemoryControls.indirectHostAllocationsAllowed); } +HWTEST_F(KernelResidencyTest, givenKernelWhenclSetKernelExecInfoWithUnifiedMemorySharedPropertyIsCalledThenKernelControlIsChanged) { + MockKernelWithInternals mockKernel(*this->pDevice); + cl_bool enableIndirectSharedAccess = CL_TRUE; + auto status = clSetKernelExecInfo(mockKernel.mockKernel, CL_KERNEL_EXEC_INFO_INDIRECT_SHARED_ACCESS_INTEL, sizeof(cl_bool), &enableIndirectSharedAccess); + EXPECT_EQ(CL_SUCCESS, status); + EXPECT_TRUE(mockKernel.mockKernel->unifiedMemoryControls.indirectSharedAllocationsAllowed); + enableIndirectSharedAccess = CL_FALSE; + status = clSetKernelExecInfo(mockKernel.mockKernel, CL_KERNEL_EXEC_INFO_INDIRECT_SHARED_ACCESS_INTEL, sizeof(cl_bool), &enableIndirectSharedAccess); + EXPECT_EQ(CL_SUCCESS, status); + EXPECT_FALSE(mockKernel.mockKernel->unifiedMemoryControls.indirectSharedAllocationsAllowed); +} + TEST(KernelImageDetectionTests, givenKernelWithImagesOnlyWhenItIsAskedIfItHasImagesOnlyThenTrueIsReturned) { auto pKernelInfo = std::make_unique(); pKernelInfo->kernelArgInfo.resize(3); diff --git a/unit_tests/memory_manager/svm_memory_manager_tests.cpp b/unit_tests/memory_manager/svm_memory_manager_tests.cpp index f02653e873..dc2be8bb38 100644 --- a/unit_tests/memory_manager/svm_memory_manager_tests.cpp +++ b/unit_tests/memory_manager/svm_memory_manager_tests.cpp @@ -179,6 +179,25 @@ TEST_F(SVMMemoryAllocatorTest, whenHostAllocationIsCreatedThenItIsStoredWithProp svmManager->freeSVMAlloc(ptr); } +TEST_F(SVMMemoryAllocatorTest, whenSharedAllocationIsCreatedThenItIsStoredWithProperTypeInAllocationMap) { + SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties; + unifiedMemoryProperties.memoryType = InternalMemoryType::SHARED_UNIFIED_MEMORY; + auto allocationSize = 4096u; + auto ptr = svmManager->createUnifiedMemoryAllocation(4096u, unifiedMemoryProperties); + EXPECT_NE(nullptr, ptr); + auto allocation = svmManager->getSVMAlloc(ptr); + EXPECT_EQ(nullptr, allocation->cpuAllocation); + EXPECT_NE(nullptr, allocation->gpuAllocation); + EXPECT_EQ(InternalMemoryType::SHARED_UNIFIED_MEMORY, allocation->memoryType); + EXPECT_EQ(allocationSize, allocation->size); + + EXPECT_EQ(alignUp(allocationSize, MemoryConstants::pageSize64k), allocation->gpuAllocation->getUnderlyingBufferSize()); + EXPECT_EQ(GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY, allocation->gpuAllocation->getAllocationType()); + EXPECT_NE(allocation->gpuAllocation->getMemoryPool(), MemoryPool::LocalMemory); + EXPECT_NE(nullptr, allocation->gpuAllocation->getUnderlyingBuffer()); + svmManager->freeSVMAlloc(ptr); +} + TEST(SvmAllocationPropertiesTests, givenDifferentMemFlagsWhenGettingSvmAllocationPropertiesThenPropertiesAreCorrectlySet) { SVMAllocsManager::SvmAllocationProperties allocationProperties = MemObjHelper::getSvmAllocationProperties(0); EXPECT_FALSE(allocationProperties.coherent);