From bbf23df6eb3b31da18249907a2cf0b11fa84cae9 Mon Sep 17 00:00:00 2001 From: "Warchulski, Jaroslaw" Date: Fri, 21 Apr 2023 13:32:51 +0000 Subject: [PATCH] feature: add new API functions for external memory sharing Related-To: NEO-6757 Signed-off-by: Warchulski, Jaroslaw --- opencl/source/api/api.cpp | 63 +++++++ opencl/source/api/api.h | 24 +++ opencl/test/unit_test/api/CMakeLists.txt | 3 +- .../test/unit_test/api/api_tests_wrapper1.cpp | 3 +- .../cl_external_memory_extension_tests.inl | 158 ++++++++++++++++++ 5 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 opencl/test/unit_test/api/cl_external_memory_extension_tests.inl diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index f44794b48a..d15993ff04 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -4477,6 +4477,9 @@ void *CL_API_CALL clGetExtensionFunctionAddress(const char *funcName) { RETURN_FUNC_PTR_IF_EXIST(clGetKernelSuggestedLocalWorkSizeINTEL); RETURN_FUNC_PTR_IF_EXIST(clEnqueueNDCountKernelINTEL); + RETURN_FUNC_PTR_IF_EXIST(clEnqueueAcquireExternalMemObjectsKHR); + RETURN_FUNC_PTR_IF_EXIST(clEnqueueReleaseExternalMemObjectsKHR); + void *ret = sharingFactory.getExtensionFunctionAddress(funcName); if (ret != nullptr) { TRACING_EXIT(ClGetExtensionFunctionAddress, &ret); @@ -6134,3 +6137,63 @@ cl_int CL_API_CALL clSetContextDestructorCallback(cl_context context, return retVal; } + +cl_int CL_API_CALL clEnqueueExternalMemObjectsKHR( + cl_command_queue commandQueue, + cl_uint numMemObjects, + const cl_mem *memObjects, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event) { + + cl_int retVal = CL_SUCCESS; + API_ENTER(&retVal); + DBG_LOG_INPUTS("commandQueue", commandQueue, + "memObjects", getClFileLogger().getMemObjects(reinterpret_cast(memObjects), numMemObjects), + "eventWaitList", getClFileLogger().getEvents(reinterpret_cast(eventWaitList), numEventsInWaitList), + "event", getClFileLogger().getEvents(reinterpret_cast(event), 1)); + + auto pCommandQueue = castToObject(commandQueue); + + retVal = validateObjects(MemObjList(numMemObjects, memObjects), + withCastToInternal(commandQueue, &pCommandQueue), + EventWaitList(numEventsInWaitList, eventWaitList)); + + if (retVal != CL_SUCCESS) { + return retVal; + } + + for (unsigned int num = 0; num < numEventsInWaitList; num++) { + auto pEvent = castToObject(eventWaitList[num]); + if (pEvent->peekExecutionStatus() < CL_COMPLETE) { + retVal = CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST; + return retVal; + } + } + + retVal = pCommandQueue->enqueueMarkerWithWaitList(numEventsInWaitList, eventWaitList, event); + + return retVal; +} + +cl_int CL_API_CALL clEnqueueAcquireExternalMemObjectsKHR( + cl_command_queue commandQueue, + cl_uint numMemObjects, + const cl_mem *memObjects, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event) { + + return clEnqueueExternalMemObjectsKHR(commandQueue, numMemObjects, memObjects, numEventsInWaitList, eventWaitList, event); +} + +cl_int CL_API_CALL clEnqueueReleaseExternalMemObjectsKHR( + cl_command_queue commandQueue, + cl_uint numMemObjects, + const cl_mem *memObjects, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event) { + + return clEnqueueExternalMemObjectsKHR(commandQueue, numMemObjects, memObjects, numEventsInWaitList, eventWaitList, event); +} diff --git a/opencl/source/api/api.h b/opencl/source/api/api.h index 7eb5405da2..9adcd0c531 100644 --- a/opencl/source/api/api.h +++ b/opencl/source/api/api.h @@ -1101,3 +1101,27 @@ cl_int CL_API_CALL clSetContextDestructorCallback( cl_context context, void(CL_CALLBACK *pfnNotify)(cl_context /* context */, void * /* user_data */), void *userData); + +cl_int CL_API_CALL clEnqueueExternalMemObjectsKHR( + cl_command_queue commandQueue, + cl_uint numMemObjects, + const cl_mem *memObjects, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event); + +cl_int CL_API_CALL clEnqueueAcquireExternalMemObjectsKHR( + cl_command_queue commandQueue, + cl_uint numMemObjects, + const cl_mem *memObjects, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event); + +cl_int CL_API_CALL clEnqueueReleaseExternalMemObjectsKHR( + cl_command_queue commandQueue, + cl_uint numMemObjects, + const cl_mem *memObjects, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event); diff --git a/opencl/test/unit_test/api/CMakeLists.txt b/opencl/test/unit_test/api/CMakeLists.txt index 0632e2baff..d3e5128f3c 100644 --- a/opencl/test/unit_test/api/CMakeLists.txt +++ b/opencl/test/unit_test/api/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2022 Intel Corporation +# Copyright (C) 2018-2023 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -65,6 +65,7 @@ set(IGDRCL_SRCS_tests_api ${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_write_buffer_rect_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_write_buffer_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_write_image_tests.inl + ${CMAKE_CURRENT_SOURCE_DIR}/cl_external_memory_extension_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_finish_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_flush_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_function_pointers_tests.inl diff --git a/opencl/test/unit_test/api/api_tests_wrapper1.cpp b/opencl/test/unit_test/api/api_tests_wrapper1.cpp index 35feaf54ed..5da0e55f8b 100644 --- a/opencl/test/unit_test/api/api_tests_wrapper1.cpp +++ b/opencl/test/unit_test/api/api_tests_wrapper1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -35,5 +35,6 @@ #include "opencl/test/unit_test/api/cl_enqueue_map_image_tests.inl" #include "opencl/test/unit_test/api/cl_enqueue_marker_tests.inl" #include "opencl/test/unit_test/api/cl_enqueue_marker_with_wait_list_tests.inl" +#include "opencl/test/unit_test/api/cl_external_memory_extension_tests.inl" #include "opencl/test/unit_test/api/cl_function_pointers_tests.inl" #include "opencl/test/unit_test/api/cl_unified_shared_memory_tests.inl" diff --git a/opencl/test/unit_test/api/cl_external_memory_extension_tests.inl b/opencl/test/unit_test/api/cl_external_memory_extension_tests.inl new file mode 100644 index 0000000000..489f1737f5 --- /dev/null +++ b/opencl/test/unit_test/api/cl_external_memory_extension_tests.inl @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "opencl/test/unit_test/api/cl_api_tests.h" + +using namespace NEO; + +using ClExternalMemoryExtensionTests = ApiTests; + +TEST_F(ClExternalMemoryExtensionTests, GivenValidCommandQueueWhenEnqueingAcquireExternalMemObjectsKHRThenSuccessIsReturned) { + auto retVal = clEnqueueAcquireExternalMemObjectsKHR( + pCommandQueue, + 0, + nullptr, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); +} + +TEST_F(ClExternalMemoryExtensionTests, GivenValidCommandQueueWhenEnqueingReleaseExternalMemObjectsKHRThenSuccessIsReturned) { + auto retVal = clEnqueueReleaseExternalMemObjectsKHR( + pCommandQueue, + 0, + nullptr, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); +} + +TEST_F(ClExternalMemoryExtensionTests, GivenInvalidValueWhenEnqueingExternalMemObjectsKHRThenInvalidValueErrorIsReturned) { + auto retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 1, + nullptr, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_INVALID_VALUE, retVal); + + retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 0, + reinterpret_cast(pCommandQueue), + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_INVALID_VALUE, retVal); +} + +TEST_F(ClExternalMemoryExtensionTests, GivenInvalidMemObjectsWhenEnqueingExternalMemObjectsKHRThenInvalidMemObjectErrorIsReturned) { + auto retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 1, + reinterpret_cast(pCommandQueue), + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_INVALID_MEM_OBJECT, retVal); +} + +TEST_F(ClExternalMemoryExtensionTests, GivenValidInputsWhenEnqueingExternalMemObjectsKHRThenSuccessIsReturned) { + auto retVal = CL_SUCCESS; + + auto buffer = clCreateBuffer( + pContext, + CL_MEM_READ_WRITE, + 16, + nullptr, + &retVal); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_NE(nullptr, buffer); + + auto userEvent = clCreateUserEvent( + pContext, + &retVal); + + retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 1, + &buffer, + 1, + &userEvent, + nullptr); + EXPECT_EQ(CL_SUCCESS, retVal); + + retVal = clReleaseMemObject(buffer); + EXPECT_EQ(CL_SUCCESS, retVal); + + retVal = clReleaseEvent(userEvent); + EXPECT_EQ(CL_SUCCESS, retVal); +} + +TEST_F(ClExternalMemoryExtensionTests, GivenNullCommandQueueWhenEnqueingExternalMemObjectsKHRThenInvalidCommandQueueErrorIsReturned) { + auto retVal = clEnqueueExternalMemObjectsKHR( + nullptr, + 0, + nullptr, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_INVALID_COMMAND_QUEUE, retVal); +} + +TEST_F(ClExternalMemoryExtensionTests, GivenInvalidEventWaitListWhenEnqueingExternalMemObjectsKHRThenInvalidEventWaitListErrorIsReturned) { + auto retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 0, + nullptr, + 1, + nullptr, + nullptr); + EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, retVal); + + retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 0, + nullptr, + 0, + reinterpret_cast(pCommandQueue), + nullptr); + EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, retVal); + + retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 0, + nullptr, + 1, + reinterpret_cast(pCommandQueue), + nullptr); + EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, retVal); +} + +TEST_F(ClExternalMemoryExtensionTests, GivenUserEventWithErrorStatusWhenEnqueingExternalMemObjectsKHRThenExecStatusErrorForEventsInWaitListIsReturned) { + auto userEvent = clCreateUserEvent( + pContext, + &retVal); + + retVal = clSetUserEventStatus(userEvent, -1); + ASSERT_EQ(CL_SUCCESS, retVal); + + retVal = clEnqueueExternalMemObjectsKHR( + pCommandQueue, + 0, + nullptr, + 1, + &userEvent, + nullptr); + ASSERT_EQ(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST, retVal); + + retVal = clReleaseEvent(userEvent); + EXPECT_EQ(CL_SUCCESS, retVal); +}