From 7f5aa241b2a9d2a59b2bcaedf1d226842cfa5a78 Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Thu, 4 Jun 2020 16:25:08 +0200 Subject: [PATCH] Correct creating shared unified memory select device from context when device is not provided by user return error when allocation fails Related-To: NEO-4588 Change-Id: I2196ebf7c3e7908d1f8ca60c85ab2ef449997f9c Signed-off-by: Mateusz Jablonski --- opencl/source/api/api.cpp | 29 +++++++++++-------- .../api/cl_unified_shared_memory_tests.inl | 25 ++++++++++++++++ opencl/test/unit_test/mocks/mock_context.h | 2 -- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index cc652c8fa9..e7fcb3f0c6 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -3558,7 +3558,6 @@ void *clSharedMemAllocINTEL( cl_uint alignment, cl_int *errcodeRet) { Context *neoContext = nullptr; - ClDevice *neoDevice = nullptr; ErrorCodeHelper err(errcodeRet, CL_SUCCESS); @@ -3579,21 +3578,27 @@ void *clSharedMemAllocINTEL( err.set(CL_INVALID_VALUE); return nullptr; } - - if (size > neoContext->getDevice(0u)->getSharedDeviceInfo().maxMemAllocSize && !unifiedMemoryProperties.allocationFlags.flags.allowUnrestrictedSize) { + ClDevice *neoDevice = castToObject(device); + if (neoDevice) { + if (!neoContext->isDeviceAssociated(*neoDevice)) { + err.set(CL_INVALID_DEVICE); + return nullptr; + } + unifiedMemoryProperties.device = device; + unifiedMemoryProperties.subdeviceBitfield = neoDevice->getDeviceBitfield(); + } else { + neoDevice = neoContext->getDevice(0); + unifiedMemoryProperties.subdeviceBitfield = neoContext->getDeviceBitfieldForAllocation(); + } + if (size > neoDevice->getSharedDeviceInfo().maxMemAllocSize && !unifiedMemoryProperties.allocationFlags.flags.allowUnrestrictedSize) { err.set(CL_INVALID_BUFFER_SIZE); return nullptr; } - - unifiedMemoryProperties.device = device; - if (!device) { - return neoContext->getSVMAllocsManager()->createUnifiedMemoryAllocation(neoContext->getDevice(0)->getRootDeviceIndex(), size, unifiedMemoryProperties); + auto ptr = neoContext->getSVMAllocsManager()->createSharedUnifiedMemoryAllocation(neoDevice->getRootDeviceIndex(), size, unifiedMemoryProperties, neoContext->getSpecialQueue()); + if (!ptr) { + err.set(CL_OUT_OF_RESOURCES); } - - validateObjects(WithCastToInternal(device, &neoDevice)); - - unifiedMemoryProperties.subdeviceBitfield = neoDevice->getDefaultEngine().osContext->getDeviceBitfield(); - return neoContext->getSVMAllocsManager()->createSharedUnifiedMemoryAllocation(neoContext->getDevice(0)->getRootDeviceIndex(), size, unifiedMemoryProperties, neoContext->getSpecialQueue()); + return ptr; } cl_int clMemFreeCommon(cl_context context, 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 d5189f9887..884f8f7322 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 @@ -12,6 +12,7 @@ #include "opencl/test/unit_test/command_queue/command_queue_fixture.h" #include "opencl/test/unit_test/mocks/mock_context.h" #include "opencl/test/unit_test/mocks/mock_kernel.h" +#include "opencl/test/unit_test/mocks/mock_memory_manager.h" #include "opencl/test/unit_test/test_macros/test_checks_ocl.h" using namespace NEO; @@ -99,6 +100,21 @@ TEST(clUnifiedSharedMemoryTests, whenUnifiedSharedMemoryAllocationCallsAreCalled EXPECT_EQ(nullptr, unfiedMemoryDeviceAllocation); } +TEST(clUnifiedSharedMemoryTests, givenSharedMemAllocCallWhenAllocatingGraphicsMemoryFailsThenOutOfResourcesErrorIsReturned) { + UltClDeviceFactory deviceFactory{1, 0}; + auto executionEnvironment = deviceFactory.rootDevices[0]->getExecutionEnvironment(); + std::unique_ptr memoryManager = std::make_unique(0, *executionEnvironment); + std::swap(memoryManager, executionEnvironment->memoryManager); + MockContext context(deviceFactory.rootDevices[0]); + + cl_int retVal = CL_INVALID_CONTEXT; + + auto allocation = clSharedMemAllocINTEL(&context, nullptr, nullptr, MemoryConstants::pageSize, 0, &retVal); + EXPECT_EQ(CL_OUT_OF_RESOURCES, retVal); + EXPECT_EQ(nullptr, allocation); + std::swap(memoryManager, executionEnvironment->memoryManager); +} + TEST(clUnifiedSharedMemoryTests, whenClSharedMemAllocINTELisCalledWithWrongContextThenInvalidContextErrorIsReturned) { cl_int retVal = CL_SUCCESS; auto ptr = clSharedMemAllocINTEL(0, 0, nullptr, 0, 0, &retVal); @@ -106,6 +122,15 @@ TEST(clUnifiedSharedMemoryTests, whenClSharedMemAllocINTELisCalledWithWrongConte EXPECT_EQ(CL_INVALID_CONTEXT, retVal); } +TEST(clUnifiedSharedMemoryTests, whenClSharedMemAllocINTELisCalledWithWrongDeviceThenInvalidDeviceErrorIsReturned) { + cl_int retVal = CL_SUCCESS; + MockContext context0; + MockContext context1; + auto ptr = clSharedMemAllocINTEL(&context0, context1.getDevice(0), nullptr, 0, 0, &retVal); + EXPECT_EQ(nullptr, ptr); + EXPECT_EQ(CL_INVALID_DEVICE, retVal); +} + TEST(clUnifiedSharedMemoryTests, whenClSharedMemAllocIntelIsCalledThenItAllocatesSharedUnifiedMemoryAllocation) { MockContext mockContext; cl_int retVal = CL_SUCCESS; diff --git a/opencl/test/unit_test/mocks/mock_context.h b/opencl/test/unit_test/mocks/mock_context.h index a8a71245ea..810aaca647 100644 --- a/opencl/test/unit_test/mocks/mock_context.h +++ b/opencl/test/unit_test/mocks/mock_context.h @@ -38,8 +38,6 @@ class MockContext : public Context { void resetSharingFunctions(SharingType sharing); void registerSharingWithId(SharingFunctions *sharing, SharingType sharingId); std::unique_ptr &getAsyncEventsHandlerUniquePtr(); - - protected: void initializeWithDevices(const ClDeviceVector &devices, bool noSpecialQueue); private: