From 2e346b58cde22fbade7aadb270b52d337bafcda6 Mon Sep 17 00:00:00 2001 From: Krzysztof Gibala Date: Mon, 28 Dec 2020 12:10:10 +0100 Subject: [PATCH] Enable memory transfer in enqueueMigrateMemObjects Related-To: NEO-4589 Signed-off-by: Krzysztof Gibala --- opencl/source/api/api.cpp | 9 ++++ .../enqueue_migrate_mem_objects.h | 7 +++ .../cl_enqueue_migrate_mem_objects_tests.inl | 48 ++++++++++++------- .../enqueue_migrate_mem_objects_tests.cpp | 12 +++-- .../test/unit_test/mem_obj/mem_obj_tests.cpp | 35 ++++++++++++++ 5 files changed, 92 insertions(+), 19 deletions(-) diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index 7e90df8f3f..f791be1f11 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -3355,6 +3355,15 @@ cl_int CL_API_CALL clEnqueueMigrateMemObjects(cl_command_queue commandQueue, return retVal; } + for (unsigned int object = 0; object < numMemObjects; object++) { + auto memObject = castToObject(memObjects[object]); + if (!memObject) { + retVal = CL_INVALID_MEM_OBJECT; + TRACING_EXIT(clEnqueueMigrateMemObjects, &retVal); + return retVal; + } + } + const cl_mem_migration_flags allValidFlags = CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED | CL_MIGRATE_MEM_OBJECT_HOST; if ((flags & (~allValidFlags)) != 0) { diff --git a/opencl/source/command_queue/enqueue_migrate_mem_objects.h b/opencl/source/command_queue/enqueue_migrate_mem_objects.h index f444851027..054cce5a3b 100644 --- a/opencl/source/command_queue/enqueue_migrate_mem_objects.h +++ b/opencl/source/command_queue/enqueue_migrate_mem_objects.h @@ -26,6 +26,13 @@ cl_int CommandQueueHw::enqueueMigrateMemObjects(cl_uint numMemObjects NullSurface s; Surface *surfaces[] = {&s}; + auto rootDeviceIndex = getDevice().getRootDeviceIndex(); + + for (unsigned int object = 0; object < numMemObjects; object++) { + auto memObject = castToObject(memObjects[object]); + memObject->getMigrateableMultiGraphicsAllocation().ensureMemoryOnDevice(*getDevice().getMemoryManager(), rootDeviceIndex); + } + enqueueHandler(surfaces, false, MultiDispatchInfo(), diff --git a/opencl/test/unit_test/api/cl_enqueue_migrate_mem_objects_tests.inl b/opencl/test/unit_test/api/cl_enqueue_migrate_mem_objects_tests.inl index f033a75455..581ba4eaf0 100644 --- a/opencl/test/unit_test/api/cl_enqueue_migrate_mem_objects_tests.inl +++ b/opencl/test/unit_test/api/cl_enqueue_migrate_mem_objects_tests.inl @@ -8,6 +8,7 @@ #include "opencl/source/command_queue/command_queue.h" #include "opencl/source/context/context.h" #include "opencl/source/event/event.h" +#include "opencl/test/unit_test/mocks/mock_buffer.h" #include "cl_api_tests.h" @@ -31,7 +32,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenNullCommandQueueWhenMigratingMemObj EXPECT_NE(nullptr, buffer); cl_event eventReturned = nullptr; - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( nullptr, 1, &buffer, @@ -39,7 +40,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenNullCommandQueueWhenMigratingMemObj 0, nullptr, &eventReturned); - EXPECT_EQ(CL_INVALID_COMMAND_QUEUE, Result); + EXPECT_EQ(CL_INVALID_COMMAND_QUEUE, result); retVal = clReleaseMemObject(buffer); EXPECT_EQ(CL_SUCCESS, retVal); @@ -65,7 +66,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenValidInputsWhenMigratingMemObjThenS EXPECT_NE(nullptr, buffer); cl_event eventReturned = nullptr; - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( pCommandQueue, 1, &buffer, @@ -73,7 +74,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenValidInputsWhenMigratingMemObjThenS 0, nullptr, &eventReturned); - EXPECT_EQ(CL_SUCCESS, Result); + EXPECT_EQ(CL_SUCCESS, result); retVal = clReleaseMemObject(buffer); EXPECT_EQ(CL_SUCCESS, retVal); @@ -86,7 +87,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenValidInputsWhenMigratingMemObjThenS TEST_F(clEnqueueMigrateMemObjectsTests, GivenNullMemObjsWhenMigratingMemObjThenInvalidValueErrorIsReturned) { cl_event eventReturned = nullptr; - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( pCommandQueue, 1, nullptr, @@ -94,13 +95,13 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenNullMemObjsWhenMigratingMemObjThenI 0, nullptr, &eventReturned); - EXPECT_EQ(CL_INVALID_VALUE, Result); + EXPECT_EQ(CL_INVALID_VALUE, result); } TEST_F(clEnqueueMigrateMemObjectsTests, GivenZeroMemObjectsWhenMigratingMemObjsThenInvalidValueErrorIsReturned) { cl_event eventReturned = nullptr; - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( pCommandQueue, 0, nullptr, @@ -108,13 +109,13 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenZeroMemObjectsWhenMigratingMemObjsT 0, nullptr, &eventReturned); - EXPECT_EQ(CL_INVALID_VALUE, Result); + EXPECT_EQ(CL_INVALID_VALUE, result); } TEST_F(clEnqueueMigrateMemObjectsTests, GivenNonZeroEventsAndNullWaitlistWhenMigratingMemObjThenInvalidWaitListErrorIsReturned) { cl_event eventReturned = nullptr; - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( pCommandQueue, 0, nullptr, @@ -122,7 +123,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenNonZeroEventsAndNullWaitlistWhenMig 2, nullptr, &eventReturned); - EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, Result); + EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, result); } TEST_F(clEnqueueMigrateMemObjectsTests, GivenZeroEventsAndNonNullWaitlistWhenMigratingMemObjsThenInvalidWaitListErrorIsReturned) { @@ -130,7 +131,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenZeroEventsAndNonNullWaitlistWhenMig cl_event eventReturned = nullptr; Event event(pCommandQueue, CL_COMMAND_MIGRATE_MEM_OBJECTS, 0, 0); - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( pCommandQueue, 0, nullptr, @@ -138,7 +139,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenZeroEventsAndNonNullWaitlistWhenMig 0, (cl_event *)&event, &eventReturned); - EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, Result); + EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, result); } TEST_F(clEnqueueMigrateMemObjectsTests, GivenValidFlagsWhenMigratingMemObjsThenSuccessIsReturned) { @@ -160,7 +161,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenValidFlagsWhenMigratingMemObjsThenS for (auto validFlag : validFlags) { cl_event eventReturned = nullptr; - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( pCommandQueue, 1, &buffer, @@ -168,7 +169,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenValidFlagsWhenMigratingMemObjsThenS 0, nullptr, &eventReturned); - EXPECT_EQ(CL_SUCCESS, Result); + EXPECT_EQ(CL_SUCCESS, result); clReleaseEvent(eventReturned); } @@ -197,7 +198,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenInvalidFlagsWhenMigratingMemObjsThe for (auto invalidFlag : invalidFlags) { cl_event eventReturned = nullptr; - auto Result = clEnqueueMigrateMemObjects( + auto result = clEnqueueMigrateMemObjects( pCommandQueue, 1, &buffer, @@ -205,7 +206,7 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenInvalidFlagsWhenMigratingMemObjsThe 0, nullptr, &eventReturned); - EXPECT_EQ(CL_INVALID_VALUE, Result); + EXPECT_EQ(CL_INVALID_VALUE, result); clReleaseEvent(eventReturned); } @@ -214,3 +215,18 @@ TEST_F(clEnqueueMigrateMemObjectsTests, GivenInvalidFlagsWhenMigratingMemObjsThe delete[] pHostMem; } + +TEST_F(clEnqueueMigrateMemObjectsTests, GivenInvalidMemObjectWhenMigratingMemObjsThenInvalidMemObjectErrorIsReturned) { + cl_event eventReturned = nullptr; + + auto result = clEnqueueMigrateMemObjects( + pCommandQueue, + 1, + reinterpret_cast(pCommandQueue), + CL_MIGRATE_MEM_OBJECT_HOST, + 0, + nullptr, + &eventReturned); + + EXPECT_EQ(CL_INVALID_MEM_OBJECT, result); +} diff --git a/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp index d385884930..20d2e9b487 100644 --- a/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp @@ -37,10 +37,12 @@ typedef Test MigrateMemObjectsTest; TEST_F(MigrateMemObjectsTest, GivenNullEventWhenMigratingEventsThenSuccessIsReturned) { MockBuffer buffer; + auto bufferMemObj = static_cast(&buffer); + auto pBufferMemObj = &bufferMemObj; auto retVal = pCmdQ->enqueueMigrateMemObjects( 1, - (cl_mem *)&buffer, + pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, @@ -52,13 +54,15 @@ TEST_F(MigrateMemObjectsTest, GivenNullEventWhenMigratingEventsThenSuccessIsRetu TEST_F(MigrateMemObjectsTest, GivenValidEventListWhenMigratingEventsThenSuccessIsReturned) { MockBuffer buffer; + auto bufferMemObj = static_cast(&buffer); + auto pBufferMemObj = &bufferMemObj; UserEvent uEvent; cl_event eventWaitList[] = {&uEvent}; auto retVal = pCmdQ->enqueueMigrateMemObjects( 1, - (cl_mem *)&buffer, + pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 1, eventWaitList, @@ -70,12 +74,14 @@ TEST_F(MigrateMemObjectsTest, GivenValidEventListWhenMigratingEventsThenSuccessI TEST_F(MigrateMemObjectsTest, GivenEventPointerWhenMigratingEventsThenEventIsReturned) { MockBuffer buffer; + auto bufferMemObj = static_cast(&buffer); + auto pBufferMemObj = &bufferMemObj; cl_event event = nullptr; auto retVal = pCmdQ->enqueueMigrateMemObjects( 1, - (cl_mem *)&buffer, + pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, diff --git a/opencl/test/unit_test/mem_obj/mem_obj_tests.cpp b/opencl/test/unit_test/mem_obj/mem_obj_tests.cpp index 2cd98614fb..2d57d2bde0 100644 --- a/opencl/test/unit_test/mem_obj/mem_obj_tests.cpp +++ b/opencl/test/unit_test/mem_obj/mem_obj_tests.cpp @@ -17,8 +17,10 @@ #include "opencl/source/helpers/properties_helper.h" #include "opencl/source/mem_obj/mem_obj.h" #include "opencl/source/platform/platform.h" +#include "opencl/test/unit_test/command_queue/command_queue_fixture.h" #include "opencl/test/unit_test/fixtures/multi_root_device_fixture.h" #include "opencl/test/unit_test/mocks/mock_allocation_properties.h" +#include "opencl/test/unit_test/mocks/mock_buffer.h" #include "opencl/test/unit_test/mocks/mock_context.h" #include "opencl/test/unit_test/mocks/mock_deferred_deleter.h" #include "opencl/test/unit_test/mocks/mock_memory_manager.h" @@ -570,3 +572,36 @@ TEST_F(MemObjMultiRootDeviceTests, WhenMemObjMapAreCreatedThenAllAllocationAreDe memObj.reset(nullptr); } + +TEST_F(MemObjMultiRootDeviceTests, WhenMemObjIsCreatedAndEnqueueMigrateMemObjectsCalledThenMemObjMultiGraphicsAllocationLastUsedRootDeviceIndexHasCorrectRootDeviceIndex) { + cl_int retVal = 0; + std::unique_ptr buffer(Buffer::create(context.get(), 0, MemoryConstants::pageSize, nullptr, retVal)); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_NE(nullptr, buffer); + + auto bufferMemObj = static_cast(buffer.get()); + auto pBufferMemObj = &bufferMemObj; + + auto cmdQ1 = context->getSpecialQueue(1u); + retVal = cmdQ1->enqueueMigrateMemObjects(1, pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(buffer.get()->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 1u); + + retVal = cmdQ1->enqueueMigrateMemObjects(1, pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(buffer.get()->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 1u); + + auto cmdQ2 = context->getSpecialQueue(2u); + retVal = cmdQ2->enqueueMigrateMemObjects(1, pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(buffer.get()->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); + + retVal = cmdQ1->enqueueMigrateMemObjects(1, pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(buffer.get()->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 1u); + + static_cast(buffer.get()->getMigrateableMultiGraphicsAllocation().getGraphicsAllocation(2u))->overrideMemoryPool(MemoryPool::LocalMemory); + retVal = cmdQ2->enqueueMigrateMemObjects(1, pBufferMemObj, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(buffer.get()->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); +}