diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index 2b63f2f60b..66153f1a3e 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -4877,25 +4877,27 @@ cl_int CL_API_CALL clSetKernelArgSVMPointer(cl_kernel kernel, return retVal; } - auto svmManager = pMultiDeviceKernel->getContext().getSVMAllocsManager(); + const auto svmManager = pMultiDeviceKernel->getContext().getSVMAllocsManager(); if (argValue != nullptr) { if (pMultiDeviceKernel->getKernelArguments()[argIndex].allocId > 0 && pMultiDeviceKernel->getKernelArguments()[argIndex].value == argValue) { bool reuseFromCache = false; - - if (svmManager->allocationsCounter == pMultiDeviceKernel->getKernelArguments()[argIndex].allocIdMemoryManagerCounter) { - reuseFromCache = true; - } else { - auto svmData = svmManager->getSVMAlloc(argValue); - if (pMultiDeviceKernel->getKernelArguments()[argIndex].allocId == svmData->getAllocId()) { + const auto allocationsCounter = svmManager->allocationsCounter.load(); + if (allocationsCounter > 0) { + if (allocationsCounter == pMultiDeviceKernel->getKernelArguments()[argIndex].allocIdMemoryManagerCounter) { reuseFromCache = true; - pMultiDeviceKernel->storeKernelArgAllocIdMemoryManagerCounter(argIndex, svmManager->allocationsCounter); + } else { + const auto svmData = svmManager->getSVMAlloc(argValue); + if (svmData && pMultiDeviceKernel->getKernelArguments()[argIndex].allocId == svmData->getAllocId()) { + reuseFromCache = true; + pMultiDeviceKernel->storeKernelArgAllocIdMemoryManagerCounter(argIndex, allocationsCounter); + } + } + if (reuseFromCache) { + TRACING_EXIT(clSetKernelArgSVMPointer, &retVal); + return CL_SUCCESS; } - } - if (reuseFromCache) { - TRACING_EXIT(clSetKernelArgSVMPointer, &retVal); - return CL_SUCCESS; } } } diff --git a/opencl/source/kernel/multi_device_kernel.cpp b/opencl/source/kernel/multi_device_kernel.cpp index 3f6abf4502..db12cbd5a0 100644 --- a/opencl/source/kernel/multi_device_kernel.cpp +++ b/opencl/source/kernel/multi_device_kernel.cpp @@ -54,7 +54,15 @@ void MultiDeviceKernel::clearUnifiedMemoryExecInfo() { callOnEachKernel(&Kernel: int MultiDeviceKernel::setKernelThreadArbitrationPolicy(uint32_t propertyValue) { return getResultFromEachKernel(&Kernel::setKernelThreadArbitrationPolicy, propertyValue); } cl_int MultiDeviceKernel::setKernelExecutionType(cl_execution_info_kernel_type_intel executionType) { return getResultFromEachKernel(&Kernel::setKernelExecutionType, executionType); } int32_t MultiDeviceKernel::setAdditionalKernelExecInfoWithParam(uint32_t paramName, size_t paramValueSize, const void *paramValue) { return getResultFromEachKernel(&Kernel::setAdditionalKernelExecInfoWithParam, paramName, paramValueSize, paramValue); } -void MultiDeviceKernel::storeKernelArgAllocIdMemoryManagerCounter(uint32_t argIndex, uint32_t allocIdMemoryManagerCounter) { defaultKernel->storeKernelArgAllocIdMemoryManagerCounter(argIndex, allocIdMemoryManagerCounter); }; + +void MultiDeviceKernel::storeKernelArgAllocIdMemoryManagerCounter(uint32_t argIndex, uint32_t allocIdMemoryManagerCounter) { + for (auto rootDeviceIndex = 0u; rootDeviceIndex < kernels.size(); rootDeviceIndex++) { + auto pKernel = getKernel(rootDeviceIndex); + if (pKernel) { + pKernel->storeKernelArgAllocIdMemoryManagerCounter(argIndex, allocIdMemoryManagerCounter); + } + } +} cl_int MultiDeviceKernel::cloneKernel(MultiDeviceKernel *pSourceMultiDeviceKernel) { for (auto rootDeviceIndex = 0u; rootDeviceIndex < kernels.size(); rootDeviceIndex++) { diff --git a/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl b/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl index 163f2f9f89..fa7b4b8bb8 100644 --- a/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl +++ b/opencl/test/unit_test/api/cl_set_kernel_arg_svm_pointer_tests.inl @@ -6,6 +6,7 @@ */ #include "shared/source/memory_manager/unified_memory_manager.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/mocks/mock_svm_manager.h" #include "shared/test/common/test_macros/test.h" @@ -214,7 +215,7 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenSvmAndValidArgValueWhenSettingSameKer if (devInfo.svmCapabilities != 0) { EXPECT_EQ(0u, pMockKernel->setArgSvmAllocCalls); - void *ptrSvm = clSVMAlloc(pContext, CL_MEM_READ_WRITE, 256, 4); + void *const ptrSvm = clSVMAlloc(pContext, CL_MEM_READ_WRITE, 256, 4); EXPECT_NE(nullptr, ptrSvm); auto callCounter = 0u; // first set arg - called @@ -226,6 +227,16 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenSvmAndValidArgValueWhenSettingSameKer EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(++callCounter, pMockKernel->setArgSvmAllocCalls); + // same values but allocationsCounter == 0 - called + retVal = clSetKernelArgSVMPointer( + pMockMultiDeviceKernel, // cl_kernel kernel + 0, // cl_uint arg_index + ptrSvm // const void *arg_value + ); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(++callCounter, pMockKernel->setArgSvmAllocCalls); + ++mockSvmManager->allocationsCounter; + // same values - not called retVal = clSetKernelArgSVMPointer( pMockMultiDeviceKernel, // cl_kernel kernel @@ -234,10 +245,19 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenSvmAndValidArgValueWhenSettingSameKer ); EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(callCounter, pMockKernel->setArgSvmAllocCalls); + + // same values and allocationsCounter - not called + retVal = clSetKernelArgSVMPointer( + pMockMultiDeviceKernel, // cl_kernel kernel + 0, // cl_uint arg_index + ptrSvm // const void *arg_value + ); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(callCounter, pMockKernel->setArgSvmAllocCalls); ++mockSvmManager->allocationsCounter; // different pointer - called - void *nextPtrSvm = static_cast(ptrSvm) + 1; + void *const nextPtrSvm = static_cast(ptrSvm) + 1; retVal = clSetKernelArgSVMPointer( pMockMultiDeviceKernel, // cl_kernel kernel 0, // cl_uint arg_index @@ -277,6 +297,19 @@ TEST_F(clSetKernelArgSVMPointerTests, GivenSvmAndValidArgValueWhenSettingSameKer ); EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(callCounter, pMockKernel->setArgSvmAllocCalls); + ++mockSvmManager->allocationsCounter; + + DebugManagerStateRestore stateRestorer; + DebugManager.flags.EnableSharedSystemUsmSupport.set(1); + mockSvmManager->freeSVMAlloc(nextPtrSvm); + // same values but no svmData - called + retVal = clSetKernelArgSVMPointer( + pMockMultiDeviceKernel, // cl_kernel kernel + 0, // cl_uint arg_index + nextPtrSvm // const void *arg_value + ); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(++callCounter, pMockKernel->setArgSvmAllocCalls); clSVMFree(pContext, ptrSvm); }