diff --git a/include/ur.py b/include/ur.py index 0cc752a142..3b8cf220fb 100644 --- a/include/ur.py +++ b/include/ur.py @@ -1906,6 +1906,13 @@ class ur_queue_dditable_t(Structure): else: _urDeviceCreateWithNativeHandle_t = CFUNCTYPE( ur_result_t, ur_native_handle_t, ur_platform_handle_t, POINTER(ur_device_handle_t) ) +############################################################################### +## @brief Function-pointer for urDeviceGetGlobalTimestamps +if __use_win_types: + _urDeviceGetGlobalTimestamps_t = WINFUNCTYPE( ur_result_t, ur_device_handle_t, POINTER(c_ulonglong), POINTER(c_ulonglong) ) +else: + _urDeviceGetGlobalTimestamps_t = CFUNCTYPE( ur_result_t, ur_device_handle_t, POINTER(c_ulonglong), POINTER(c_ulonglong) ) + ############################################################################### ## @brief Table of Device functions pointers @@ -1918,7 +1925,8 @@ class ur_device_dditable_t(Structure): ("pfnPartition", c_void_p), ## _urDevicePartition_t ("pfnSelectBinary", c_void_p), ## _urDeviceSelectBinary_t ("pfnGetNativeHandle", c_void_p), ## _urDeviceGetNativeHandle_t - ("pfnCreateWithNativeHandle", c_void_p) ## _urDeviceCreateWithNativeHandle_t + ("pfnCreateWithNativeHandle", c_void_p), ## _urDeviceCreateWithNativeHandle_t + ("pfnGetGlobalTimestamps", c_void_p) ## _urDeviceGetGlobalTimestamps_t ] ############################################################################### @@ -2177,5 +2185,6 @@ def __init__(self, version : ur_api_version_t): self.urDeviceSelectBinary = _urDeviceSelectBinary_t(self.__dditable.Device.pfnSelectBinary) self.urDeviceGetNativeHandle = _urDeviceGetNativeHandle_t(self.__dditable.Device.pfnGetNativeHandle) self.urDeviceCreateWithNativeHandle = _urDeviceCreateWithNativeHandle_t(self.__dditable.Device.pfnCreateWithNativeHandle) + self.urDeviceGetGlobalTimestamps = _urDeviceGetGlobalTimestamps_t(self.__dditable.Device.pfnGetGlobalTimestamps) # success! diff --git a/include/ur_api.h b/include/ur_api.h index 47a768e659..a21a56bf07 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -3148,6 +3148,36 @@ urDeviceCreateWithNativeHandle( ur_device_handle_t* phDevice ///< [out] pointer to the handle of the device object created. ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief static +/// +/// @details +/// - The application may call this function from simultaneous threads for +/// the same context. +/// - The implementation of this function should be thread-safe. +/// +/// @remarks +/// _Analogues_ +/// - **clGetDeviceAndHostTimer** +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pDeviceTimestamp` +/// + `NULL == pHostTimestamp` +UR_APIEXPORT ur_result_t UR_APICALL +urDeviceGetGlobalTimestamps( + ur_device_handle_t hDevice, ///< [in] handle of the device instance + uint64_t* pDeviceTimestamp, ///< [out] pointer to the Device's global timestamp that + ///< correlates with the Host's global timestamp value + uint64_t* pHostTimestamp ///< [out] pointer to the Host's global timestamp that + ///< correlates with the Device's global timestamp value + ); + #if !defined(__GNUC__) #pragma endregion #endif @@ -7115,6 +7145,30 @@ typedef void (UR_APICALL *ur_pfnDeviceCreateWithNativeHandleCb_t)( void** ppTracerInstanceUserData ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Callback function parameters for urDeviceGetGlobalTimestamps +/// @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_device_get_global_timestamps_params_t +{ + ur_device_handle_t* phDevice; + uint64_t** ppDeviceTimestamp; + uint64_t** ppHostTimestamp; +} ur_device_get_global_timestamps_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Callback function-pointer for urDeviceGetGlobalTimestamps +/// @param[in] params Parameters passed to this instance +/// @param[in] result Return value +/// @param[in] pTracerUserData Per-Tracer user data +/// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data +typedef void (UR_APICALL *ur_pfnDeviceGetGlobalTimestampsCb_t)( + ur_device_get_global_timestamps_params_t* params, + ur_result_t result, + void* pTracerUserData, + void** ppTracerInstanceUserData + ); + /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Device callback functions pointers typedef struct ur_device_callbacks_t @@ -7127,6 +7181,7 @@ typedef struct ur_device_callbacks_t ur_pfnDeviceSelectBinaryCb_t pfnSelectBinaryCb; ur_pfnDeviceGetNativeHandleCb_t pfnGetNativeHandleCb; ur_pfnDeviceCreateWithNativeHandleCb_t pfnCreateWithNativeHandleCb; + ur_pfnDeviceGetGlobalTimestampsCb_t pfnGetGlobalTimestampsCb; } ur_device_callbacks_t; /////////////////////////////////////////////////////////////////////////////// diff --git a/include/ur_ddi.h b/include/ur_ddi.h index dfc107cf4a..26b5954797 100644 --- a/include/ur_ddi.h +++ b/include/ur_ddi.h @@ -1420,6 +1420,14 @@ typedef ur_result_t (UR_APICALL *ur_pfnDeviceCreateWithNativeHandle_t)( ur_device_handle_t* ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urDeviceGetGlobalTimestamps +typedef ur_result_t (UR_APICALL *ur_pfnDeviceGetGlobalTimestamps_t)( + ur_device_handle_t, + uint64_t*, + uint64_t* + ); + /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Device functions pointers typedef struct ur_device_dditable_t @@ -1432,6 +1440,7 @@ typedef struct ur_device_dditable_t ur_pfnDeviceSelectBinary_t pfnSelectBinary; ur_pfnDeviceGetNativeHandle_t pfnGetNativeHandle; ur_pfnDeviceCreateWithNativeHandle_t pfnCreateWithNativeHandle; + ur_pfnDeviceGetGlobalTimestamps_t pfnGetGlobalTimestamps; } ur_device_dditable_t; /////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/core/device.yml b/scripts/core/device.yml index 7444860182..1b3ae85791 100644 --- a/scripts/core/device.yml +++ b/scripts/core/device.yml @@ -568,3 +568,29 @@ params: name: phDevice desc: | [out] pointer to the handle of the device object created. +--- #-------------------------------------------------------------------------- +type: function +desc: "Returns synchronized Host and Device global timestamps." +class: $xDevice +name: GetGlobalTimestamps +desc: static +ordinal: "0" +analogue: + - "**clGetDeviceAndHostTimer**" +details: + - "The application may call this function from simultaneous threads for the same context." + - "The implementation of this function should be thread-safe." +params: + - type: $x_device_handle_t + name: hDevice + desc: "[in] handle of the device instance" + - type: "uint64_t*" + name: pDeviceTimestamp + desc: | + [out] pointer to the Device's global timestamp that + correlates with the Host's global timestamp value + - type: "uint64_t*" + name: pHostTimestamp + desc: | + [out] pointer to the Host's global timestamp that + correlates with the Device's global timestamp value diff --git a/source/drivers/null/ur_nullddi.cpp b/source/drivers/null/ur_nullddi.cpp index 49ba7cf5f1..6d051ddb94 100644 --- a/source/drivers/null/ur_nullddi.cpp +++ b/source/drivers/null/ur_nullddi.cpp @@ -2138,6 +2138,33 @@ namespace driver return result; } + /////////////////////////////////////////////////////////////////////////////// + /// @brief Intercept function for urDeviceGetGlobalTimestamps + __urdlllocal ur_result_t UR_APICALL + urDeviceGetGlobalTimestamps( + ur_device_handle_t hDevice, ///< [in] handle of the device instance + uint64_t* pDeviceTimestamp, ///< [out] pointer to the Device's global timestamp that + ///< correlates with the Host's global timestamp value + uint64_t* pHostTimestamp ///< [out] pointer to the Host's global timestamp that + ///< correlates with the Device's global timestamp value + ) + { + ur_result_t result = UR_RESULT_SUCCESS; + + // if the driver has created a custom function, then call it instead of using the generic path + auto pfnGetGlobalTimestamps = d_context.urDdiTable.Device.pfnGetGlobalTimestamps; + if( nullptr != pfnGetGlobalTimestamps ) + { + result = pfnGetGlobalTimestamps( hDevice, pDeviceTimestamp, pHostTimestamp ); + } + else + { + // generic implementation + } + + return result; + } + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urKernelCreate __urdlllocal ur_result_t UR_APICALL @@ -3622,6 +3649,8 @@ urGetDeviceProcAddrTable( pDdiTable->pfnCreateWithNativeHandle = driver::urDeviceCreateWithNativeHandle; + pDdiTable->pfnGetGlobalTimestamps = driver::urDeviceGetGlobalTimestamps; + return result; } diff --git a/source/loader/ur_ldrddi.cpp b/source/loader/ur_ldrddi.cpp index ac248b8b83..943f3fbe37 100644 --- a/source/loader/ur_ldrddi.cpp +++ b/source/loader/ur_ldrddi.cpp @@ -2870,6 +2870,34 @@ namespace loader return result; } + /////////////////////////////////////////////////////////////////////////////// + /// @brief Intercept function for urDeviceGetGlobalTimestamps + __urdlllocal ur_result_t UR_APICALL + urDeviceGetGlobalTimestamps( + ur_device_handle_t hDevice, ///< [in] handle of the device instance + uint64_t* pDeviceTimestamp, ///< [out] pointer to the Device's global timestamp that + ///< correlates with the Host's global timestamp value + uint64_t* pHostTimestamp ///< [out] pointer to the Host's global timestamp that + ///< correlates with the Device's global timestamp value + ) + { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast( hDevice )->dditable; + auto pfnGetGlobalTimestamps = dditable->ur.Device.pfnGetGlobalTimestamps; + if( nullptr == pfnGetGlobalTimestamps ) + return UR_RESULT_ERROR_UNINITIALIZED; + + // convert loader handle to platform handle + hDevice = reinterpret_cast( hDevice )->handle; + + // forward to device-platform + result = pfnGetGlobalTimestamps( hDevice, pDeviceTimestamp, pHostTimestamp ); + + return result; + } + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urKernelCreate __urdlllocal ur_result_t UR_APICALL @@ -4991,6 +5019,7 @@ urGetDeviceProcAddrTable( pDdiTable->pfnSelectBinary = loader::urDeviceSelectBinary; pDdiTable->pfnGetNativeHandle = loader::urDeviceGetNativeHandle; pDdiTable->pfnCreateWithNativeHandle = loader::urDeviceCreateWithNativeHandle; + pDdiTable->pfnGetGlobalTimestamps = loader::urDeviceGetGlobalTimestamps; } else { diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index f84c6abfea..554226f1d8 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -2785,6 +2785,43 @@ urDeviceCreateWithNativeHandle( return pfnCreateWithNativeHandle( hNativeDevice, hPlatform, phDevice ); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief static +/// +/// @details +/// - The application may call this function from simultaneous threads for +/// the same context. +/// - The implementation of this function should be thread-safe. +/// +/// @remarks +/// _Analogues_ +/// - **clGetDeviceAndHostTimer** +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pDeviceTimestamp` +/// + `NULL == pHostTimestamp` +ur_result_t UR_APICALL +urDeviceGetGlobalTimestamps( + ur_device_handle_t hDevice, ///< [in] handle of the device instance + uint64_t* pDeviceTimestamp, ///< [out] pointer to the Device's global timestamp that + ///< correlates with the Host's global timestamp value + uint64_t* pHostTimestamp ///< [out] pointer to the Host's global timestamp that + ///< correlates with the Device's global timestamp value + ) +{ + auto pfnGetGlobalTimestamps = ur_lib::context->urDdiTable.Device.pfnGetGlobalTimestamps; + if( nullptr == pfnGetGlobalTimestamps ) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnGetGlobalTimestamps( hDevice, pDeviceTimestamp, pHostTimestamp ); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Create kernel object from a program. /// diff --git a/source/ur_api.cpp b/source/ur_api.cpp index 99710ae1db..ff2a06e4fa 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -2569,6 +2569,40 @@ urDeviceCreateWithNativeHandle( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief static +/// +/// @details +/// - The application may call this function from simultaneous threads for +/// the same context. +/// - The implementation of this function should be thread-safe. +/// +/// @remarks +/// _Analogues_ +/// - **clGetDeviceAndHostTimer** +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pDeviceTimestamp` +/// + `NULL == pHostTimestamp` +ur_result_t UR_APICALL +urDeviceGetGlobalTimestamps( + ur_device_handle_t hDevice, ///< [in] handle of the device instance + uint64_t* pDeviceTimestamp, ///< [out] pointer to the Device's global timestamp that + ///< correlates with the Host's global timestamp value + uint64_t* pHostTimestamp ///< [out] pointer to the Host's global timestamp that + ///< correlates with the Device's global timestamp value + ) +{ + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Create kernel object from a program. ///