diff --git a/.github/intel-llvm-mirror-base-commit b/.github/intel-llvm-mirror-base-commit index ccdde2d8ec..6ad41e8832 100644 --- a/.github/intel-llvm-mirror-base-commit +++ b/.github/intel-llvm-mirror-base-commit @@ -1 +1 @@ -84518c193adb9d8b03ae449345d892c6c9984846 +cbea6003f58953ebf25e1ed353d3d7ac37191e8c diff --git a/include/ur_api.h b/include/ur_api.h index 23b33c0f2e..e6f814e178 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -5722,6 +5722,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urProgramRelease( /// - ::UR_RESULT_ERROR_FUNCTION_ADDRESS_NOT_AVAILABLE /// + If `pFunctionName` could be located, but its address couldn't be /// retrieved. +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If the backend does not support querying function pointers. UR_APIEXPORT ur_result_t UR_APICALL urProgramGetFunctionPointer( /// [in] handle of the device to retrieve pointer for. ur_device_handle_t hDevice, diff --git a/scripts/core/program.yml b/scripts/core/program.yml index c6c2a9f83d..f2f1259a07 100644 --- a/scripts/core/program.yml +++ b/scripts/core/program.yml @@ -323,6 +323,8 @@ returns: - "If `pFunctionName` couldn't be found in `hProgram`." - $X_RESULT_ERROR_FUNCTION_ADDRESS_NOT_AVAILABLE: - "If `pFunctionName` could be located, but its address couldn't be retrieved." + - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: + - "If the backend does not support querying function pointers." --- #-------------------------------------------------------------------------- type: function desc: "Retrieves a pointer to a device global variable." diff --git a/source/adapters/level_zero/v2/command_list_manager.cpp b/source/adapters/level_zero/v2/command_list_manager.cpp index 753ad2e0af..9f5fa7e31a 100644 --- a/source/adapters/level_zero/v2/command_list_manager.cpp +++ b/source/adapters/level_zero/v2/command_list_manager.cpp @@ -907,19 +907,66 @@ ur_result_t ur_command_list_manager::bindlessImagesImageCopyExp( } ur_result_t ur_command_list_manager::bindlessImagesWaitExternalSemaphoreExp( - ur_exp_external_semaphore_handle_t /*hSemaphore*/, bool /*hasWaitValue*/, - uint64_t /*waitValue*/, uint32_t /*numEventsInWaitList*/, - const ur_event_handle_t * /*phEventWaitList*/, - ur_event_handle_t /*phEvent*/) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + ur_exp_external_semaphore_handle_t hSemaphore, bool hasWaitValue, + uint64_t waitValue, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t phEvent) { + auto hPlatform = hContext->getPlatform(); + if (!hPlatform->ZeExternalSemaphoreExt.Supported == false || + !hPlatform->ZeExternalSemaphoreExt.LoaderExtension) { + UR_LOG_LEGACY(ERR, + logger::LegacyMessage("[UR][L0] {} function not supported!"), + "{} function not supported!", __FUNCTION__); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + auto zeSignalEvent = + getSignalEvent(phEvent, UR_COMMAND_EXTERNAL_SEMAPHORE_WAIT_EXP); + auto [pWaitEvents, numWaitEvents] = + getWaitListView(phEventWaitList, numEventsInWaitList); + + ze_external_semaphore_wait_params_ext_t waitParams = { + ZE_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_WAIT_PARAMS_EXT, nullptr, 0}; + waitParams.value = hasWaitValue ? waitValue : 0; + ze_external_semaphore_ext_handle_t hExtSemaphore = + reinterpret_cast(hSemaphore); + ZE2UR_CALL(hPlatform->ZeExternalSemaphoreExt + .zexCommandListAppendWaitExternalSemaphoresExp, + (zeCommandList.get(), 1, &hExtSemaphore, &waitParams, + zeSignalEvent, numWaitEvents, pWaitEvents)); + + return UR_RESULT_SUCCESS; } ur_result_t ur_command_list_manager::bindlessImagesSignalExternalSemaphoreExp( - ur_exp_external_semaphore_handle_t /*hSemaphore*/, bool /*hasSignalValue*/, - uint64_t /*signalValue*/, uint32_t /*numEventsInWaitList*/, - const ur_event_handle_t * /*phEventWaitList*/, - ur_event_handle_t /*phEvent*/) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + ur_exp_external_semaphore_handle_t hSemaphore, bool hasSignalValue, + uint64_t signalValue, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t phEvent) { + auto hPlatform = hContext->getPlatform(); + if (!hPlatform->ZeExternalSemaphoreExt.Supported == false || + !hPlatform->ZeExternalSemaphoreExt.LoaderExtension) { + UR_LOG_LEGACY(ERR, + logger::LegacyMessage("[UR][L0] {} function not supported!"), + "{} function not supported!", __FUNCTION__); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + auto zeSignalEvent = + getSignalEvent(phEvent, UR_COMMAND_EXTERNAL_SEMAPHORE_SIGNAL_EXP); + auto [pWaitEvents, numWaitEvents] = + getWaitListView(phEventWaitList, numEventsInWaitList); + + ze_external_semaphore_signal_params_ext_t signalParams = { + ZE_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_EXT, nullptr, 0}; + signalParams.value = hasSignalValue ? signalValue : 0; + ze_external_semaphore_ext_handle_t hExtSemaphore = + reinterpret_cast(hSemaphore); + + ZE2UR_CALL(hPlatform->ZeExternalSemaphoreExt + .zexCommandListAppendSignalExternalSemaphoresExp, + (zeCommandList.get(), 1, &hExtSemaphore, &signalParams, + zeSignalEvent, numWaitEvents, pWaitEvents)); + + return UR_RESULT_SUCCESS; } ur_result_t ur_command_list_manager::appendNativeCommandExp( diff --git a/source/adapters/offload/program.cpp b/source/adapters/offload/program.cpp index b2297b2b4b..ec73469bfb 100644 --- a/source/adapters/offload/program.cpp +++ b/source/adapters/offload/program.cpp @@ -293,3 +293,12 @@ UR_APIEXPORT ur_result_t UR_APICALL urProgramGetGlobalVariablePointer( return UR_RESULT_SUCCESS; } + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramGetFunctionPointer([[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_program_handle_t hProgram, + [[maybe_unused]] const char *pFunctionName, + [[maybe_unused]] void **ppFunctionPointer) { + // liboffload doesn't support a representation of function pointers (yet) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/source/adapters/offload/ur_interface_loader.cpp b/source/adapters/offload/ur_interface_loader.cpp index 498b09d7da..5b4c8bd13b 100644 --- a/source/adapters/offload/ur_interface_loader.cpp +++ b/source/adapters/offload/ur_interface_loader.cpp @@ -91,7 +91,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramProcAddrTable( pDdiTable->pfnCreateWithIL = urProgramCreateWithIL; pDdiTable->pfnCreateWithNativeHandle = urProgramCreateWithNativeHandle; pDdiTable->pfnGetBuildInfo = nullptr; - pDdiTable->pfnGetFunctionPointer = nullptr; + pDdiTable->pfnGetFunctionPointer = urProgramGetFunctionPointer; pDdiTable->pfnGetGlobalVariablePointer = urProgramGetGlobalVariablePointer; pDdiTable->pfnGetInfo = urProgramGetInfo; pDdiTable->pfnGetNativeHandle = urProgramGetNativeHandle; diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index 286df652fe..a7559029e2 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -3438,6 +3438,8 @@ ur_result_t UR_APICALL urProgramRelease( /// - ::UR_RESULT_ERROR_FUNCTION_ADDRESS_NOT_AVAILABLE /// + If `pFunctionName` could be located, but its address couldn't be /// retrieved. +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If the backend does not support querying function pointers. ur_result_t UR_APICALL urProgramGetFunctionPointer( /// [in] handle of the device to retrieve pointer for. ur_device_handle_t hDevice, diff --git a/source/ur_api.cpp b/source/ur_api.cpp index be7e5662cd..4709496405 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -3024,6 +3024,8 @@ ur_result_t UR_APICALL urProgramRelease( /// - ::UR_RESULT_ERROR_FUNCTION_ADDRESS_NOT_AVAILABLE /// + If `pFunctionName` could be located, but its address couldn't be /// retrieved. +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If the backend does not support querying function pointers. ur_result_t UR_APICALL urProgramGetFunctionPointer( /// [in] handle of the device to retrieve pointer for. ur_device_handle_t hDevice, diff --git a/test/conformance/event/urEventSetCallback.cpp b/test/conformance/event/urEventSetCallback.cpp index 7479b50a2a..ac3086a2ec 100644 --- a/test/conformance/event/urEventSetCallback.cpp +++ b/test/conformance/event/urEventSetCallback.cpp @@ -6,9 +6,24 @@ #include "fixtures.h" #include "uur/known_failure.h" +using namespace std::chrono_literals; /* Using urEventReferenceTest to be able to release the event during the test */ -using urEventSetCallbackTest = uur::event::urEventReferenceTest; +struct urEventSetCallbackTest : uur::event::urEventReferenceTest { + std::mutex m; + std::condition_variable cv; + int flag = 0; + + void WaitForFlag(int Target = 1) { + std::unique_lock lk(m); + cv.wait_for(lk, 1000ms, [&] { return flag == Target; }); + } + + void SetFlag() { + flag++; + cv.notify_one(); + } +}; /** * Checks that the callback function is called. @@ -22,19 +37,19 @@ TEST_P(urEventSetCallbackTest, Success) { [[maybe_unused]] ur_execution_info_t execStatus, void *pUserData) { - auto status = reinterpret_cast(pUserData); - *status = true; + auto that = reinterpret_cast(pUserData); + that->SetFlag(); } }; - bool didRun = false; ASSERT_SUCCESS( urEventSetCallback(event, ur_execution_info_t::UR_EXECUTION_INFO_COMPLETE, - Callback::callback, &didRun)); + Callback::callback, this)); ASSERT_SUCCESS(urEventWait(1, &event)); ASSERT_SUCCESS(urEventRelease(event)); - ASSERT_TRUE(didRun); + WaitForFlag(); + ASSERT_EQ(flag, 1); } /** @@ -45,6 +60,7 @@ TEST_P(urEventSetCallbackTest, ValidateParameters) { uur::LevelZeroV2{}, uur::NativeCPU{}); struct CallbackParameters { + urEventSetCallbackTest *test; ur_event_handle_t event; ur_execution_info_t execStatus; }; @@ -56,10 +72,11 @@ TEST_P(urEventSetCallbackTest, ValidateParameters) { auto parameters = reinterpret_cast(pUserData); parameters->event = hEvent; parameters->execStatus = execStatus; + parameters->test->SetFlag(); } }; - CallbackParameters parameters{}; + CallbackParameters parameters{this, nullptr, UR_EXECUTION_INFO_QUEUED}; ASSERT_SUCCESS( urEventSetCallback(event, ur_execution_info_t::UR_EXECUTION_INFO_COMPLETE, @@ -67,6 +84,7 @@ TEST_P(urEventSetCallbackTest, ValidateParameters) { ASSERT_SUCCESS(urEventWait(1, &event)); ASSERT_SUCCESS(urEventRelease(event)); + WaitForFlag(); ASSERT_EQ(event, parameters.event); ASSERT_EQ(ur_execution_info_t::UR_EXECUTION_INFO_COMPLETE, parameters.execStatus); @@ -80,6 +98,7 @@ TEST_P(urEventSetCallbackTest, AllStates) { uur::LevelZeroV2{}, uur::NativeCPU{}); struct CallbackStatus { + urEventSetCallbackTest *test = nullptr; bool submitted = false; bool running = false; bool complete = false; @@ -107,10 +126,12 @@ TEST_P(urEventSetCallbackTest, AllStates) { FAIL() << "Invalid execution info enumeration"; } } + + status->test->SetFlag(); } }; - CallbackStatus status{}; + CallbackStatus status{this}; ASSERT_SUCCESS(urEventSetCallback( event, ur_execution_info_t::UR_EXECUTION_INFO_SUBMITTED, @@ -124,6 +145,7 @@ TEST_P(urEventSetCallbackTest, AllStates) { ASSERT_SUCCESS(urEventWait(1, &event)); ASSERT_SUCCESS(urEventRelease(event)); + WaitForFlag(3); ASSERT_TRUE(status.submitted); ASSERT_TRUE(status.running); @@ -145,19 +167,18 @@ TEST_P(urEventSetCallbackTest, EventAlreadyCompleted) { [[maybe_unused]] ur_execution_info_t execStatus, void *pUserData) { - auto status = reinterpret_cast(pUserData); - *status = true; + auto that = reinterpret_cast(pUserData); + that->SetFlag(); } }; - bool didRun = false; - ASSERT_SUCCESS( urEventSetCallback(event, ur_execution_info_t::UR_EXECUTION_INFO_COMPLETE, - Callback::callback, &didRun)); + Callback::callback, this)); ASSERT_SUCCESS(urEventRelease(event)); - ASSERT_TRUE(didRun); + WaitForFlag(); + ASSERT_EQ(flag, 1); } UUR_INSTANTIATE_DEVICE_TEST_SUITE(urEventSetCallbackTest); diff --git a/test/conformance/program/urProgramGetFunctionPointer.cpp b/test/conformance/program/urProgramGetFunctionPointer.cpp index 9243701000..83906dc9db 100644 --- a/test/conformance/program/urProgramGetFunctionPointer.cpp +++ b/test/conformance/program/urProgramGetFunctionPointer.cpp @@ -24,7 +24,8 @@ TEST_P(urProgramGetFunctionPointerTest, Success) { void *function_pointer = nullptr; ur_result_t res = urProgramGetFunctionPointer( device, program, function_name.data(), &function_pointer); - if (res == UR_RESULT_ERROR_FUNCTION_ADDRESS_NOT_AVAILABLE) { + if (res == UR_RESULT_ERROR_FUNCTION_ADDRESS_NOT_AVAILABLE || + res == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) { return; } ASSERT_SUCCESS(res); @@ -36,17 +37,10 @@ TEST_P(urProgramGetFunctionPointerTest, InvalidKernelName) { std::string missing_function = "aFakeFunctionName"; auto result = urProgramGetFunctionPointer( device, program, missing_function.data(), &function_pointer); - ur_backend_t backend; - ASSERT_SUCCESS(urPlatformGetInfo(platform, UR_PLATFORM_INFO_BACKEND, - sizeof(backend), &backend, nullptr)); - // TODO: level zero backend incorrectly returns - // UR_RESULT_ERROR_UNSUPPORTED_FEATURE - if (backend == UR_BACKEND_LEVEL_ZERO) { - ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); - } else { - ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_KERNEL_NAME, result); + if (result == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) { + return; } - + ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_KERNEL_NAME, result); ASSERT_EQ(function_pointer, nullptr); }