From 3c1502387162c27b24897fac6444e5274207bd30 Mon Sep 17 00:00:00 2001 From: Szymon Morek Date: Thu, 5 Aug 2021 10:10:20 +0000 Subject: [PATCH] Add AllowUnrestrictedSize debug flag This debug flag allows to allocate memory with size greater than CL_DEVICE_MAX_MEM_ALLOC_SIZE. Signed-off-by: Szymon Morek --- opencl/source/api/api.cpp | 2 +- .../memory_properties_helpers_base.inl | 3 +- opencl/source/mem_obj/buffer.cpp | 3 +- .../unit_test/api/cl_create_buffer_tests.cpp | 20 +++++++++ .../test/unit_test/api/cl_svm_alloc_tests.inl | 9 ++++ .../api/cl_unified_shared_memory_tests.inl | 43 +++++++++++++++++++ .../test/unit_test/test_files/igdrcl.config | 1 + .../debug_settings/debug_variables_base.inl | 1 + 8 files changed, 79 insertions(+), 3 deletions(-) diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index 49fbf13e90..e5d5159491 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -4457,7 +4457,7 @@ void *CL_API_CALL clSVMAlloc(cl_context context, } auto pDevice = pContext->getDevice(0); - bool allowUnrestrictedSize = (flags & CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL); + bool allowUnrestrictedSize = (flags & CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL) || DebugManager.flags.AllowUnrestrictedSize.get(); if ((size == 0) || (!allowUnrestrictedSize && (size > pDevice->getSharedDeviceInfo().maxMemAllocSize))) { diff --git a/opencl/source/helpers/memory_properties_helpers_base.inl b/opencl/source/helpers/memory_properties_helpers_base.inl index 8cba8f99db..5b2a9a3f0d 100644 --- a/opencl/source/helpers/memory_properties_helpers_base.inl +++ b/opencl/source/helpers/memory_properties_helpers_base.inl @@ -59,7 +59,8 @@ MemoryProperties MemoryPropertiesHelper::createMemoryProperties(cl_mem_flags fla memoryProperties.flags.noAccess = true; } if (isValueSet(flags, CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL) || - isValueSet(flagsIntel, CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL)) { + isValueSet(flagsIntel, CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL) || + DebugManager.flags.AllowUnrestrictedSize.get()) { memoryProperties.flags.allowUnrestrictedSize = true; } if (isValueSet(flagsIntel, CL_MEM_LOCALLY_UNCACHED_RESOURCE)) { diff --git a/opencl/source/mem_obj/buffer.cpp b/opencl/source/mem_obj/buffer.cpp index 02f7dd10c5..36e5597123 100644 --- a/opencl/source/mem_obj/buffer.cpp +++ b/opencl/source/mem_obj/buffer.cpp @@ -124,7 +124,8 @@ cl_mem Buffer::validateInputAndCreateBuffer(cl_context context, auto pDevice = pContext->getDevice(0); bool allowCreateBuffersWithUnrestrictedSize = isValueSet(flags, CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL) || - isValueSet(flagsIntel, CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL); + isValueSet(flagsIntel, CL_MEM_ALLOW_UNRESTRICTED_SIZE_INTEL) || + DebugManager.flags.AllowUnrestrictedSize.get(); if (size == 0 || (size > pDevice->getDevice().getDeviceInfo().maxMemAllocSize && !allowCreateBuffersWithUnrestrictedSize)) { retVal = CL_INVALID_BUFFER_SIZE; diff --git a/opencl/test/unit_test/api/cl_create_buffer_tests.cpp b/opencl/test/unit_test/api/cl_create_buffer_tests.cpp index 8a197ccea1..cae610eace 100644 --- a/opencl/test/unit_test/api/cl_create_buffer_tests.cpp +++ b/opencl/test/unit_test/api/cl_create_buffer_tests.cpp @@ -278,6 +278,26 @@ TEST_F(clCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeAndClMemAllowUnres EXPECT_EQ(CL_SUCCESS, retVal); } +TEST_F(clCreateBufferTests, GivenBufferSizeOverMaxMemAllocSizeAndDebugFlagSetWhenCreatingBufferThenClSuccessIsReturned) { + DebugManagerStateRestore restorer; + DebugManager.flags.AllowUnrestrictedSize.set(1); + auto pDevice = pContext->getDevice(0); + size_t size = static_cast(pDevice->getDevice().getDeviceInfo().maxMemAllocSize) + 1; + auto memoryManager = static_cast(pDevice->getMemoryManager()); + memoryManager->turnOnFakingBigAllocations(); + + if (memoryManager->peekForce32BitAllocations() || is32bit) { + GTEST_SKIP(); + } + + auto buffer = clCreateBuffer(pContext, 0, size, nullptr, &retVal); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_NE(nullptr, buffer); + + retVal = clReleaseMemObject(buffer); + EXPECT_EQ(CL_SUCCESS, retVal); +} + TEST_F(clCreateBufferTests, GivenNullHostPointerAndMemCopyHostPtrFlagWhenCreatingBufferThenNullIsReturned) { cl_mem_flags flags = CL_MEM_USE_HOST_PTR; static const unsigned int bufferSize = 16; diff --git a/opencl/test/unit_test/api/cl_svm_alloc_tests.inl b/opencl/test/unit_test/api/cl_svm_alloc_tests.inl index 3b22d833a1..24ec5f2b7f 100644 --- a/opencl/test/unit_test/api/cl_svm_alloc_tests.inl +++ b/opencl/test/unit_test/api/cl_svm_alloc_tests.inl @@ -222,6 +222,15 @@ TEST_F(clSVMAllocTests, givenUnrestrictedFlagWhenCreatingSvmAllocThenAllowSizeBi clSVMFree(pContext, svmPtr); } + { + // debug flag + not allowed size + DebugManagerStateRestore restorer; + DebugManager.flags.AllowUnrestrictedSize.set(1); + svmPtr = clSVMAlloc(pContext, 0, notAllowedSize, 0); + EXPECT_NE(nullptr, svmPtr); + clSVMFree(pContext, svmPtr); + } + { // unrestricted size flag + allowed size svmPtr = clSVMAlloc(pContext, flags, allowedSize, 0); 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 774e95cdf1..7f62ac0ee1 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 @@ -1041,6 +1041,49 @@ TEST(clUnifiedSharedMemoryTests, givenUnifiedMemoryAllocationSizeGreaterThanMaxM } } +TEST(clUnifiedSharedMemoryTests, givenUnifiedMemoryAllocationSizeGreaterThanMaxMemAllocSizeAndDebugFlagSetWhenCreateAllocationThenSuccesIsReturned) { + DebugManagerStateRestore restorer; + DebugManager.flags.AllowUnrestrictedSize.set(1); + MockContext mockContext; + cl_int retVal = CL_SUCCESS; + auto allocationSize = static_cast(mockContext.getDevice(0u)->getSharedDeviceInfo().maxMemAllocSize) + 1; + auto memoryManager = static_cast(mockContext.getDevice(0u)->getMemoryManager()); + memoryManager->turnOnFakingBigAllocations(); + if (memoryManager->peekForce32BitAllocations() || is32bit) { + GTEST_SKIP(); + } + + { + auto unfiedMemoryAllocation = clDeviceMemAllocINTEL(&mockContext, mockContext.getDevice(0u), 0, allocationSize, 0, &retVal); + + EXPECT_EQ(CL_SUCCESS, retVal); + ASSERT_NE(nullptr, unfiedMemoryAllocation); + + retVal = clMemFreeINTEL(&mockContext, unfiedMemoryAllocation); + EXPECT_EQ(CL_SUCCESS, retVal); + } + + { + auto unfiedMemoryAllocation = clSharedMemAllocINTEL(&mockContext, mockContext.getDevice(0u), 0, allocationSize, 0, &retVal); + + EXPECT_EQ(CL_SUCCESS, retVal); + ASSERT_NE(nullptr, unfiedMemoryAllocation); + + retVal = clMemFreeINTEL(&mockContext, unfiedMemoryAllocation); + EXPECT_EQ(CL_SUCCESS, retVal); + } + + { + auto unfiedMemoryAllocation = clHostMemAllocINTEL(&mockContext, 0, allocationSize, 0, &retVal); + + EXPECT_EQ(CL_SUCCESS, retVal); + ASSERT_NE(nullptr, unfiedMemoryAllocation); + + retVal = clMemFreeINTEL(&mockContext, unfiedMemoryAllocation); + EXPECT_EQ(CL_SUCCESS, retVal); + } +} + TEST(clUnifiedSharedMemoryTests, givenUnifiedMemoryAllocationSizeGreaterThanMaxMemAllocSizeWhenCreateAllocationThenErrorIsReturned) { MockContext mockContext; cl_int retVal = CL_SUCCESS; diff --git a/opencl/test/unit_test/test_files/igdrcl.config b/opencl/test/unit_test/test_files/igdrcl.config index 5c57a9569a..5b73cedbf4 100644 --- a/opencl/test/unit_test/test_files/igdrcl.config +++ b/opencl/test/unit_test/test_files/igdrcl.config @@ -316,3 +316,4 @@ OverrideSystolicPipelineSelect = -1 OverrideSystolicInComputeWalker = -1 OverrideKernelSizeLimitForSmallDispatch = -1 SkipFlushingEventsOnGetStatusCalls = 0 +AllowUnrestrictedSize = 0 \ No newline at end of file diff --git a/shared/source/debug_settings/debug_variables_base.inl b/shared/source/debug_settings/debug_variables_base.inl index 73a0c81f78..b16c5a6d42 100644 --- a/shared/source/debug_settings/debug_variables_base.inl +++ b/shared/source/debug_settings/debug_variables_base.inl @@ -332,3 +332,4 @@ DECLARE_DEBUG_VARIABLE(bool, UseCommandBufferHeaderSizeForWddmQueueSubmission, t DECLARE_DEBUG_VARIABLE(bool, DisableDeepBind, false, "Disable passing RTLD_DEEPBIND flag to all dlopen calls.") DECLARE_DEBUG_VARIABLE(bool, UseUmKmDataTranslator, false, "Use helper library for UMD<->KMD (WDDM) struct layout compatibility") DECLARE_DEBUG_VARIABLE(bool, SkipFlushingEventsOnGetStatusCalls, false, "When set to 1, events are not causing internal flush when querying for CL_EVENT_COMMAND_EXECUTION_STATUS") +DECLARE_DEBUG_VARIABLE(bool, AllowUnrestrictedSize, false, "Allow allocating memory with greater size than MAX_MEM_ALLOC_SIZE")