From 8f287375fa1e97a6d2307e9755af95ee1c230608 Mon Sep 17 00:00:00 2001 From: kweronsx Date: Mon, 1 Jun 2026 11:43:43 +0200 Subject: [PATCH] [SYCL][UR] Add reusable events --- .../include/unified-runtime/ur_api.h | 124 +++++++++++ .../include/unified-runtime/ur_api_funcs.def | 1 + .../include/unified-runtime/ur_ddi.h | 33 +++ .../include/unified-runtime/ur_print.h | 40 ++++ .../include/unified-runtime/ur_print.hpp | 199 ++++++++++++++++++ .../scripts/core/exp-reusable-events.yml | 107 ++++++++++ unified-runtime/scripts/core/registry.yml | 5 +- .../source/adapters/adapter.def.in | 1 + .../source/adapters/adapter.map.in | 1 + .../source/adapters/level_zero/event.cpp | 8 +- .../level_zero/ur_interface_loader.cpp | 16 ++ .../level_zero/ur_interface_loader.hpp | 4 + .../source/adapters/level_zero/v2/event.cpp | 6 + .../source/adapters/mock/ur_mockddi.cpp | 78 +++++++ .../source/adapters/opencl/event.cpp | 6 + .../adapters/opencl/ur_interface_loader.cpp | 12 ++ .../source/common/stype_map_helpers.def | 6 + .../loader/layers/tracing/ur_trcddi.cpp | 76 +++++++ .../loader/layers/validation/ur_valddi.cpp | 93 ++++++++ unified-runtime/source/loader/loader.def.in | 6 + unified-runtime/source/loader/loader.map.in | 6 + unified-runtime/source/loader/ur_ldrddi.cpp | 75 +++++++ unified-runtime/source/loader/ur_libapi.cpp | 54 +++++ unified-runtime/source/loader/ur_libddi.cpp | 5 + unified-runtime/source/loader/ur_print.cpp | 33 +++ unified-runtime/source/ur_api.cpp | 49 +++++ unified-runtime/tools/urinfo/urinfo.hpp | 5 + 27 files changed, 1047 insertions(+), 2 deletions(-) create mode 100644 unified-runtime/scripts/core/exp-reusable-events.yml diff --git a/unified-runtime/include/unified-runtime/ur_api.h b/unified-runtime/include/unified-runtime/ur_api.h index 5fe17e1eed9c3..a01b89445a726 100644 --- a/unified-runtime/include/unified-runtime/ur_api.h +++ b/unified-runtime/include/unified-runtime/ur_api.h @@ -512,6 +512,8 @@ typedef enum ur_function_t { UR_FUNCTION_QUEUE_GET_GRAPH_EXP = 314, /// Enumerator for ::urGraphSetDestructionCallbackExp UR_FUNCTION_GRAPH_SET_DESTRUCTION_CALLBACK_EXP = 315, + /// Enumerator for ::urEventCreateExp + UR_FUNCTION_EVENT_CREATE_EXP = 316, /// @cond UR_FUNCTION_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -631,6 +633,10 @@ typedef enum ur_structure_type_t { UR_STRUCTURE_TYPE_EXP_ENQUEUE_NATIVE_COMMAND_PROPERTIES = 0x3000, /// ::ur_exp_enqueue_ext_properties_t UR_STRUCTURE_TYPE_EXP_ENQUEUE_EXT_PROPERTIES = 0x4000, + /// ::ur_exp_event_create_properties_t + UR_STRUCTURE_TYPE_EXP_EVENT_CREATE_PROPERTIES = 0x4001, + /// ::ur_exp_enqueue_signal_event_properties_t + UR_STRUCTURE_TYPE_EXP_ENQUEUE_SIGNAL_EVENT_PROPERTIES = 0x4002, /// ::ur_exp_kernel_arg_properties_t UR_STRUCTURE_TYPE_EXP_KERNEL_ARG_PROPERTIES = 0x5000, /// ::ur_exp_host_task_properties_t @@ -2504,6 +2510,12 @@ typedef enum ur_device_info_t { /// [::ur_bool_t] returns true if the device supports inter-process /// communicable memory handles UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP = 0x2023, + /// [::ur_bool_t] returns true if the device supports reusable events + /// created with ::urEventCreateExp. + UR_DEVICE_INFO_REUSABLE_EVENTS_EXP = 0x2024, + /// [::ur_bool_t] returns true if the device supports profiling timestamps + /// for reusable events created with ::urEventCreateExp. + UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP = 0x2025, /// [::ur_bool_t] returns true if the device supports enqueueing of /// allocations and frees. UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP = 0x2050, @@ -13649,6 +13661,107 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueNativeCommandExp( /// array. ur_event_handle_t *phEvent); +#if !defined(__GNUC__) +#pragma endregion +#endif +// Intel 'oneAPI' Unified Runtime Experimental API for reusable events +#if !defined(__GNUC__) +#pragma region reusable_events_(experimental) +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Flags for creating a reusable event. +typedef uint32_t ur_exp_event_create_flags_t; +typedef enum ur_exp_event_create_flag_t { + /// Enables profiling timestamps for the event. + UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE = UR_BIT(0), + /// @cond + UR_EXP_EVENT_CREATE_FLAG_FORCE_UINT32 = 0x7fffffff + /// @endcond + +} ur_exp_event_create_flag_t; +/// @brief Bit Mask for validating ur_exp_event_create_flags_t +#define UR_EXP_EVENT_CREATE_FLAGS_MASK 0xfffffffe + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Properties for ::urEventCreateExp. +typedef struct ur_exp_event_create_properties_t { + /// [in] type of this structure, must be + /// ::UR_STRUCTURE_TYPE_EXP_EVENT_CREATE_PROPERTIES + ur_structure_type_t stype; + /// [in,out][optional] pointer to extension-specific structure + void *pNext; + /// [in] event creation flags + ur_exp_event_create_flags_t flags; + +} ur_exp_event_create_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Extended enqueue properties for specifying a pre-existing event to +/// signal. This structure may be passed via the pNext chain of +/// ::ur_exp_enqueue_ext_properties_t when calling +/// ::urEnqueueEventsWaitWithBarrierExt. When present, the implementation +/// signals hSignalEvent on completion instead of allocating a new event. +/// The handle value pointed to by hSignalEvent is never overwritten by +/// the implementation. +typedef struct ur_exp_enqueue_signal_event_properties_t { + /// [in] type of this structure, must be + /// ::UR_STRUCTURE_TYPE_EXP_ENQUEUE_SIGNAL_EVENT_PROPERTIES + ur_structure_type_t stype; + /// [in,out][optional] pointer to extension-specific structure + void *pNext; + /// [in] handle of an existing reusable event to signal on completion. The + /// handle value is not modified by the implementation. The event must + /// have been created with ::urEventCreateExp. + ur_event_handle_t hSignalEvent; + +} ur_exp_enqueue_signal_event_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Create a reusable event object. +/// +/// @details +/// - A reusable event can be associated with at most one in-flight command +/// at a time, but may be reused across multiple successive commands. +/// - The event is initially in the completed state. +/// - The context and device must be compatible: hDevice must be one of the +/// devices associated with hContext. +/// - To enable profiling timestamps, pass +/// ::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE in pProperties->flags. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `NULL != pProperties && ::UR_EXP_EVENT_CREATE_FLAGS_MASK & +/// pProperties->flags` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phEvent` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_DEVICE +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + `pProperties != NULL && pProperties->flags & +/// ~::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE` +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If ::UR_DEVICE_INFO_REUSABLE_EVENTS_EXP is false. +/// + If ::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE is set and +/// ::UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP is false. +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urEventCreateExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device on which the event will be used + ur_device_handle_t hDevice, + /// [in][optional] pointer to event creation properties + const ur_exp_event_create_properties_t *pProperties, + /// [out][alloc] pointer to handle of the created event object + ur_event_handle_t *phEvent); + #if !defined(__GNUC__) #pragma endregion #endif @@ -14273,6 +14386,17 @@ typedef struct ur_event_set_callback_params_t { void **ppUserData; } ur_event_set_callback_params_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urEventCreateExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_event_create_exp_params_t { + ur_context_handle_t *phContext; + ur_device_handle_t *phDevice; + const ur_exp_event_create_properties_t **ppProperties; + ur_event_handle_t **pphEvent; +} ur_event_create_exp_params_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urProgramCreateWithIL /// @details Each entry is a pointer to the parameter passed to the function; diff --git a/unified-runtime/include/unified-runtime/ur_api_funcs.def b/unified-runtime/include/unified-runtime/ur_api_funcs.def index fc481d947a8c7..6126600a9b934 100644 --- a/unified-runtime/include/unified-runtime/ur_api_funcs.def +++ b/unified-runtime/include/unified-runtime/ur_api_funcs.def @@ -44,6 +44,7 @@ _UR_API(urEventRelease) _UR_API(urEventGetNativeHandle) _UR_API(urEventCreateWithNativeHandle) _UR_API(urEventSetCallback) +_UR_API(urEventCreateExp) _UR_API(urProgramCreateWithIL) _UR_API(urProgramCreateWithBinary) _UR_API(urProgramBuild) diff --git a/unified-runtime/include/unified-runtime/ur_ddi.h b/unified-runtime/include/unified-runtime/ur_ddi.h index cc734e6194d92..a63a6ff2c31fa 100644 --- a/unified-runtime/include/unified-runtime/ur_ddi.h +++ b/unified-runtime/include/unified-runtime/ur_ddi.h @@ -301,6 +301,38 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( typedef ur_result_t(UR_APICALL *ur_pfnGetEventProcAddrTable_t)( ur_api_version_t, ur_event_dditable_t *); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urEventCreateExp +typedef ur_result_t(UR_APICALL *ur_pfnEventCreateExp_t)( + ur_context_handle_t, ur_device_handle_t, + const ur_exp_event_create_properties_t *, ur_event_handle_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Table of EventExp functions pointers +typedef struct ur_event_exp_dditable_t { + ur_pfnEventCreateExp_t pfnCreateExp; +} ur_event_exp_dditable_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's EventExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetEventExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_event_exp_dditable_t *pDdiTable); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urGetEventExpProcAddrTable +typedef ur_result_t(UR_APICALL *ur_pfnGetEventExpProcAddrTable_t)( + ur_api_version_t, ur_event_exp_dditable_t *); + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urProgramCreateWithIL typedef ur_result_t(UR_APICALL *ur_pfnProgramCreateWithIL_t)( @@ -2258,6 +2290,7 @@ typedef struct ur_dditable_t { ur_platform_dditable_t Platform; ur_context_dditable_t Context; ur_event_dditable_t Event; + ur_event_exp_dditable_t EventExp; ur_program_dditable_t Program; ur_program_exp_dditable_t ProgramExp; ur_kernel_dditable_t Kernel; diff --git a/unified-runtime/include/unified-runtime/ur_print.h b/unified-runtime/include/unified-runtime/ur_print.h index d9acae65c7d07..41fab94a520c3 100644 --- a/unified-runtime/include/unified-runtime/ur_print.h +++ b/unified-runtime/include/unified-runtime/ur_print.h @@ -1564,6 +1564,36 @@ UR_APIEXPORT ur_result_t UR_APICALL urPrintExpEnqueueNativeCommandProperties( const struct ur_exp_enqueue_native_command_properties_t params, char *buffer, const size_t buff_size, size_t *out_size); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_exp_event_create_flag_t enum +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL +urPrintExpEventCreateFlags(enum ur_exp_event_create_flag_t value, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_exp_event_create_properties_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintExpEventCreateProperties( + const struct ur_exp_event_create_properties_t params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_exp_enqueue_signal_event_properties_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintExpEnqueueSignalEventProperties( + const struct ur_exp_enqueue_signal_event_properties_t params, char *buffer, + const size_t buff_size, size_t *out_size); + /////////////////////////////////////////////////////////////////////////////// /// @brief Print ur_loader_config_create_params_t struct /// @returns @@ -1915,6 +1945,16 @@ UR_APIEXPORT ur_result_t UR_APICALL urPrintEventSetCallbackParams( const struct ur_event_set_callback_params_t *params, char *buffer, const size_t buff_size, size_t *out_size); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_event_create_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintEventCreateExpParams( + const struct ur_event_create_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + /////////////////////////////////////////////////////////////////////////////// /// @brief Print ur_program_create_with_il_params_t struct /// @returns diff --git a/unified-runtime/include/unified-runtime/ur_print.hpp b/unified-runtime/include/unified-runtime/ur_print.hpp index c29373a7d162a..1fbf04fc6d125 100644 --- a/unified-runtime/include/unified-runtime/ur_print.hpp +++ b/unified-runtime/include/unified-runtime/ur_print.hpp @@ -292,6 +292,10 @@ inline ur_result_t printFlag(std::ostream &os, uint32_t flag); +template <> +inline ur_result_t printFlag(std::ostream &os, + uint32_t flag); + } // namespace ur::details inline std::ostream &operator<<(std::ostream &os, @@ -652,6 +656,15 @@ inline std::ostream &operator<<( std::ostream &os, [[maybe_unused]] const struct ur_exp_enqueue_native_command_properties_t params); +inline std::ostream &operator<<(std::ostream &os, + enum ur_exp_event_create_flag_t value); +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_exp_event_create_properties_t params); +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_exp_enqueue_signal_event_properties_t + params); /////////////////////////////////////////////////////////////////////////////// /// @brief Print operator for the ur_function_t type @@ -1380,6 +1393,9 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_function_t value) { case UR_FUNCTION_GRAPH_SET_DESTRUCTION_CALLBACK_EXP: os << "UR_FUNCTION_GRAPH_SET_DESTRUCTION_CALLBACK_EXP"; break; + case UR_FUNCTION_EVENT_CREATE_EXP: + os << "UR_FUNCTION_EVENT_CREATE_EXP"; + break; default: os << "unknown enumerator"; break; @@ -1558,6 +1574,12 @@ inline std::ostream &operator<<(std::ostream &os, case UR_STRUCTURE_TYPE_EXP_ENQUEUE_EXT_PROPERTIES: os << "UR_STRUCTURE_TYPE_EXP_ENQUEUE_EXT_PROPERTIES"; break; + case UR_STRUCTURE_TYPE_EXP_EVENT_CREATE_PROPERTIES: + os << "UR_STRUCTURE_TYPE_EXP_EVENT_CREATE_PROPERTIES"; + break; + case UR_STRUCTURE_TYPE_EXP_ENQUEUE_SIGNAL_EVENT_PROPERTIES: + os << "UR_STRUCTURE_TYPE_EXP_ENQUEUE_SIGNAL_EVENT_PROPERTIES"; + break; case UR_STRUCTURE_TYPE_EXP_KERNEL_ARG_PROPERTIES: os << "UR_STRUCTURE_TYPE_EXP_KERNEL_ARG_PROPERTIES"; break; @@ -1902,6 +1924,18 @@ inline ur_result_t printStruct(std::ostream &os, const void *ptr) { printPtr(os, pstruct); } break; + case UR_STRUCTURE_TYPE_EXP_EVENT_CREATE_PROPERTIES: { + const ur_exp_event_create_properties_t *pstruct = + (const ur_exp_event_create_properties_t *)ptr; + printPtr(os, pstruct); + } break; + + case UR_STRUCTURE_TYPE_EXP_ENQUEUE_SIGNAL_EVENT_PROPERTIES: { + const ur_exp_enqueue_signal_event_properties_t *pstruct = + (const ur_exp_enqueue_signal_event_properties_t *)ptr; + printPtr(os, pstruct); + } break; + case UR_STRUCTURE_TYPE_EXP_KERNEL_ARG_PROPERTIES: { const ur_exp_kernel_arg_properties_t *pstruct = (const ur_exp_kernel_arg_properties_t *)ptr; @@ -3309,6 +3343,12 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_device_info_t value) { case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: os << "UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP"; break; + case UR_DEVICE_INFO_REUSABLE_EVENTS_EXP: + os << "UR_DEVICE_INFO_REUSABLE_EVENTS_EXP"; + break; + case UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP: + os << "UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP"; + break; case UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP: os << "UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP"; break; @@ -5594,6 +5634,32 @@ inline ur_result_t printTagged(std::ostream &os, const void *ptr, os << ")"; } break; + case UR_DEVICE_INFO_REUSABLE_EVENTS_EXP: { + const ur_bool_t *tptr = (const ur_bool_t *)ptr; + if (sizeof(ur_bool_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(ur_bool_t) << ")"; + return UR_RESULT_ERROR_INVALID_SIZE; + } + os << (const void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; + case UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP: { + const ur_bool_t *tptr = (const ur_bool_t *)ptr; + if (sizeof(ur_bool_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(ur_bool_t) << ")"; + return UR_RESULT_ERROR_INVALID_SIZE; + } + os << (const void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; case UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP: { const ur_bool_t *tptr = (const ur_bool_t *)ptr; if (sizeof(ur_bool_t) > size) { @@ -13307,6 +13373,106 @@ operator<<(std::ostream &os, os << "}"; return os; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_exp_event_create_flag_t type +/// @returns +/// std::ostream & +inline std::ostream &operator<<(std::ostream &os, + enum ur_exp_event_create_flag_t value) { + switch (value) { + case UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE: + os << "UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE"; + break; + default: + os << "unknown enumerator"; + break; + } + return os; +} + +namespace ur::details { +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_exp_event_create_flag_t flag +template <> +inline ur_result_t printFlag(std::ostream &os, + uint32_t flag) { + uint32_t val = flag; + bool first = true; + + if ((val & UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE) == + (uint32_t)UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE) { + val ^= (uint32_t)UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE; + if (!first) { + os << " | "; + } else { + first = false; + } + os << UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE; + } + if (val != 0) { + std::bitset<32> bits(val); + if (!first) { + os << " | "; + } + os << "unknown bit flags " << bits; + } else if (first) { + os << "0"; + } + return UR_RESULT_SUCCESS; +} +} // namespace ur::details +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_exp_event_create_properties_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_exp_event_create_properties_t params) { + os << "(struct ur_exp_event_create_properties_t){"; + + os << ".stype = "; + + os << (params.stype); + + os << ", "; + os << ".pNext = "; + + ur::details::printStruct(os, (params.pNext)); + + os << ", "; + os << ".flags = "; + + ur::details::printFlag(os, (params.flags)); + + os << "}"; + return os; +} +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_exp_enqueue_signal_event_properties_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_exp_enqueue_signal_event_properties_t params) { + os << "(struct ur_exp_enqueue_signal_event_properties_t){"; + + os << ".stype = "; + + os << (params.stype); + + os << ", "; + os << ".pNext = "; + + ur::details::printStruct(os, (params.pNext)); + + os << ", "; + os << ".hSignalEvent = "; + + ur::details::printPtr(os, (params.hSignalEvent)); + + os << "}"; + return os; +} /////////////////////////////////////////////////////////////////////////////// /// @brief Print operator for the ur_loader_config_create_params_t type @@ -14234,6 +14400,36 @@ inline std::ostream &operator<<( return os; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_event_create_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, + [[maybe_unused]] const struct ur_event_create_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".hDevice = "; + + ur::details::printPtr(os, *(params->phDevice)); + + os << ", "; + os << ".pProperties = "; + + ur::details::printPtr(os, *(params->ppProperties)); + + os << ", "; + os << ".phEvent = "; + + ur::details::printPtr(os, *(params->pphEvent)); + + return os; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Print operator for the ur_program_create_with_il_params_t type /// @returns @@ -22688,6 +22884,9 @@ inline ur_result_t UR_APICALL printFunctionParams(std::ostream &os, case UR_FUNCTION_EVENT_SET_CALLBACK: { os << (const struct ur_event_set_callback_params_t *)params; } break; + case UR_FUNCTION_EVENT_CREATE_EXP: { + os << (const struct ur_event_create_exp_params_t *)params; + } break; case UR_FUNCTION_PROGRAM_CREATE_WITH_IL: { os << (const struct ur_program_create_with_il_params_t *)params; } break; diff --git a/unified-runtime/scripts/core/exp-reusable-events.yml b/unified-runtime/scripts/core/exp-reusable-events.yml new file mode 100644 index 0000000000000..bc7e1f6904dd5 --- /dev/null +++ b/unified-runtime/scripts/core/exp-reusable-events.yml @@ -0,0 +1,107 @@ +# +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# See YaML.md for syntax definition +# +--- #-------------------------------------------------------------------------- +type: header +desc: "Intel $OneApi Unified Runtime Experimental API for reusable events" +ordinal: "100" +--- #-------------------------------------------------------------------------- +type: enum +extend: true +typed_etors: true +desc: "Extension enums to $x_device_info_t to support reusable events." +name: $x_device_info_t +etors: + - name: REUSABLE_EVENTS_EXP + value: "0x2024" + desc: "[$x_bool_t] returns true if the device supports reusable events created with $xEventCreateExp." + - name: REUSABLE_EVENTS_PROFILING_EXP + value: "0x2025" + desc: "[$x_bool_t] returns true if the device supports profiling timestamps for reusable events created with $xEventCreateExp." +--- #-------------------------------------------------------------------------- +type: enum +desc: "Flags for creating a reusable event." +name: $x_exp_event_create_flags_t +etors: + - name: PROFILING_ENABLE + value: "$X_BIT(0)" + desc: "Enables profiling timestamps for the event." +--- #-------------------------------------------------------------------------- +type: struct +desc: "Properties for $xEventCreateExp." +name: $x_exp_event_create_properties_t +base: $x_base_properties_t +members: + - type: $x_exp_event_create_flags_t + name: flags + desc: "[in] event creation flags" +--- #-------------------------------------------------------------------------- +type: struct +desc: > + Extended enqueue properties for specifying a pre-existing event to signal. + This structure may be passed via the pNext chain of + $x_exp_enqueue_ext_properties_t when calling + $xEnqueueEventsWaitWithBarrierExt. When present, the implementation + signals hSignalEvent on completion instead of allocating a new event. + The handle value pointed to by hSignalEvent is never overwritten by the + implementation. +name: $x_exp_enqueue_signal_event_properties_t +base: $x_base_properties_t +members: + - type: $x_event_handle_t + name: hSignalEvent + desc: > + [in] handle of an existing reusable event to signal on completion. + The handle value is not modified by the implementation. + The event must have been created with $xEventCreateExp. +--- #-------------------------------------------------------------------------- +type: enum +extend: true +desc: "Structure type experimental enumerations to support reusable events." +name: $x_structure_type_t +etors: + - name: EXP_EVENT_CREATE_PROPERTIES + desc: $x_exp_event_create_properties_t + value: "0x4001" + - name: EXP_ENQUEUE_SIGNAL_EVENT_PROPERTIES + desc: $x_exp_enqueue_signal_event_properties_t + value: "0x4002" +--- #-------------------------------------------------------------------------- +type: function +desc: "Create a reusable event object." +class: $xEvent +name: CreateExp +ordinal: "0" +details: + - "A reusable event can be associated with at most one in-flight command at a time, but may be reused across multiple successive commands." + - "The event is initially in the completed state." + - "The context and device must be compatible: hDevice must be one of the devices associated with hContext." + - "To enable profiling timestamps, pass $X_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE in pProperties->flags." +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: $x_device_handle_t + name: hDevice + desc: "[in] handle of the device on which the event will be used" + - type: const $x_exp_event_create_properties_t* + name: pProperties + desc: "[in][optional] pointer to event creation properties" + - type: $x_event_handle_t* + name: phEvent + desc: "[out][alloc] pointer to handle of the created event object" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_DEVICE + - $X_RESULT_ERROR_INVALID_VALUE: + - "`pProperties != NULL && pProperties->flags & ~$X_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE`" + - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: + - "If $X_DEVICE_INFO_REUSABLE_EVENTS_EXP is false." + - "If $X_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE is set and $X_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP is false." + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES diff --git a/unified-runtime/scripts/core/registry.yml b/unified-runtime/scripts/core/registry.yml index f7a11b40c6547..29e7962dba9b1 100644 --- a/unified-runtime/scripts/core/registry.yml +++ b/unified-runtime/scripts/core/registry.yml @@ -727,7 +727,10 @@ etors: - name: GRAPH_SET_DESTRUCTION_CALLBACK_EXP desc: Enumerator for $xGraphSetDestructionCallbackExp value: '315' -max_id: '315' +- name: EVENT_CREATE_EXP + desc: Enumerator for $xEventCreateExp + value: '316' +max_id: '316' --- type: enum desc: Defines structure types diff --git a/unified-runtime/source/adapters/adapter.def.in b/unified-runtime/source/adapters/adapter.def.in index 51b2c228036c3..60910ce5fbd1d 100644 --- a/unified-runtime/source/adapters/adapter.def.in +++ b/unified-runtime/source/adapters/adapter.def.in @@ -7,6 +7,7 @@ EXPORTS urGetEnqueueProcAddrTable urGetEnqueueExpProcAddrTable urGetEventProcAddrTable + urGetEventExpProcAddrTable urGetGraphExpProcAddrTable urGetIPCExpProcAddrTable urGetKernelProcAddrTable diff --git a/unified-runtime/source/adapters/adapter.map.in b/unified-runtime/source/adapters/adapter.map.in index 18beaa3e6ce38..a8d2ad8d783ad 100644 --- a/unified-runtime/source/adapters/adapter.map.in +++ b/unified-runtime/source/adapters/adapter.map.in @@ -7,6 +7,7 @@ urGetEnqueueProcAddrTable; urGetEnqueueExpProcAddrTable; urGetEventProcAddrTable; + urGetEventExpProcAddrTable; urGetGraphExpProcAddrTable; urGetIPCExpProcAddrTable; urGetKernelProcAddrTable; diff --git a/unified-runtime/source/adapters/level_zero/event.cpp b/unified-runtime/source/adapters/level_zero/event.cpp index 8e31eb5991f14..a7ba757d36d04 100644 --- a/unified-runtime/source/adapters/level_zero/event.cpp +++ b/unified-runtime/source/adapters/level_zero/event.cpp @@ -1013,6 +1013,12 @@ ur_result_t urEventSetCallback( return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } +ur_result_t urEventCreateExp(ur_context_handle_t, ur_device_handle_t, + const ur_exp_event_create_properties_t *, + ur_event_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + } // namespace ur::level_zero ur_result_t ur_event_handle_t_::getOrCreateHostVisibleEvent( @@ -1773,7 +1779,7 @@ ur_result_t ur_ze_event_list_t::collectEventsForReleaseAndDestroyUrZeEventList( return UR_RESULT_SUCCESS; } -// Tells if this event is with profiling capabilities. +// Tells if this event is with profiling capabilities: bool ur_event_handle_t_::isProfilingEnabled() const { return !UrQueue || // tentatively assume user events are profiling enabled (UrQueue->Properties & UR_QUEUE_FLAG_PROFILING_ENABLE) != 0; diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp index dc76f7729f937..2b1599c35b7bb 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp @@ -261,6 +261,18 @@ UR_APIEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +UR_APIEXPORT ur_result_t UR_APICALL urGetEventExpProcAddrTable( + ur_api_version_t version, ur_event_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnCreateExp = ur::level_zero::urEventCreateExp; + + return result; +} + UR_APIEXPORT ur_result_t UR_APICALL urGetGraphExpProcAddrTable( ur_api_version_t version, ur_graph_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -668,6 +680,10 @@ ur_result_t populateDdiTable(ur_dditable_t *ddi) { NAMESPACE_::urGetEventProcAddrTable(UR_API_VERSION_CURRENT, &ddi->Event); if (result != UR_RESULT_SUCCESS) return result; + result = NAMESPACE_::urGetEventExpProcAddrTable(UR_API_VERSION_CURRENT, + &ddi->EventExp); + if (result != UR_RESULT_SUCCESS) + return result; result = NAMESPACE_::urGetGraphExpProcAddrTable(UR_API_VERSION_CURRENT, &ddi->GraphExp); if (result != UR_RESULT_SUCCESS) diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp index b56cc5e803c5d..eb4e5de3020ab 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp @@ -842,6 +842,10 @@ ur_result_t urEnqueueNativeCommandExp( const ur_exp_enqueue_native_command_properties_t *pProperties, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent); +ur_result_t +urEventCreateExp(ur_context_handle_t hContext, ur_device_handle_t hDevice, + const ur_exp_event_create_properties_t *pProperties, + ur_event_handle_t *phEvent); ur_result_t urGraphCreateExp(ur_context_handle_t hContext, ur_exp_graph_handle_t *phGraph); ur_result_t urQueueBeginGraphCaptureExp(ur_queue_handle_t hQueue); diff --git a/unified-runtime/source/adapters/level_zero/v2/event.cpp b/unified-runtime/source/adapters/level_zero/v2/event.cpp index 2b5871e371a24..07ddb8121364c 100644 --- a/unified-runtime/source/adapters/level_zero/v2/event.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/event.cpp @@ -397,6 +397,12 @@ ur_result_t urEventGetNativeHandle(ur_event_handle_t hEvent, return exceptionToResult(std::current_exception()); } +ur_result_t urEventCreateExp(ur_context_handle_t, ur_device_handle_t, + const ur_exp_event_create_properties_t *, + ur_event_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + ur_result_t urEventCreateWithNativeHandle(ur_native_handle_t hNativeEvent, ur_context_handle_t hContext, diff --git a/unified-runtime/source/adapters/mock/ur_mockddi.cpp b/unified-runtime/source/adapters/mock/ur_mockddi.cpp index 195702990d65c..45bb7ad30b773 100644 --- a/unified-runtime/source/adapters/mock/ur_mockddi.cpp +++ b/unified-runtime/source/adapters/mock/ur_mockddi.cpp @@ -12444,6 +12444,56 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueNativeCommandExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urEventCreateExp +__urdlllocal ur_result_t UR_APICALL urEventCreateExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device on which the event will be used + ur_device_handle_t hDevice, + /// [in][optional] pointer to event creation properties + const ur_exp_event_create_properties_t *pProperties, + /// [out][alloc] pointer to handle of the created event object + ur_event_handle_t *phEvent) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_event_create_exp_params_t params = {&hContext, &hDevice, &pProperties, + &phEvent}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urEventCreateExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urEventCreateExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + *phEvent = mock::createDummyHandle(); + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urEventCreateExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urGraphCreateExp __urdlllocal ur_result_t UR_APICALL urGraphCreateExp( @@ -13476,6 +13526,34 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's EventExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetEventExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_event_exp_dditable_t *pDdiTable) try { + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (driver::d_context.version < version) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + pDdiTable->pfnCreateExp = driver::urEventCreateExp; + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's GraphExp table /// with current process' addresses diff --git a/unified-runtime/source/adapters/opencl/event.cpp b/unified-runtime/source/adapters/opencl/event.cpp index f1695c47cf9e2..4628c60977d5a 100644 --- a/unified-runtime/source/adapters/opencl/event.cpp +++ b/unified-runtime/source/adapters/opencl/event.cpp @@ -305,3 +305,9 @@ urEnqueueTimestampRecordingExp(ur_queue_handle_t, bool, uint32_t, const ur_event_handle_t *, ur_event_handle_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } + +UR_APIEXPORT ur_result_t UR_APICALL urEventCreateExp( + ur_context_handle_t, ur_device_handle_t, + const ur_exp_event_create_properties_t *, ur_event_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp index 3205af2df209e..243649297a46f 100644 --- a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp @@ -248,6 +248,17 @@ urGetUSMProcAddrTable(ur_api_version_t Version, ur_usm_dditable_t *pDdiTable) { return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetEventExpProcAddrTable( + ur_api_version_t Version, ur_event_exp_dditable_t *pDdiTable) { + auto Result = validateProcInputs(Version, pDdiTable); + if (UR_RESULT_SUCCESS != Result) { + return Result; + } + + pDdiTable->pfnCreateExp = urEventCreateExp; + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetUSMExpProcAddrTable( ur_api_version_t Version, ur_usm_exp_dditable_t *pDdiTable) { auto Result = validateProcInputs(Version, pDdiTable); @@ -520,6 +531,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); + urGetEventExpProcAddrTable(version, &pDdiTable->EventExp); urGetGraphExpProcAddrTable(version, &pDdiTable->GraphExp); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/common/stype_map_helpers.def b/unified-runtime/source/common/stype_map_helpers.def index e37724e0f1781..37da30f7f9111 100644 --- a/unified-runtime/source/common/stype_map_helpers.def +++ b/unified-runtime/source/common/stype_map_helpers.def @@ -177,6 +177,12 @@ template <> struct stype_map : stype_map_impl {}; template <> +struct stype_map + : stype_map_impl {}; +template <> +struct stype_map + : stype_map_impl {}; +template <> struct stype_map : stype_map_impl {}; template <> diff --git a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp index 5f8bfca375b61..547926e632a29 100644 --- a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp +++ b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp @@ -10565,6 +10565,46 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueNativeCommandExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urEventCreateExp +__urdlllocal ur_result_t UR_APICALL urEventCreateExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device on which the event will be used + ur_device_handle_t hDevice, + /// [in][optional] pointer to event creation properties + const ur_exp_event_create_properties_t *pProperties, + /// [out][alloc] pointer to handle of the created event object + ur_event_handle_t *phEvent) { + auto pfnCreateExp = getContext()->urDdiTable.EventExp.pfnCreateExp; + + if (nullptr == pfnCreateExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_event_create_exp_params_t params = {&hContext, &hDevice, &pProperties, + &phEvent}; + uint64_t instance = getContext()->notify_begin(UR_FUNCTION_EVENT_CREATE_EXP, + "urEventCreateExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urEventCreateExp\n"); + + ur_result_t result = pfnCreateExp(hContext, hDevice, pProperties, phEvent); + + getContext()->notify_end(UR_FUNCTION_EVENT_CREATE_EXP, "urEventCreateExp", + ¶ms, &result, instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams(args_str, UR_FUNCTION_EVENT_CREATE_EXP, + ¶ms); + UR_LOG_L(logger, INFO, " <--- urEventCreateExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urGraphCreateExp __urdlllocal ur_result_t UR_APICALL urGraphCreateExp( @@ -11640,6 +11680,37 @@ __urdlllocal ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } /////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's EventExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +__urdlllocal ur_result_t UR_APICALL urGetEventExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_event_exp_dditable_t *pDdiTable) { + auto &dditable = ur_tracing_layer::getContext()->urDdiTable.EventExp; + + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (UR_MAJOR_VERSION(ur_tracing_layer::getContext()->version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_tracing_layer::getContext()->version) > + UR_MINOR_VERSION(version)) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnCreateExp = pDdiTable->pfnCreateExp; + pDdiTable->pfnCreateExp = ur_tracing_layer::urEventCreateExp; + + return result; +} +/////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's GraphExp table /// with current process' addresses /// @@ -12620,6 +12691,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable, &dditable->Event); } + if (UR_RESULT_SUCCESS == result) { + result = ur_tracing_layer::urGetEventExpProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->EventExp); + } + if (UR_RESULT_SUCCESS == result) { result = ur_tracing_layer::urGetGraphExpProcAddrTable( UR_API_VERSION_CURRENT, &dditable->GraphExp); diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index 077e6b736846a..d2ee6e4723a84 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -11414,6 +11414,62 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueNativeCommandExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urEventCreateExp +__urdlllocal ur_result_t UR_APICALL urEventCreateExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device on which the event will be used + ur_device_handle_t hDevice, + /// [in][optional] pointer to event creation properties + const ur_exp_event_create_properties_t *pProperties, + /// [out][alloc] pointer to handle of the created event object + ur_event_handle_t *phEvent) { + auto pfnCreateExp = getContext()->urDdiTable.EventExp.pfnCreateExp; + + if (nullptr == pfnCreateExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == phEvent) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + + if (NULL == hDevice) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + + if (NULL != pProperties && + UR_EXP_EVENT_CREATE_FLAGS_MASK & pProperties->flags) + return UR_RESULT_ERROR_INVALID_ENUMERATION; + + if (pProperties != NULL && + pProperties->flags & ~UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE) + return UR_RESULT_ERROR_INVALID_VALUE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hDevice)) { + URLOG_CTX_INVALID_REFERENCE(hDevice); + } + + ur_result_t result = pfnCreateExp(hContext, hDevice, pProperties, phEvent); + + if (getContext()->enableLeakChecking && result == UR_RESULT_SUCCESS && + phEvent) { + getContext()->refCountContext->createRefCount(*phEvent); + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urGraphCreateExp __urdlllocal ur_result_t UR_APICALL urGraphCreateExp( @@ -12409,6 +12465,38 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's EventExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetEventExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_event_exp_dditable_t *pDdiTable) { + auto &dditable = ur_validation_layer::getContext()->urDdiTable.EventExp; + + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (UR_MAJOR_VERSION(ur_validation_layer::getContext()->version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_validation_layer::getContext()->version) > + UR_MINOR_VERSION(version)) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnCreateExp = pDdiTable->pfnCreateExp; + pDdiTable->pfnCreateExp = ur_validation_layer::urEventCreateExp; + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's GraphExp table /// with current process' addresses @@ -13428,6 +13516,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable, UR_API_VERSION_CURRENT, &dditable->Event); } + if (UR_RESULT_SUCCESS == result) { + result = ur_validation_layer::urGetEventExpProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->EventExp); + } + if (UR_RESULT_SUCCESS == result) { result = ur_validation_layer::urGetGraphExpProcAddrTable( UR_API_VERSION_CURRENT, &dditable->GraphExp); diff --git a/unified-runtime/source/loader/loader.def.in b/unified-runtime/source/loader/loader.def.in index cc6ec03371edb..360786d29f252 100644 --- a/unified-runtime/source/loader/loader.def.in +++ b/unified-runtime/source/loader/loader.def.in @@ -106,6 +106,7 @@ EXPORTS urEnqueueUSMPrefetch urEnqueueUSMSharedAllocExp urEnqueueWriteHostPipe + urEventCreateExp urEventCreateWithNativeHandle urEventGetInfo urEventGetNativeHandle @@ -122,6 +123,7 @@ EXPORTS urGetDeviceProcAddrTable urGetEnqueueExpProcAddrTable urGetEnqueueProcAddrTable + urGetEventExpProcAddrTable urGetEventProcAddrTable urGetGraphExpProcAddrTable urGetIPCExpProcAddrTable @@ -333,6 +335,7 @@ EXPORTS urPrintEnqueueUsmPrefetchParams urPrintEnqueueUsmSharedAllocExpParams urPrintEnqueueWriteHostPipeParams + urPrintEventCreateExpParams urPrintEventCreateWithNativeHandleParams urPrintEventGetInfoParams urPrintEventGetNativeHandleParams @@ -359,6 +362,9 @@ EXPORTS urPrintExpEnqueueExtProperties urPrintExpEnqueueNativeCommandFlags urPrintExpEnqueueNativeCommandProperties + urPrintExpEnqueueSignalEventProperties + urPrintExpEventCreateFlags + urPrintExpEventCreateProperties urPrintExpExternalMemDesc urPrintExpExternalMemType urPrintExpExternalSemaphoreDesc diff --git a/unified-runtime/source/loader/loader.map.in b/unified-runtime/source/loader/loader.map.in index 9ffb00211b6dc..87762fe81171a 100644 --- a/unified-runtime/source/loader/loader.map.in +++ b/unified-runtime/source/loader/loader.map.in @@ -106,6 +106,7 @@ urEnqueueUSMPrefetch; urEnqueueUSMSharedAllocExp; urEnqueueWriteHostPipe; + urEventCreateExp; urEventCreateWithNativeHandle; urEventGetInfo; urEventGetNativeHandle; @@ -122,6 +123,7 @@ urGetDeviceProcAddrTable; urGetEnqueueExpProcAddrTable; urGetEnqueueProcAddrTable; + urGetEventExpProcAddrTable; urGetEventProcAddrTable; urGetGraphExpProcAddrTable; urGetIPCExpProcAddrTable; @@ -333,6 +335,7 @@ urPrintEnqueueUsmPrefetchParams; urPrintEnqueueUsmSharedAllocExpParams; urPrintEnqueueWriteHostPipeParams; + urPrintEventCreateExpParams; urPrintEventCreateWithNativeHandleParams; urPrintEventGetInfoParams; urPrintEventGetNativeHandleParams; @@ -359,6 +362,9 @@ urPrintExpEnqueueExtProperties; urPrintExpEnqueueNativeCommandFlags; urPrintExpEnqueueNativeCommandProperties; + urPrintExpEnqueueSignalEventProperties; + urPrintExpEventCreateFlags; + urPrintExpEventCreateProperties; urPrintExpExternalMemDesc; urPrintExpExternalMemType; urPrintExpExternalSemaphoreDesc; diff --git a/unified-runtime/source/loader/ur_ldrddi.cpp b/unified-runtime/source/loader/ur_ldrddi.cpp index a68a92742892e..924fab091180d 100644 --- a/unified-runtime/source/loader/ur_ldrddi.cpp +++ b/unified-runtime/source/loader/ur_ldrddi.cpp @@ -6016,6 +6016,28 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueNativeCommandExp( phEventWaitList, phEvent); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urEventCreateExp +__urdlllocal ur_result_t UR_APICALL urEventCreateExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device on which the event will be used + ur_device_handle_t hDevice, + /// [in][optional] pointer to event creation properties + const ur_exp_event_create_properties_t *pProperties, + /// [out][alloc] pointer to handle of the created event object + ur_event_handle_t *phEvent) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnCreateExp = dditable->EventExp.pfnCreateExp; + if (nullptr == pfnCreateExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnCreateExp(hContext, hDevice, pProperties, phEvent); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urGraphCreateExp __urdlllocal ur_result_t UR_APICALL urGraphCreateExp( @@ -6791,6 +6813,59 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's EventExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetEventExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_event_exp_dditable_t *pDdiTable) { + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (ur_loader::getContext()->version < version) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + // Load the device-platform DDI tables + for (auto &platform : ur_loader::getContext()->platforms) { + // statically linked adapter inside of the loader + if (platform.handle == nullptr) + continue; + + if (platform.initStatus != UR_RESULT_SUCCESS) + continue; + + auto getTable = reinterpret_cast( + ur_loader::LibLoader::getFunctionPtr(platform.handle.get(), + "urGetEventExpProcAddrTable")); + if (!getTable) + continue; + platform.initStatus = getTable(version, &platform.dditable.EventExp); + } + + if (UR_RESULT_SUCCESS == result) { + if (ur_loader::getContext()->platforms.size() != 1 || + ur_loader::getContext()->forceIntercept) { + // return pointers to loader's DDIs + pDdiTable->pfnCreateExp = ur_loader::urEventCreateExp; + } else { + // return pointers directly to platform's DDIs + *pDdiTable = ur_loader::getContext()->platforms.front().dditable.EventExp; + } + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's GraphExp table /// with current process' addresses diff --git a/unified-runtime/source/loader/ur_libapi.cpp b/unified-runtime/source/loader/ur_libapi.cpp index 1188978674036..d5fc3e4d0db4d 100644 --- a/unified-runtime/source/loader/ur_libapi.cpp +++ b/unified-runtime/source/loader/ur_libapi.cpp @@ -11040,6 +11040,60 @@ ur_result_t UR_APICALL urEnqueueNativeCommandExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Create a reusable event object. +/// +/// @details +/// - A reusable event can be associated with at most one in-flight command +/// at a time, but may be reused across multiple successive commands. +/// - The event is initially in the completed state. +/// - The context and device must be compatible: hDevice must be one of the +/// devices associated with hContext. +/// - To enable profiling timestamps, pass +/// ::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE in pProperties->flags. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `NULL != pProperties && ::UR_EXP_EVENT_CREATE_FLAGS_MASK & +/// pProperties->flags` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phEvent` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_DEVICE +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + `pProperties != NULL && pProperties->flags & +/// ~::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE` +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If ::UR_DEVICE_INFO_REUSABLE_EVENTS_EXP is false. +/// + If ::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE is set and +/// ::UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP is false. +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urEventCreateExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device on which the event will be used + ur_device_handle_t hDevice, + /// [in][optional] pointer to event creation properties + const ur_exp_event_create_properties_t *pProperties, + /// [out][alloc] pointer to handle of the created event object + ur_event_handle_t *phEvent) try { + auto pfnCreateExp = ur_lib::getContext()->urDdiTable.EventExp.pfnCreateExp; + if (nullptr == pfnCreateExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnCreateExp(hContext, hDevice, pProperties, phEvent); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Create a new record & replay graph instance explicitly. /// diff --git a/unified-runtime/source/loader/ur_libddi.cpp b/unified-runtime/source/loader/ur_libddi.cpp index 83e2721f03070..2d8dc1f3a5a65 100644 --- a/unified-runtime/source/loader/ur_libddi.cpp +++ b/unified-runtime/source/loader/ur_libddi.cpp @@ -55,6 +55,11 @@ __urdlllocal ur_result_t context_t::ddiInit() { result = urGetEventProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Event); } + if (UR_RESULT_SUCCESS == result) { + result = urGetEventExpProcAddrTable(UR_API_VERSION_CURRENT, + &urDdiTable.EventExp); + } + if (UR_RESULT_SUCCESS == result) { result = urGetGraphExpProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.GraphExp); diff --git a/unified-runtime/source/loader/ur_print.cpp b/unified-runtime/source/loader/ur_print.cpp index 8c56e882cde85..8588ab5d58efb 100644 --- a/unified-runtime/source/loader/ur_print.cpp +++ b/unified-runtime/source/loader/ur_print.cpp @@ -1257,6 +1257,30 @@ ur_result_t urPrintExpEnqueueNativeCommandProperties( return str_copy(&ss, buffer, buff_size, out_size); } +ur_result_t urPrintExpEventCreateFlags(enum ur_exp_event_create_flag_t value, + char *buffer, const size_t buff_size, + size_t *out_size) { + std::stringstream ss; + ss << value; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintExpEventCreateProperties( + const struct ur_exp_event_create_properties_t params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintExpEnqueueSignalEventProperties( + const struct ur_exp_enqueue_signal_event_properties_t params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + ur_result_t urPrintAdapterGetParams(const struct ur_adapter_get_params_t *params, char *buffer, const size_t buff_size, @@ -2113,6 +2137,15 @@ ur_result_t urPrintEventSetCallbackParams( return str_copy(&ss, buffer, buff_size, out_size); } +ur_result_t +urPrintEventCreateExpParams(const struct ur_event_create_exp_params_t *params, + char *buffer, const size_t buff_size, + size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + ur_result_t urPrintGraphCreateExpParams(const struct ur_graph_create_exp_params_t *params, char *buffer, const size_t buff_size, diff --git a/unified-runtime/source/ur_api.cpp b/unified-runtime/source/ur_api.cpp index d6b7be91aa80d..59c1ce0f4fc2b 100644 --- a/unified-runtime/source/ur_api.cpp +++ b/unified-runtime/source/ur_api.cpp @@ -9607,6 +9607,55 @@ ur_result_t UR_APICALL urEnqueueNativeCommandExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Create a reusable event object. +/// +/// @details +/// - A reusable event can be associated with at most one in-flight command +/// at a time, but may be reused across multiple successive commands. +/// - The event is initially in the completed state. +/// - The context and device must be compatible: hDevice must be one of the +/// devices associated with hContext. +/// - To enable profiling timestamps, pass +/// ::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE in pProperties->flags. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `NULL != pProperties && ::UR_EXP_EVENT_CREATE_FLAGS_MASK & +/// pProperties->flags` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phEvent` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_DEVICE +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + `pProperties != NULL && pProperties->flags & +/// ~::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE` +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If ::UR_DEVICE_INFO_REUSABLE_EVENTS_EXP is false. +/// + If ::UR_EXP_EVENT_CREATE_FLAG_PROFILING_ENABLE is set and +/// ::UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP is false. +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urEventCreateExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device on which the event will be used + ur_device_handle_t hDevice, + /// [in][optional] pointer to event creation properties + const ur_exp_event_create_properties_t *pProperties, + /// [out][alloc] pointer to handle of the created event object + ur_event_handle_t *phEvent) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Create a new record & replay graph instance explicitly. /// diff --git a/unified-runtime/tools/urinfo/urinfo.hpp b/unified-runtime/tools/urinfo/urinfo.hpp index d5b15e5aaa00b..68fbe21ae9c21 100644 --- a/unified-runtime/tools/urinfo/urinfo.hpp +++ b/unified-runtime/tools/urinfo/urinfo.hpp @@ -466,6 +466,11 @@ inline void printDeviceInfos(ur_device_handle_t hDevice, std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP); std::cout << prefix; + printDeviceInfo(hDevice, UR_DEVICE_INFO_REUSABLE_EVENTS_EXP); + std::cout << prefix; + printDeviceInfo(hDevice, + UR_DEVICE_INFO_REUSABLE_EVENTS_PROFILING_EXP); + std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP); std::cout << prefix;