diff --git a/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp index 5f7b6a1363..72d80b643e 100644 --- a/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp @@ -1401,12 +1401,14 @@ struct createHostUnifiedMemoryAllocationTest : public ::testing::Test { void SetUp() override { device0 = context.pRootDevice0; device1 = context.pRootDevice1; + device2 = context.pRootDevice2; svmManager = context.getSVMAllocsManager(); EXPECT_EQ(0u, svmManager->getNumAllocs()); } const size_t allocationSize = 4096u; - const uint32_t numDevices = 2u; + const uint32_t numDevices = 3u; MockDefaultContext context; + MockClDevice *device2; MockClDevice *device1; MockClDevice *device0; SVMAllocsManager *svmManager = nullptr; @@ -1436,6 +1438,102 @@ HWTEST_F(createHostUnifiedMemoryAllocationTest, svmManager->freeSVMAlloc(unifiedMemoryPtr); } +HWTEST_F(createHostUnifiedMemoryAllocationTest, + whenCreatingMultiGraphicsAllocationThenGraphicsAllocationPerDeviceIsCreated) { + + NEO::SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY); + unifiedMemoryProperties.subdeviceBitfield = device0->getDevice().getDeviceBitfield(); + + auto alignedSize = alignUp(allocationSize, MemoryConstants::pageSize64k); + auto memoryManager = context.getMemoryManager(); + auto allocationType = GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY; + auto maxRootDeviceIndex = numDevices - 1u; + + std::vector rootDeviceIndices; + rootDeviceIndices.reserve(numDevices); + rootDeviceIndices.push_back(0u); + rootDeviceIndices.push_back(1u); + rootDeviceIndices.push_back(2u); + + auto rootDeviceIndex = rootDeviceIndices.at(0); + AllocationProperties allocationProperties{rootDeviceIndex, + true, + alignedSize, + allocationType, + unifiedMemoryProperties.subdeviceBitfield.count() > 1, + unifiedMemoryProperties.subdeviceBitfield.count() > 1, + unifiedMemoryProperties.subdeviceBitfield}; + allocationProperties.flags.shareable = unifiedMemoryProperties.allocationFlags.flags.shareable; + + SvmAllocationData allocData(maxRootDeviceIndex); + + void *unifiedMemoryPtr = memoryManager->createMultiGraphicsAllocation(rootDeviceIndices, allocationProperties, allocData.gpuAllocations); + + EXPECT_NE(nullptr, unifiedMemoryPtr); + EXPECT_EQ(numDevices, allocData.gpuAllocations.getGraphicsAllocations().size()); + + for (auto rootDeviceIndex = 0u; rootDeviceIndex <= maxRootDeviceIndex; rootDeviceIndex++) { + auto alloc = allocData.gpuAllocations.getGraphicsAllocation(rootDeviceIndex); + + EXPECT_NE(nullptr, alloc); + EXPECT_EQ(rootDeviceIndex, alloc->getRootDeviceIndex()); + } + + for (auto gpuAllocation : allocData.gpuAllocations.getGraphicsAllocations()) { + memoryManager->freeGraphicsMemory(gpuAllocation); + } +} + +HWTEST_F(createHostUnifiedMemoryAllocationTest, + whenCreatingMultiGraphicsAllocationForSpecificRootDeviceIndicesThenOnlyGraphicsAllocationPerSpecificRootDeviceIndexIsCreated) { + + NEO::SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY); + unifiedMemoryProperties.subdeviceBitfield = device0->getDevice().getDeviceBitfield(); + + auto alignedSize = alignUp(allocationSize, MemoryConstants::pageSize64k); + auto memoryManager = context.getMemoryManager(); + auto allocationType = GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY; + auto maxRootDeviceIndex = numDevices - 1u; + + std::vector rootDeviceIndices; + rootDeviceIndices.reserve(numDevices); + rootDeviceIndices.push_back(0u); + rootDeviceIndices.push_back(2u); + + auto noProgramedRootDeviceIndex = 1u; + auto rootDeviceIndex = rootDeviceIndices.at(0); + AllocationProperties allocationProperties{rootDeviceIndex, + true, + alignedSize, + allocationType, + unifiedMemoryProperties.subdeviceBitfield.count() > 1, + unifiedMemoryProperties.subdeviceBitfield.count() > 1, + unifiedMemoryProperties.subdeviceBitfield}; + allocationProperties.flags.shareable = unifiedMemoryProperties.allocationFlags.flags.shareable; + + SvmAllocationData allocData(maxRootDeviceIndex); + + void *unifiedMemoryPtr = memoryManager->createMultiGraphicsAllocation(rootDeviceIndices, allocationProperties, allocData.gpuAllocations); + + EXPECT_NE(nullptr, unifiedMemoryPtr); + EXPECT_EQ(numDevices, allocData.gpuAllocations.getGraphicsAllocations().size()); + + for (auto rootDeviceIndex = 0u; rootDeviceIndex <= maxRootDeviceIndex; rootDeviceIndex++) { + auto alloc = allocData.gpuAllocations.getGraphicsAllocation(rootDeviceIndex); + + if (rootDeviceIndex == noProgramedRootDeviceIndex) { + EXPECT_EQ(nullptr, alloc); + } else { + EXPECT_NE(nullptr, alloc); + EXPECT_EQ(rootDeviceIndex, alloc->getRootDeviceIndex()); + } + } + + for (auto gpuAllocation : allocData.gpuAllocations.getGraphicsAllocations()) { + memoryManager->freeGraphicsMemory(gpuAllocation); + } +} + struct MemoryAllocationTypeArray { const InternalMemoryType allocationType[3] = {InternalMemoryType::HOST_UNIFIED_MEMORY, InternalMemoryType::DEVICE_UNIFIED_MEMORY, diff --git a/opencl/test/unit_test/mocks/mock_context.h b/opencl/test/unit_test/mocks/mock_context.h index 2cd0211b58..24f4fe7e8a 100644 --- a/opencl/test/unit_test/mocks/mock_context.h +++ b/opencl/test/unit_test/mocks/mock_context.h @@ -48,9 +48,10 @@ class MockContext : public Context { struct MockDefaultContext : MockContext { MockDefaultContext(); - UltClDeviceFactory ultClDeviceFactory{2, 0}; + UltClDeviceFactory ultClDeviceFactory{3, 0}; MockClDevice *pRootDevice0; MockClDevice *pRootDevice1; + MockClDevice *pRootDevice2; }; struct MockSpecializedContext : MockContext { diff --git a/shared/source/memory_manager/unified_memory_manager.cpp b/shared/source/memory_manager/unified_memory_manager.cpp index 3dda87dc99..f7161ed9fa 100644 --- a/shared/source/memory_manager/unified_memory_manager.cpp +++ b/shared/source/memory_manager/unified_memory_manager.cpp @@ -119,7 +119,7 @@ void *SVMAllocsManager::createHostUnifiedMemoryAllocation(uint32_t maxRootDevice GraphicsAllocation::AllocationType allocationType = GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY; std::vector rootDeviceIndices; - rootDeviceIndices.reserve(maxRootDeviceIndex); + rootDeviceIndices.reserve(maxRootDeviceIndex + 1); for (auto rootDeviceIndex = 0u; rootDeviceIndex <= maxRootDeviceIndex; rootDeviceIndex++) { rootDeviceIndices.push_back(rootDeviceIndex); }