From 4b0473718e6dee60dcbabad0dac8ee57f2dbaff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Zwoli=C5=84ski?= Date: Mon, 10 Feb 2025 20:38:40 +0000 Subject: [PATCH] fix: configure UsmMemAllocPool params based on productHelper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When is2MBLocalMemAlignmentEnabled() returns true, increase device USM pool parameters: - Pool size from 2MB to 16MB - Max serviced size from 1MB to 2MB Host USM pool parameters remain unchanged. Related-To: NEO-12287 Signed-off-by: Fabian ZwoliƄski --- opencl/source/context/context.cpp | 36 +++++- opencl/source/context/context.h | 9 ++ .../test/unit_test/context/context_tests.cpp | 104 ++++++++++++++++++ opencl/test/unit_test/mocks/mock_context.h | 3 + 4 files changed, 146 insertions(+), 6 deletions(-) diff --git a/opencl/source/context/context.cpp b/opencl/source/context/context.cpp index 2f6dc16775..083080eb46 100644 --- a/opencl/source/context/context.cpp +++ b/opencl/source/context/context.cpp @@ -515,6 +515,29 @@ bool Context::isSingleDeviceContext() { return getNumDevices() == 1 && devices[0]->getNumGenericSubDevices() == 0; } +Context::UsmPoolParams Context::getUsmHostPoolParams() const { + return { + .poolSize = 2 * MemoryConstants::megaByte, + .minServicedSize = 0u, + .maxServicedSize = 1 * MemoryConstants::megaByte}; +} + +Context::UsmPoolParams Context::getUsmDevicePoolParams() const { + const auto &productHelper = devices[0]->getDevice().getProductHelper(); + + if (productHelper.is2MBLocalMemAlignmentEnabled()) { + return { + .poolSize = 16 * MemoryConstants::megaByte, + .minServicedSize = 0u, + .maxServicedSize = 2 * MemoryConstants::megaByte}; + } + + return { + .poolSize = 2 * MemoryConstants::megaByte, + .minServicedSize = 0u, + .maxServicedSize = 1 * MemoryConstants::megaByte}; +} + void Context::initializeUsmAllocationPools() { if (this->usmPoolInitialized) { return; @@ -531,10 +554,11 @@ void Context::initializeUsmAllocationPools() { auto &productHelper = getDevices()[0]->getProductHelper(); bool enabled = ApiSpecificConfig::isDeviceUsmPoolingEnabled() && productHelper.isUsmPoolAllocatorSupported(); - size_t poolSize = 2 * MemoryConstants::megaByte; + + auto usmDevicePoolParams = getUsmDevicePoolParams(); if (debugManager.flags.EnableDeviceUsmAllocationPool.get() != -1) { enabled = debugManager.flags.EnableDeviceUsmAllocationPool.get() > 0; - poolSize = debugManager.flags.EnableDeviceUsmAllocationPool.get() * MemoryConstants::megaByte; + usmDevicePoolParams.poolSize = debugManager.flags.EnableDeviceUsmAllocationPool.get() * MemoryConstants::megaByte; } if (enabled) { auto subDeviceBitfields = getDeviceBitfields(); @@ -543,14 +567,14 @@ void Context::initializeUsmAllocationPools() { SVMAllocsManager::UnifiedMemoryProperties memoryProperties(InternalMemoryType::deviceUnifiedMemory, MemoryConstants::pageSize2M, getRootDeviceIndices(), subDeviceBitfields); memoryProperties.device = &neoDevice; - usmDeviceMemAllocPool.initialize(svmMemoryManager, memoryProperties, poolSize, 0u, 1 * MemoryConstants::megaByte); + usmDeviceMemAllocPool.initialize(svmMemoryManager, memoryProperties, usmDevicePoolParams.poolSize, usmDevicePoolParams.minServicedSize, usmDevicePoolParams.maxServicedSize); } enabled = ApiSpecificConfig::isHostUsmPoolingEnabled() && productHelper.isUsmPoolAllocatorSupported(); - poolSize = 2 * MemoryConstants::megaByte; + auto usmHostPoolParams = getUsmHostPoolParams(); if (debugManager.flags.EnableHostUsmAllocationPool.get() != -1) { enabled = debugManager.flags.EnableHostUsmAllocationPool.get() > 0; - poolSize = debugManager.flags.EnableHostUsmAllocationPool.get() * MemoryConstants::megaByte; + usmHostPoolParams.poolSize = debugManager.flags.EnableHostUsmAllocationPool.get() * MemoryConstants::megaByte; } if (enabled) { auto subDeviceBitfields = getDeviceBitfields(); @@ -558,7 +582,7 @@ void Context::initializeUsmAllocationPools() { subDeviceBitfields[neoDevice.getRootDeviceIndex()] = neoDevice.getDeviceBitfield(); SVMAllocsManager::UnifiedMemoryProperties memoryProperties(InternalMemoryType::hostUnifiedMemory, MemoryConstants::pageSize2M, getRootDeviceIndices(), subDeviceBitfields); - usmHostMemAllocPool.initialize(svmMemoryManager, memoryProperties, poolSize, 0u, 1 * MemoryConstants::megaByte); + usmHostMemAllocPool.initialize(svmMemoryManager, memoryProperties, usmHostPoolParams.poolSize, usmHostPoolParams.minServicedSize, usmHostPoolParams.maxServicedSize); } this->usmPoolInitialized = true; } diff --git a/opencl/source/context/context.h b/opencl/source/context/context.h index 2d31f41452..f3dec1febe 100644 --- a/opencl/source/context/context.h +++ b/opencl/source/context/context.h @@ -272,6 +272,15 @@ class Context : public BaseObject<_cl_context> { } }; + struct UsmPoolParams { + size_t poolSize{0}; + size_t minServicedSize{0}; + size_t maxServicedSize{0}; + }; + + UsmPoolParams getUsmHostPoolParams() const; + UsmPoolParams getUsmDevicePoolParams() const; + Context(void(CL_CALLBACK *pfnNotify)(const char *, const void *, size_t, void *) = nullptr, void *userData = nullptr); diff --git a/opencl/test/unit_test/context/context_tests.cpp b/opencl/test/unit_test/context/context_tests.cpp index cb62910ffc..04755f3037 100644 --- a/opencl/test/unit_test/context/context_tests.cpp +++ b/opencl/test/unit_test/context/context_tests.cpp @@ -15,6 +15,8 @@ #include "shared/test/common/mocks/mock_deferred_deleter.h" #include "shared/test/common/mocks/mock_device.h" #include "shared/test/common/mocks/mock_memory_manager.h" +#include "shared/test/common/mocks/mock_product_helper.h" +#include "shared/test/common/mocks/mock_usm_memory_pool.h" #include "shared/test/common/mocks/ult_device_factory.h" #include "shared/test/common/test_macros/hw_test.h" @@ -833,3 +835,105 @@ TEST_F(GTPinContextDestroyTest, whenCallingConxtextDestructorThenGTPinIsNotified EXPECT_TRUE(MockSVMAllocManager::svmAllocManagerDeleted); } } // namespace NEO + +struct ContextUsmPoolParamsTest : public ::testing::Test { + void SetUp() override { + deviceFactory = std::make_unique(2, 0); + device = deviceFactory->rootDevices[rootDeviceIndex]; + mockNeoDevice = static_cast(&device->getDevice()); + mockProductHelper = new MockProductHelper; + mockNeoDevice->getRootDeviceEnvironmentRef().productHelper.reset(mockProductHelper); + } + + bool compareUsmPoolParams(const MockContext::UsmPoolParams &first, const MockContext::UsmPoolParams &second) { + return first.poolSize == second.poolSize && + first.minServicedSize == second.minServicedSize && + first.maxServicedSize == second.maxServicedSize; + } + + const size_t rootDeviceIndex = 1u; + std::unique_ptr deviceFactory; + MockClDevice *device; + MockDevice *mockNeoDevice; + MockProductHelper *mockProductHelper; + std::unique_ptr context; + cl_int retVal = CL_SUCCESS; + DebugManagerStateRestore restore; +}; + +TEST_F(ContextUsmPoolParamsTest, GivenDisabled2MBLocalMemAlignmentWhenGettingUsmPoolParamsThenReturnCorrectValues) { + mockProductHelper->is2MBLocalMemAlignmentEnabledResult = false; + + cl_device_id devices[] = {device}; + context.reset(Context::create(nullptr, ClDeviceVector(devices, 1), nullptr, nullptr, retVal)); + EXPECT_EQ(CL_SUCCESS, retVal); + + const MockContext::UsmPoolParams expectedUsmHostPoolParams{ + .poolSize = 2 * MemoryConstants::megaByte, + .minServicedSize = 0u, + .maxServicedSize = 1 * MemoryConstants::megaByte}; + + const MockContext::UsmPoolParams expectedUsmDevicePoolParams{ + .poolSize = 2 * MemoryConstants::megaByte, + .minServicedSize = 0u, + .maxServicedSize = 1 * MemoryConstants::megaByte}; + + EXPECT_TRUE(compareUsmPoolParams(expectedUsmHostPoolParams, context->getUsmHostPoolParams())); + EXPECT_TRUE(compareUsmPoolParams(expectedUsmDevicePoolParams, context->getUsmDevicePoolParams())); +} + +TEST_F(ContextUsmPoolParamsTest, GivenEnabled2MBLocalMemAlignmentWhenGettingUsmPoolParamsThenReturnCorrectValues) { + mockProductHelper->is2MBLocalMemAlignmentEnabledResult = true; + + cl_device_id devices[] = {device}; + context.reset(Context::create(nullptr, ClDeviceVector(devices, 1), nullptr, nullptr, retVal)); + EXPECT_EQ(CL_SUCCESS, retVal); + + const MockContext::UsmPoolParams expectedUsmHostPoolParams{ + .poolSize = 2 * MemoryConstants::megaByte, + .minServicedSize = 0u, + .maxServicedSize = 1 * MemoryConstants::megaByte}; + + const MockContext::UsmPoolParams expectedUsmDevicePoolParams{ + .poolSize = 16 * MemoryConstants::megaByte, + .minServicedSize = 0u, + .maxServicedSize = 2 * MemoryConstants::megaByte}; + + EXPECT_TRUE(compareUsmPoolParams(expectedUsmHostPoolParams, context->getUsmHostPoolParams())); + EXPECT_TRUE(compareUsmPoolParams(expectedUsmDevicePoolParams, context->getUsmDevicePoolParams())); +} + +TEST_F(ContextUsmPoolParamsTest, GivenUsmPoolAllocatorSupportedWhenInitializingUsmPoolsThenPoolsAreInitializedWithCorrectParams) { + mockProductHelper->isUsmPoolAllocatorSupportedResult = true; + + cl_device_id devices[] = {device}; + context.reset(Context::create(nullptr, ClDeviceVector(devices, 1), nullptr, nullptr, retVal)); + EXPECT_EQ(CL_SUCCESS, retVal); + + context->initializeUsmAllocationPools(); + + EXPECT_TRUE(context->getHostMemAllocPool().isInitialized()); + EXPECT_TRUE(context->getDeviceMemAllocPool().isInitialized()); + + { + auto mockHostUsmMemAllocPool = static_cast(&context->getHostMemAllocPool()); + const MockContext::UsmPoolParams givenUsmHostPoolParams{ + .poolSize = mockHostUsmMemAllocPool->poolSize, + .minServicedSize = mockHostUsmMemAllocPool->minServicedSize, + .maxServicedSize = mockHostUsmMemAllocPool->maxServicedSize}; + const MockContext::UsmPoolParams expectedUsmHostPoolParams = context->getUsmHostPoolParams(); + + EXPECT_TRUE(compareUsmPoolParams(expectedUsmHostPoolParams, givenUsmHostPoolParams)); + } + + { + auto mockDeviceUsmMemAllocPool = static_cast(&context->getDeviceMemAllocPool()); + const MockContext::UsmPoolParams givenUsmDevicePoolParams{ + .poolSize = mockDeviceUsmMemAllocPool->poolSize, + .minServicedSize = mockDeviceUsmMemAllocPool->minServicedSize, + .maxServicedSize = mockDeviceUsmMemAllocPool->maxServicedSize}; + const MockContext::UsmPoolParams expectedUsmDevicePoolParams = context->getUsmDevicePoolParams(); + + EXPECT_TRUE(compareUsmPoolParams(expectedUsmDevicePoolParams, givenUsmDevicePoolParams)); + } +} diff --git a/opencl/test/unit_test/mocks/mock_context.h b/opencl/test/unit_test/mocks/mock_context.h index bcc61d40c4..e01f00e5f6 100644 --- a/opencl/test/unit_test/mocks/mock_context.h +++ b/opencl/test/unit_test/mocks/mock_context.h @@ -26,6 +26,8 @@ class MockContext : public Context { using Context::deviceBitfields; using Context::devices; using Context::driverDiagnostics; + using Context::getUsmDevicePoolParams; + using Context::getUsmHostPoolParams; using Context::maxRootDeviceIndex; using Context::memoryManager; using Context::preferD3dSharedResources; @@ -37,6 +39,7 @@ class MockContext : public Context { using Context::specialQueues; using Context::svmAllocsManager; using Context::usmPoolInitialized; + using Context::UsmPoolParams; MockContext(ClDevice *pDevice, bool noSpecialQueue = false); MockContext(const ClDeviceVector &clDeviceVector, bool noSpecialQueue = true);