diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index 87c3ec125c..c0b6814b9b 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -3933,6 +3933,8 @@ CL_API_ENTRY void *CL_API_CALL clHostMemAllocINTEL( return nullptr; } + neoContext->initializeUsmAllocationPools(); + auto allocationFromPool = neoContext->getHostMemAllocPool().createUnifiedMemoryAllocation(size, unifiedMemoryProperties); if (allocationFromPool) { TRACING_EXIT(ClHostMemAllocINTEL, &allocationFromPool); @@ -3995,6 +3997,8 @@ CL_API_ENTRY void *CL_API_CALL clDeviceMemAllocINTEL( unifiedMemoryProperties.device = &neoDevice->getDevice(); + neoContext->initializeUsmAllocationPools(); + auto allocationFromPool = neoContext->getDeviceMemAllocPool().createUnifiedMemoryAllocation(size, unifiedMemoryProperties); if (allocationFromPool) { TRACING_EXIT(ClDeviceMemAllocINTEL, &allocationFromPool); diff --git a/opencl/source/context/context.cpp b/opencl/source/context/context.cpp index 47b2c8896e..7d177c18c8 100644 --- a/opencl/source/context/context.cpp +++ b/opencl/source/context/context.cpp @@ -498,10 +498,19 @@ bool Context::isSingleDeviceContext() { } void Context::initializeUsmAllocationPools() { + if (this->usmPoolInitialized) { + return; + } auto svmMemoryManager = getSVMAllocsManager(); if (!(svmMemoryManager && this->isSingleDeviceContext())) { return; } + + TakeOwnershipWrapper lock(*this); + if (this->usmPoolInitialized) { + return; + } + auto &productHelper = getDevices()[0]->getProductHelper(); bool enabled = ApiSpecificConfig::isDeviceUsmPoolingEnabled() && productHelper.isUsmPoolAllocatorSupported(); @@ -534,6 +543,7 @@ void Context::initializeUsmAllocationPools() { getRootDeviceIndices(), subDeviceBitfields); usmHostMemAllocPool.initialize(svmMemoryManager, memoryProperties, poolSize); } + this->usmPoolInitialized = true; } void Context::cleanupUsmAllocationPools() { diff --git a/opencl/source/context/context.h b/opencl/source/context/context.h index b5f6814812..0b47594c24 100644 --- a/opencl/source/context/context.h +++ b/opencl/source/context/context.h @@ -119,7 +119,6 @@ class Context : public BaseObject<_cl_context> { if (bufferPoolAllocator.isAggregatedSmallBuffersEnabled(pContext)) { bufferPoolAllocator.initAggregatedSmallBuffers(pContext); } - pContext->initializeUsmAllocationPools(); } gtpinNotifyContextCreate(pContext); return pContext; @@ -308,5 +307,6 @@ class Context : public BaseObject<_cl_context> { bool interopUserSync = false; bool resolvesRequiredInKernels = false; bool nonZebinContext = false; + bool usmPoolInitialized = false; }; } // namespace NEO diff --git a/opencl/test/unit_test/api/cl_unified_shared_memory_tests.inl b/opencl/test/unit_test/api/cl_unified_shared_memory_tests.inl index 6b52546549..7b478396ec 100644 --- a/opencl/test/unit_test/api/cl_unified_shared_memory_tests.inl +++ b/opencl/test/unit_test/api/cl_unified_shared_memory_tests.inl @@ -716,6 +716,7 @@ TEST(clUnifiedSharedMemoryTests, givenSVMAllocationPoolWhenClGetMemAllocInfoINTE debugManager.flags.EnableHostUsmAllocationPool.set(2); debugManager.flags.EnableDeviceUsmAllocationPool.set(2); MockContext mockContext; + mockContext.usmPoolInitialized = false; auto device = mockContext.getDevice(0u); REQUIRE_SVM_OR_SKIP(device); @@ -725,7 +726,6 @@ TEST(clUnifiedSharedMemoryTests, givenSVMAllocationPoolWhenClGetMemAllocInfoINTE size_t paramValueSizeRet = 0; const size_t allocationSize = 4u; - mockContext.initializeUsmAllocationPools(); { auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, allocationSize, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); @@ -778,6 +778,7 @@ TEST(clUnifiedSharedMemoryTests, givenSVMAllocationPoolWhenClGetMemAllocInfoINTE debugManager.flags.EnableHostUsmAllocationPool.set(2); debugManager.flags.EnableDeviceUsmAllocationPool.set(2); MockContext mockContext; + mockContext.usmPoolInitialized = false; auto device = mockContext.getDevice(0u); REQUIRE_SVM_OR_SKIP(device); @@ -786,7 +787,6 @@ TEST(clUnifiedSharedMemoryTests, givenSVMAllocationPoolWhenClGetMemAllocInfoINTE uint64_t paramValue = 0; size_t paramValueSizeRet = 0; - mockContext.initializeUsmAllocationPools(); { auto unifiedMemoryHostAllocation = clHostMemAllocINTEL(&mockContext, nullptr, 4, 0, &retVal); auto allocationsManager = mockContext.getSVMAllocsManager(); diff --git a/opencl/test/unit_test/context/context_usm_memory_pool_tests.cpp b/opencl/test/unit_test/context/context_usm_memory_pool_tests.cpp index 35815c135d..a6c0a9ece8 100644 --- a/opencl/test/unit_test/context/context_usm_memory_pool_tests.cpp +++ b/opencl/test/unit_test/context/context_usm_memory_pool_tests.cpp @@ -5,6 +5,8 @@ * */ +#include "shared/source/helpers/api_specific_config.h" +#include "shared/source/os_interface/product_helper.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/mocks/mock_usm_memory_pool.h" #include "shared/test/common/test_macros/hw_test.h" @@ -22,6 +24,7 @@ struct ContextUsmPoolFlagValuesTest : public ::testing::Test { void SetUp() override { mockContext = std::make_unique(); + mockContext->usmPoolInitialized = false; const ClDeviceInfo &devInfo = mockContext->getDevice(0u)->getDeviceInfo(); if (devInfo.svmCapabilities == 0) { GTEST_SKIP(); @@ -30,7 +33,6 @@ struct ContextUsmPoolFlagValuesTest : public ::testing::Test { mockHostUsmMemAllocPool = static_cast(&mockContext->getHostMemAllocPool()); debugManager.flags.EnableDeviceUsmAllocationPool.set(devicePoolFlag); debugManager.flags.EnableHostUsmAllocationPool.set(hostPoolFlag); - mockContext->initializeUsmAllocationPools(); } std::unique_ptr mockContext; @@ -51,16 +53,9 @@ HWTEST2_F(ContextUsmPoolDefaultFlagsTest, givenDefaultDebugFlagsWhenCreatingCont EXPECT_EQ(nullptr, mockHostUsmMemAllocPool->pool); } -HWTEST2_F(ContextUsmPoolDefaultFlagsTest, givenDefaultDebugFlagsWhenCreatingContextThenPoolsAreInitialized, IsXeHpgCore) { - EXPECT_TRUE(mockDeviceUsmMemAllocPool->isInitialized()); - EXPECT_EQ(1 * MemoryConstants::megaByte, mockDeviceUsmMemAllocPool->poolSize); - EXPECT_NE(nullptr, mockDeviceUsmMemAllocPool->pool); - EXPECT_EQ(InternalMemoryType::deviceUnifiedMemory, mockDeviceUsmMemAllocPool->poolMemoryType); - - EXPECT_TRUE(mockHostUsmMemAllocPool->isInitialized()); - EXPECT_EQ(1 * MemoryConstants::megaByte, mockHostUsmMemAllocPool->poolSize); - EXPECT_NE(nullptr, mockHostUsmMemAllocPool->pool); - EXPECT_EQ(InternalMemoryType::hostUnifiedMemory, mockHostUsmMemAllocPool->poolMemoryType); +HWTEST2_F(ContextUsmPoolDefaultFlagsTest, givenDefaultDebugFlagsWhenCreatingContextThenPoolsAreNotInitialized, IsXeHpgCore) { + EXPECT_FALSE(mockDeviceUsmMemAllocPool->isInitialized()); + EXPECT_FALSE(mockHostUsmMemAllocPool->isInitialized()); } HWTEST2_F(ContextUsmPoolDefaultFlagsTest, givenDefaultDebugFlagsWhenCreatingContextThenPoolsAreNotInitialized, IsXeHpcCore) { @@ -74,7 +69,18 @@ HWTEST2_F(ContextUsmPoolDefaultFlagsTest, givenDefaultDebugFlagsWhenCreatingCont } using ContextUsmPoolEnabledFlagsTest = ContextUsmPoolFlagValuesTest<1, 3>; -TEST_F(ContextUsmPoolEnabledFlagsTest, givenEnabledDebugFlagsWhenCreatingContextThenPoolsAreInitialized) { +TEST_F(ContextUsmPoolEnabledFlagsTest, givenEnabledDebugFlagsWhenCreatingAllocaitonsThenPoolsAreInitialized) { + cl_int retVal = CL_SUCCESS; + void *pooledDeviceAlloc = clDeviceMemAllocINTEL(mockContext.get(), static_cast(mockContext->getDevice(0)), nullptr, UsmMemAllocPool::allocationThreshold, 0, &retVal); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_NE(nullptr, pooledDeviceAlloc); + clMemFreeINTEL(mockContext.get(), pooledDeviceAlloc); + + void *pooledHostAlloc = clHostMemAllocINTEL(mockContext.get(), nullptr, UsmMemAllocPool::allocationThreshold, 0, &retVal); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_NE(nullptr, pooledHostAlloc); + clMemFreeINTEL(mockContext.get(), pooledHostAlloc); + EXPECT_TRUE(mockDeviceUsmMemAllocPool->isInitialized()); EXPECT_EQ(1 * MemoryConstants::megaByte, mockDeviceUsmMemAllocPool->poolSize); EXPECT_NE(nullptr, mockDeviceUsmMemAllocPool->pool); @@ -84,6 +90,12 @@ TEST_F(ContextUsmPoolEnabledFlagsTest, givenEnabledDebugFlagsWhenCreatingContext EXPECT_EQ(3 * MemoryConstants::megaByte, mockHostUsmMemAllocPool->poolSize); EXPECT_NE(nullptr, mockHostUsmMemAllocPool->pool); EXPECT_EQ(InternalMemoryType::hostUnifiedMemory, mockHostUsmMemAllocPool->poolMemoryType); +} + +using ContextUsmPoolEnabledFlagsTestDefault = ContextUsmPoolFlagValuesTest<-1, -1>; +TEST_F(ContextUsmPoolEnabledFlagsTestDefault, givenDefaultDebugSettingsThenPoolIsInitializedWhenPlatformSupportIt) { + EXPECT_FALSE(mockDeviceUsmMemAllocPool->isInitialized()); + EXPECT_FALSE(mockHostUsmMemAllocPool->isInitialized()); cl_int retVal = CL_SUCCESS; void *pooledDeviceAlloc = clDeviceMemAllocINTEL(mockContext.get(), static_cast(mockContext->getDevice(0)), nullptr, UsmMemAllocPool::allocationThreshold, 0, &retVal); @@ -95,4 +107,11 @@ TEST_F(ContextUsmPoolEnabledFlagsTest, givenEnabledDebugFlagsWhenCreatingContext EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_NE(nullptr, pooledHostAlloc); clMemFreeINTEL(mockContext.get(), pooledHostAlloc); + + auto &productHelper = mockContext->getDevice(0u)->getProductHelper(); + bool enabledDevice = ApiSpecificConfig::isDeviceUsmPoolingEnabled() && productHelper.isUsmPoolAllocatorSupported(); + bool enabledHost = ApiSpecificConfig::isHostUsmPoolingEnabled() && productHelper.isUsmPoolAllocatorSupported(); + + EXPECT_EQ(enabledDevice, mockDeviceUsmMemAllocPool->isInitialized()); + EXPECT_EQ(enabledHost, mockHostUsmMemAllocPool->isInitialized()); } \ No newline at end of file diff --git a/opencl/test/unit_test/mem_obj/buffer_pool_alloc_tests.cpp b/opencl/test/unit_test/mem_obj/buffer_pool_alloc_tests.cpp index f1e6f51987..ec180ac512 100644 --- a/opencl/test/unit_test/mem_obj/buffer_pool_alloc_tests.cpp +++ b/opencl/test/unit_test/mem_obj/buffer_pool_alloc_tests.cpp @@ -63,6 +63,8 @@ class AggregatedSmallBuffersTestTemplate : public ::testing::Test { this->setAllocationToFail(failMainStorageAllocation); cl_device_id devices[] = {device}; this->context.reset(Context::create(nullptr, ClDeviceVector(devices, 1), nullptr, nullptr, retVal)); + this->context->usmPoolInitialized = false; + this->context->initializeUsmAllocationPools(); EXPECT_EQ(retVal, CL_SUCCESS); this->setAllocationToFail(false); this->poolAllocator = static_cast(&context->smallBufferPoolAllocator); diff --git a/opencl/test/unit_test/mocks/mock_context.cpp b/opencl/test/unit_test/mocks/mock_context.cpp index 51149d765b..ff132dfd2c 100644 --- a/opencl/test/unit_test/mocks/mock_context.cpp +++ b/opencl/test/unit_test/mocks/mock_context.cpp @@ -71,6 +71,7 @@ MockContext::MockContext() { cl_device_id deviceId = pDevice; initializeWithDevices(ClDeviceVector{&deviceId, 1}, false); pDevice->decRefInternal(); + this->usmPoolInitialized = true; } void MockContext::setSharingFunctions(SharingFunctions *sharingFunctions) { @@ -202,6 +203,7 @@ BcsMockContext::BcsMockContext(ClDevice *device) : MockContext(device) { return BlitOperationResult::success; }; blitMemoryToAllocationFuncBackup = mockBlitMemoryToAllocation; + this->usmPoolInitialized = true; } BcsMockContext::~BcsMockContext() = default; } // namespace NEO diff --git a/opencl/test/unit_test/mocks/mock_context.h b/opencl/test/unit_test/mocks/mock_context.h index 910b7093df..325abd0e9e 100644 --- a/opencl/test/unit_test/mocks/mock_context.h +++ b/opencl/test/unit_test/mocks/mock_context.h @@ -36,6 +36,7 @@ class MockContext : public Context { using Context::smallBufferPoolAllocator; using Context::specialQueues; using Context::svmAllocsManager; + using Context::usmPoolInitialized; MockContext(ClDevice *pDevice, bool noSpecialQueue = false); MockContext(const ClDeviceVector &clDeviceVector, bool noSpecialQueue = true);