diff --git a/unified-runtime/include/ur_api.h b/unified-runtime/include/ur_api.h index 906c32b837bbe..057c89cc91396 100644 --- a/unified-runtime/include/ur_api.h +++ b/unified-runtime/include/ur_api.h @@ -475,6 +475,14 @@ typedef enum ur_function_t { UR_FUNCTION_MEMORY_EXPORT_EXPORT_MEMORY_HANDLE_EXP = 287, /// Enumerator for ::urBindlessImagesSupportsImportingHandleTypeExp UR_FUNCTION_BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP = 288, + /// Enumerator for ::urIPCGetMemHandleExp + UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP = 289, + /// Enumerator for ::urIPCPutMemHandleExp + UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP = 290, + /// Enumerator for ::urIPCOpenMemHandleExp + UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP = 291, + /// Enumerator for ::urIPCCloseMemHandleExp + UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP = 292, /// @cond UR_FUNCTION_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -2426,6 +2434,9 @@ typedef enum ur_device_info_t { /// [::ur_exp_device_2d_block_array_capability_flags_t] return a bit-field /// of Intel GPU 2D block array capabilities UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP = 0x2022, + /// [::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 enqueueing of /// allocations and frees. UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP = 0x2050, @@ -12393,6 +12404,117 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( /// array. ur_event_handle_t *phEvent); +#if !defined(__GNUC__) +#pragma endregion +#endif +// Intel 'oneAPI' Unified Runtime Experimental APIs for Inter Process +// Communication +#if !defined(__GNUC__) +#pragma region inter_process_communication_(experimental) +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets an inter-process memory handle for a pointer to device USM +/// memory +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == pIPCMemHandleDataSizeRet` +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Releases an inter-process memory handle +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory +/// +/// @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_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == ppMem` +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *pIPCMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] pointer to a pointer to device USM memory + void **ppMem); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Closes an inter-process memory handle +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem); + #if !defined(__GNUC__) #pragma endregion #endif @@ -15469,6 +15591,47 @@ typedef struct ur_command_buffer_get_native_handle_exp_params_t { ur_native_handle_t **pphNativeCommandBuffer; } ur_command_buffer_get_native_handle_exp_params_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCGetMemHandleExp +/// @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_ipc_get_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + void **ppMem; + void **ppIPCMemHandleData; + size_t **ppIPCMemHandleDataSizeRet; +} ur_ipc_get_mem_handle_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCPutMemHandleExp +/// @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_ipc_put_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + void **ppIPCMemHandleData; +} ur_ipc_put_mem_handle_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCOpenMemHandleExp +/// @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_ipc_open_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + ur_device_handle_t *phDevice; + void **ppIPCMemHandleData; + size_t *pipcMemHandleDataSize; + void ***pppMem; +} ur_ipc_open_mem_handle_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCCloseMemHandleExp +/// @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_ipc_close_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + void **ppMem; +} ur_ipc_close_mem_handle_exp_params_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urMemoryExportAllocExportableMemoryExp /// @details Each entry is a pointer to the parameter passed to the function; diff --git a/unified-runtime/include/ur_api_funcs.def b/unified-runtime/include/ur_api_funcs.def index f0c92445b9238..ab189345ce9d0 100644 --- a/unified-runtime/include/ur_api_funcs.def +++ b/unified-runtime/include/ur_api_funcs.def @@ -206,6 +206,10 @@ _UR_API(urCommandBufferUpdateSignalEventExp) _UR_API(urCommandBufferUpdateWaitEventsExp) _UR_API(urCommandBufferGetInfoExp) _UR_API(urCommandBufferGetNativeHandleExp) +_UR_API(urIPCGetMemHandleExp) +_UR_API(urIPCPutMemHandleExp) +_UR_API(urIPCOpenMemHandleExp) +_UR_API(urIPCCloseMemHandleExp) _UR_API(urMemoryExportAllocExportableMemoryExp) _UR_API(urMemoryExportFreeExportableMemoryExp) _UR_API(urMemoryExportExportMemoryHandleExp) diff --git a/unified-runtime/include/ur_ddi.h b/unified-runtime/include/ur_ddi.h index f59e15a9eb3cd..39cd96274f1d0 100644 --- a/unified-runtime/include/ur_ddi.h +++ b/unified-runtime/include/ur_ddi.h @@ -1787,6 +1787,56 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetCommandBufferExpProcAddrTable( typedef ur_result_t(UR_APICALL *ur_pfnGetCommandBufferExpProcAddrTable_t)( ur_api_version_t, ur_command_buffer_exp_dditable_t *); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCGetMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleExp_t)(ur_context_handle_t, + void *, void *, + size_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCPutMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCPutMemHandleExp_t)(ur_context_handle_t, + void *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCOpenMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCOpenMemHandleExp_t)( + ur_context_handle_t, ur_device_handle_t, void *, size_t, void **); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCCloseMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCCloseMemHandleExp_t)( + ur_context_handle_t, void *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Table of IPCExp functions pointers +typedef struct ur_ipc_exp_dditable_t { + ur_pfnIPCGetMemHandleExp_t pfnGetMemHandleExp; + ur_pfnIPCPutMemHandleExp_t pfnPutMemHandleExp; + ur_pfnIPCOpenMemHandleExp_t pfnOpenMemHandleExp; + ur_pfnIPCCloseMemHandleExp_t pfnCloseMemHandleExp; +} ur_ipc_exp_dditable_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp 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 urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urGetIPCExpProcAddrTable +typedef ur_result_t(UR_APICALL *ur_pfnGetIPCExpProcAddrTable_t)( + ur_api_version_t, ur_ipc_exp_dditable_t *); + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urMemoryExportAllocExportableMemoryExp typedef ur_result_t(UR_APICALL *ur_pfnMemoryExportAllocExportableMemoryExp_t)( @@ -2049,6 +2099,7 @@ typedef struct ur_dditable_t { ur_usm_exp_dditable_t USMExp; ur_bindless_images_exp_dditable_t BindlessImagesExp; ur_command_buffer_exp_dditable_t CommandBufferExp; + ur_ipc_exp_dditable_t IPCExp; ur_memory_export_exp_dditable_t MemoryExportExp; ur_usm_p2p_exp_dditable_t UsmP2PExp; ur_virtual_mem_dditable_t VirtualMem; diff --git a/unified-runtime/include/ur_print.h b/unified-runtime/include/ur_print.h index 7c4528ec9ea81..8f734596419dc 100644 --- a/unified-runtime/include/ur_print.h +++ b/unified-runtime/include/ur_print.h @@ -3500,6 +3500,46 @@ urPrintCommandBufferGetNativeHandleExpParams( const struct ur_command_buffer_get_native_handle_exp_params_t *params, char *buffer, const size_t buff_size, size_t *out_size); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_get_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcGetMemHandleExpParams( + const struct ur_ipc_get_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_put_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcPutMemHandleExpParams( + const struct ur_ipc_put_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_open_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcOpenMemHandleExpParams( + const struct ur_ipc_open_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_close_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcCloseMemHandleExpParams( + const struct ur_ipc_close_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + /////////////////////////////////////////////////////////////////////////////// /// @brief Print ur_memory_export_alloc_exportable_memory_exp_params_t struct /// @returns diff --git a/unified-runtime/include/ur_print.hpp b/unified-runtime/include/ur_print.hpp index b3de6c166ca31..c0e8e3628fe84 100644 --- a/unified-runtime/include/ur_print.hpp +++ b/unified-runtime/include/ur_print.hpp @@ -1276,6 +1276,18 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_function_t value) { case UR_FUNCTION_BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP: os << "UR_FUNCTION_BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP"; break; + case UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP"; + break; + case UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP"; + break; + case UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP"; + break; + case UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP"; + break; default: os << "unknown enumerator"; break; @@ -3118,6 +3130,9 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_device_info_t value) { case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: os << "UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP"; break; + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + os << "UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP"; + break; case UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP: os << "UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP"; break; @@ -5258,6 +5273,19 @@ inline ur_result_t printTagged(std::ostream &os, const void *ptr, os << ")"; } break; + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_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) { @@ -20354,6 +20382,112 @@ operator<<(std::ostream &os, [[maybe_unused]] const struct return os; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_get_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_ipc_get_mem_handle_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".pMem = "; + + os << *(params->ppMem); + + os << ", "; + os << ".pIPCMemHandleData = "; + + ur::details::printPtr(os, *(params->ppIPCMemHandleData)); + + os << ", "; + os << ".pIPCMemHandleDataSizeRet = "; + + ur::details::printPtr(os, *(params->ppIPCMemHandleDataSizeRet)); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_put_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_ipc_put_mem_handle_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".pIPCMemHandleData = "; + + ur::details::printPtr(os, *(params->ppIPCMemHandleData)); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_open_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_ipc_open_mem_handle_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".hDevice = "; + + ur::details::printPtr(os, *(params->phDevice)); + + os << ", "; + os << ".pIPCMemHandleData = "; + + os << *(params->ppIPCMemHandleData); + + os << ", "; + os << ".ipcMemHandleDataSize = "; + + os << *(params->pipcMemHandleDataSize); + + os << ", "; + os << ".ppMem = "; + + os << *(params->pppMem); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_close_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, + [[maybe_unused]] const struct ur_ipc_close_mem_handle_exp_params_t + *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".pMem = "; + + os << *(params->ppMem); + + return os; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Print operator for the /// ur_memory_export_alloc_exportable_memory_exp_params_t type @@ -21818,6 +21952,18 @@ inline ur_result_t UR_APICALL printFunctionParams(std::ostream &os, os << (const struct ur_command_buffer_get_native_handle_exp_params_t *) params; } break; + case UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_get_mem_handle_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_put_mem_handle_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_open_mem_handle_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_close_mem_handle_exp_params_t *)params; + } break; case UR_FUNCTION_MEMORY_EXPORT_ALLOC_EXPORTABLE_MEMORY_EXP: { os << (const struct ur_memory_export_alloc_exportable_memory_exp_params_t *) params; diff --git a/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst new file mode 100644 index 0000000000000..647f6f09ac23b --- /dev/null +++ b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst @@ -0,0 +1,64 @@ +<% + OneApi=tags['$OneApi'] + x=tags['$x'] + X=x.upper() +%> + +.. _experimental-inter-process-communication: + +================================================================================ +Inter Process Communication +================================================================================ + +.. warning:: + + Experimental features: + + * May be replaced, updated, or removed at any time. + * Do not require maintaining API/ABI stability of their own additions over + time. + * Do not require conformance testing of their own additions. + + +Motivation +-------------------------------------------------------------------------------- +This extension introduces functionality for allowing processes to share common +objects, such as device USM memory allocations. Doing so lets processes actively +communicate with each other through the devices, by explicitly managing handles +that represent shareable objects for inter-process communication. + +API +-------------------------------------------------------------------------------- + +Enums +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* ${x}_device_info_t + * ${X}_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP + +Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* Inter-Process Communication + * ${x}IPCGetMemHandleExp + * ${x}IPCPutMemHandleExp + * ${x}IPCOpenMemHandleExp + * ${x}IPCCloseMemHandleExp + +Changelog +-------------------------------------------------------------------------------- + ++-----------+------------------------+ +| Revision | Changes | ++===========+========================+ +| 1.0 | Initial Draft | ++-----------+------------------------+ + +Support +-------------------------------------------------------------------------------- + +Adapters which support this experimental feature *must* return true for the new +``${X}_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP`` device info query. + +Contributors +-------------------------------------------------------------------------------- + +* Larsen, Steffen `steffen.larsen@intel.com `_ diff --git a/unified-runtime/scripts/core/exp-inter-process-communication.yml b/unified-runtime/scripts/core/exp-inter-process-communication.yml new file mode 100644 index 0000000000000..117e66d815ba9 --- /dev/null +++ b/unified-runtime/scripts/core/exp-inter-process-communication.yml @@ -0,0 +1,129 @@ +# +# Copyright (C) 2025 Intel Corporation +# +# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +# Exceptions. +# See LICENSE.TXT +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# See YaML.md for syntax definition +# +--- #-------------------------------------------------------------------------- +type: header +desc: "Intel $OneApi Unified Runtime Experimental APIs for Inter Process Communication" +ordinal: "99" +--- #-------------------------------------------------------------------------- +type: enum +extend: true +typed_etors: true +desc: "Extension enums to $x_device_info_t to support inter-process communicable memory handles." +name: $x_device_info_t +etors: + - name: IPC_MEMORY_SUPPORT_EXP + value: "0x2023" + desc: "[$x_bool_t] returns true if the device supports inter-process communicable memory handles" +--- #-------------------------------------------------------------------------- +type: function +desc: "Gets an inter-process memory handle for a pointer to device USM memory" +class: $xIPC +name: GetMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: void * + name: pMem + desc: "[in] pointer to device USM memory" + - type: void* + name: pIPCMemHandleData + desc: "[out][optional] a pointer to the IPC memory handle data" + - type: size_t* + name: pIPCMemHandleDataSizeRet + desc: "[out][optional] size of the resulting IPC memory handle data" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "`NULL == hContext`" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "`NULL == pIPCMemHandleData`" + - "`NULL == pIPCMemHandleDataSizeRet`" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Releases an inter-process memory handle" +class: $xIPC +name: PutMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: void* + name: pIPCMemHandleData + desc: "[in] a pointer to the IPC memory handle data" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "`NULL == hContext`" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "`NULL == pIPCMemHandleData`" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Opens an inter-process memory handle to get the corresponding pointer to device USM memory" +class: $xIPC +name: OpenMemHandleExp +ordinal: "0" +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 object the corresponding USM device memory was allocated on" + - type: void * + name: pIPCMemHandleData + desc: "[in] the IPC memory handle data" + - type: size_t + name: ipcMemHandleDataSize + desc: "[in] size of the IPC memory handle data" + - type: void ** + name: ppMem + desc: "[out] pointer to a pointer to device USM memory" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "`NULL == hContext`" + - "`NULL == hDevice`" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "`NULL == pIPCMemHandleData`" + - "`NULL == ppMem`" + - $X_RESULT_ERROR_INVALID_VALUE: + - "ipcMemHandleDataSize is not the same as the size of IPC memory handle data" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Closes an inter-process memory handle" +class: $xIPC +name: CloseMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: void * + name: pMem + desc: "[in] pointer to device USM memory opened through urIPCOpenMemHandleExp" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "`NULL == hContext`" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "`NULL == pMem`" + - $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 baefa0ad0903d..b37d399ef3326 100644 --- a/unified-runtime/scripts/core/registry.yml +++ b/unified-runtime/scripts/core/registry.yml @@ -670,7 +670,19 @@ etors: - name: BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP desc: Enumerator for $xBindlessImagesSupportsImportingHandleTypeExp value: '288' -max_id: '288' +- name: IPC_GET_MEM_HANDLE_EXP + desc: Enumerator for $xIPCGetMemHandleExp + value: '289' +- name: IPC_PUT_MEM_HANDLE_EXP + desc: Enumerator for $xIPCPutMemHandleExp + value: '290' +- name: IPC_OPEN_MEM_HANDLE_EXP + desc: Enumerator for $xIPCOpenMemHandleExp + value: '291' +- name: IPC_CLOSE_MEM_HANDLE_EXP + desc: Enumerator for $xIPCCloseMemHandleExp + value: '292' +max_id: '292' --- 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 edccce444d2e0..aa3b55765ce3c 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 + urGetIPCExpProcAddrTable urGetKernelProcAddrTable urGetMemProcAddrTable urGetMemoryExportExpProcAddrTable diff --git a/unified-runtime/source/adapters/adapter.map.in b/unified-runtime/source/adapters/adapter.map.in index 54ff7d6b93f31..4be9b9b1348b7 100644 --- a/unified-runtime/source/adapters/adapter.map.in +++ b/unified-runtime/source/adapters/adapter.map.in @@ -7,6 +7,7 @@ urGetEnqueueProcAddrTable; urGetEnqueueExpProcAddrTable; urGetEventProcAddrTable; + urGetIPCExpProcAddrTable; urGetKernelProcAddrTable; urGetMemProcAddrTable; urGetMemoryExportExpProcAddrTable; diff --git a/unified-runtime/source/adapters/cuda/device.cpp b/unified-runtime/source/adapters/cuda/device.cpp index 03d9a13999f84..ddc4c7a115e26 100644 --- a/unified-runtime/source/adapters/cuda/device.cpp +++ b/unified-runtime/source/adapters/cuda/device.cpp @@ -1146,6 +1146,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: return ReturnValue( static_cast(0)); + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: { + int IPCSupported = 0; + UR_CHECK_ERROR(cuDeviceGetAttribute(&IPCSupported, + CU_DEVICE_ATTRIBUTE_IPC_EVENT_SUPPORTED, + hDevice->get())); + return ReturnValue(static_cast(IPCSupported)); + } case UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP: case UR_DEVICE_INFO_COMMAND_BUFFER_EVENT_SUPPORT_EXP: return ReturnValue(true); diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index b48252de6a816..4477173cb83cc 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -15,6 +15,7 @@ #include "enqueue.hpp" #include "memory.hpp" #include "umf_helpers.hpp" +#include "usm.hpp" /// Creates a UR Memory object using a CUDA memory allocation. /// Can trigger a manual copy depending on the mode. @@ -589,3 +590,63 @@ CUsurfObject SurfaceMem::getSurface(const ur_device_handle_t Device) { } return SurfObjs[OuterMemStruct->getContext()->getDeviceIndex(Device)]; } + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet) { + umf_memory_pool_handle_t umfPool; + auto urRet = umf::umf2urResult(umfPoolByPtr(pMem, &umfPool)); + if (urRet) + return urRet; + + // Fast path for returning the size of the handle only. + if (!pIPCMemHandleData) + return umf::umf2urResult( + umfPoolGetIPCHandleSize(umfPool, pIPCMemHandleDataSizeRet)); + + size_t fallbackUMFHandleSize = 0; + size_t *umfHandleSize = pIPCMemHandleDataSizeRet != nullptr + ? pIPCMemHandleDataSizeRet + : &fallbackUMFHandleSize; + umf_ipc_handle_t umfHandle; + urRet = umf::umf2urResult(umfGetIPCHandle(pMem, &umfHandle, umfHandleSize)); + if (urRet) + return urRet; + std::memcpy(pIPCMemHandleData, umfHandle, *umfHandleSize); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCPutMemHandleExp(ur_context_handle_t, void *pIPCMemHandleData) { + return umf::umf2urResult( + umfPutIPCHandle(reinterpret_cast(pIPCMemHandleData))); +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( + ur_context_handle_t, ur_device_handle_t hDevice, void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem) { + umf_memory_pool_handle_t umfPool = hDevice->MemoryPoolDevice; + + size_t umfHandleSize = 0; + auto urRet = + umf::umf2urResult(umfPoolGetIPCHandleSize(umfPool, &umfHandleSize)); + if (urRet) + return urRet; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + + umf_ipc_handler_handle_t umfIPCHandler; + urRet = umf::umf2urResult(umfPoolGetIPCHandler(umfPool, &umfIPCHandler)); + if (urRet) + return urRet; + + return umf::umf2urResult(umfOpenIPCHandle( + umfIPCHandler, reinterpret_cast(pIPCMemHandleData), + ppMem)); +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *pMem) { + return umf::umf2urResult(umfCloseIPCHandle(pMem)); +} diff --git a/unified-runtime/source/adapters/cuda/memory.hpp b/unified-runtime/source/adapters/cuda/memory.hpp index 6bb817f1efee8..4e72e6dd15bec 100644 --- a/unified-runtime/source/adapters/cuda/memory.hpp +++ b/unified-runtime/source/adapters/cuda/memory.hpp @@ -19,6 +19,7 @@ #include "common/ur_ref_count.hpp" #include "context.hpp" #include "queue.hpp" +#include ur_result_t allocateMemObjOnDeviceIfNeeded(ur_mem_handle_t, const ur_device_handle_t); diff --git a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp index 8430df0ab0678..a53266ecbe20a 100644 --- a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp @@ -458,6 +458,21 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -480,6 +495,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/hip/device.cpp b/unified-runtime/source/adapters/hip/device.cpp index c48033ec88826..f71d86c3f4a5e 100644 --- a/unified-runtime/source/adapters/hip/device.cpp +++ b/unified-runtime/source/adapters/hip/device.cpp @@ -999,6 +999,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: return ReturnValue( static_cast(0)); + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(false); case UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP: { int RuntimeVersion = 0; UR_CHECK_ERROR(hipRuntimeGetVersion(&RuntimeVersion)); diff --git a/unified-runtime/source/adapters/hip/memory.cpp b/unified-runtime/source/adapters/hip/memory.cpp index 7995b15d36f84..4c646ed64a1e4 100644 --- a/unified-runtime/source/adapters/hip/memory.cpp +++ b/unified-runtime/source/adapters/hip/memory.cpp @@ -640,3 +640,26 @@ hipSurfaceObject_t SurfaceMem::getSurface(const ur_device_handle_t Device) { } return SurfObjs[OuterMemStruct->getContext()->getDeviceIndex(Device)]; } + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp index dfb4382cad828..978570a96376a 100644 --- a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp @@ -451,6 +451,21 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -473,6 +488,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/level_zero/device.cpp b/unified-runtime/source/adapters/level_zero/device.cpp index 911e565a996f8..bb168927ca561 100644 --- a/unified-runtime/source/adapters/level_zero/device.cpp +++ b/unified-runtime/source/adapters/level_zero/device.cpp @@ -1306,6 +1306,8 @@ ur_result_t urDeviceGetInfo( return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION; #endif } + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(true); case UR_DEVICE_INFO_ASYNC_BARRIER: return ReturnValue(false); case UR_DEVICE_INFO_HOST_PIPE_READ_WRITE_SUPPORT: diff --git a/unified-runtime/source/adapters/level_zero/memory.cpp b/unified-runtime/source/adapters/level_zero/memory.cpp index 107fcc2d1c2f5..127629734bfaf 100644 --- a/unified-runtime/source/adapters/level_zero/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/memory.cpp @@ -1952,6 +1952,69 @@ ur_result_t urEnqueueWriteHostPipe( return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } +ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, + void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet) { + umf_memory_pool_handle_t umfPool; + auto urRet = umf::umf2urResult(umfPoolByPtr(pMem, &umfPool)); + if (urRet) + return urRet; + + // Fast path for returning the size of the handle only. + if (!pIPCMemHandleData) + return umf::umf2urResult( + umfPoolGetIPCHandleSize(umfPool, pIPCMemHandleDataSizeRet)); + + size_t fallbackUMFHandleSize = 0; + size_t *umfHandleSize = pIPCMemHandleDataSizeRet != nullptr + ? pIPCMemHandleDataSizeRet + : &fallbackUMFHandleSize; + umf_ipc_handle_t umfHandle; + urRet = umf::umf2urResult(umfGetIPCHandle(pMem, &umfHandle, umfHandleSize)); + if (urRet) + return urRet; + std::memcpy(pIPCMemHandleData, umfHandle, *umfHandleSize); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, void *pIPCMemHandleData) { + return umf::umf2urResult( + umfPutIPCHandle(reinterpret_cast(pIPCMemHandleData))); +} + +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem) { + auto *pool = hContext->DefaultPool.getPool(usm::pool_descriptor{ + &hContext->DefaultPool, hContext, hDevice, UR_USM_TYPE_DEVICE, false}); + if (!pool) + return UR_RESULT_ERROR_INVALID_CONTEXT; + umf_memory_pool_handle_t umfPool = pool->UmfPool.get(); + + size_t umfHandleSize = 0; + auto urRet = + umf::umf2urResult(umfPoolGetIPCHandleSize(umfPool, &umfHandleSize)); + if (urRet) + return urRet; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + + umf_ipc_handler_handle_t umfIPCHandler; + urRet = umf::umf2urResult(umfPoolGetIPCHandler(umfPool, &umfIPCHandler)); + if (urRet) + return urRet; + + return umf::umf2urResult(umfOpenIPCHandle( + umfIPCHandler, reinterpret_cast(pIPCMemHandleData), + ppMem)); +} + +ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { + return umf::umf2urResult(umfCloseIPCHandle(pMem)); +} + } // namespace ur::level_zero // If indirect access tracking is enabled then performs reference counting, diff --git a/unified-runtime/source/adapters/level_zero/memory.hpp b/unified-runtime/source/adapters/level_zero/memory.hpp index f58f189b21c77..9d96eee2a499e 100644 --- a/unified-runtime/source/adapters/level_zero/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/memory.hpp @@ -25,6 +25,7 @@ #include "program.hpp" #include "queue.hpp" #include "sampler.hpp" +#include struct ur_device_handle_t_; 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 13d7274e7aebf..269a21f6c56ef 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp @@ -257,6 +257,21 @@ UR_APIEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +UR_APIEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = ur::level_zero::urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur::level_zero::urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur::level_zero::urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur::level_zero::urIPCCloseMemHandleExp; + + return result; +} + UR_APIEXPORT ur_result_t UR_APICALL urGetKernelProcAddrTable( ur_api_version_t version, ur_kernel_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -595,6 +610,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_::urGetIPCExpProcAddrTable(UR_API_VERSION_CURRENT, + &ddi->IPCExp); + if (result != UR_RESULT_SUCCESS) + return result; result = NAMESPACE_::urGetKernelProcAddrTable(UR_API_VERSION_CURRENT, &ddi->Kernel); 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 77bc0b7d5b737..8fee48da9d69c 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp @@ -770,6 +770,16 @@ urCommandBufferGetNativeHandleExp(ur_exp_command_buffer_handle_t hCommandBuffer, ur_result_t urEnqueueTimestampRecordingExp( ur_queue_handle_t hQueue, bool blocking, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent); +ur_result_t urIPCGetMemHandleExp(ur_context_handle_t hContext, void *pMem, + void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet); +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t hContext, + void *pIPCMemHandleData); +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem); +ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t hContext, void *pMem); ur_result_t urMemoryExportAllocExportableMemoryExp( ur_context_handle_t hContext, ur_device_handle_t hDevice, size_t alignment, size_t size, ur_exp_external_mem_type_t handleTypeToExport, void **ppMem); diff --git a/unified-runtime/source/adapters/level_zero/usm.hpp b/unified-runtime/source/adapters/level_zero/usm.hpp index aa7558926b5ed..d3e2e344f149f 100644 --- a/unified-runtime/source/adapters/level_zero/usm.hpp +++ b/unified-runtime/source/adapters/level_zero/usm.hpp @@ -84,12 +84,12 @@ struct ur_usm_pool_handle_t_ : ur_object { size_t getPeakReservedSize(); size_t getTotalUsedSize(); size_t getPeakUsedSize(); + UsmPool *getPool(const usm::pool_descriptor &Desc); ur_context_handle_t Context; ur::RefCount RefCount; private: - UsmPool *getPool(const usm::pool_descriptor &Desc); usm::pool_manager PoolManager; AllocationStats AllocStats; }; diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.cpp b/unified-runtime/source/adapters/level_zero/v2/memory.cpp index a5a8ee3387d3e..941d73be8de3e 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.cpp @@ -781,4 +781,68 @@ ur_result_t urMemImageGetInfo(ur_mem_handle_t /*hMemory*/, return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } +ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, + void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet) { + umf_memory_pool_handle_t umfPool; + auto urRet = umf::umf2urResult(umfPoolByPtr(pMem, &umfPool)); + if (urRet) + return urRet; + + // Fast path for returning the size of the handle only. + if (!pIPCMemHandleData) + return umf::umf2urResult( + umfPoolGetIPCHandleSize(umfPool, pIPCMemHandleDataSizeRet)); + + size_t fallbackUMFHandleSize = 0; + size_t *umfHandleSize = pIPCMemHandleDataSizeRet != nullptr + ? pIPCMemHandleDataSizeRet + : &fallbackUMFHandleSize; + umf_ipc_handle_t umfHandle; + urRet = umf::umf2urResult(umfGetIPCHandle(pMem, &umfHandle, umfHandleSize)); + if (urRet) + return urRet; + std::memcpy(pIPCMemHandleData, umfHandle, *umfHandleSize); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, void *pIPCMemHandleData) { + return umf::umf2urResult( + umfPutIPCHandle(reinterpret_cast(pIPCMemHandleData))); +} + +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem) { + auto *pool = hContext->getDefaultUSMPool()->getPool( + usm::pool_descriptor{hContext->getDefaultUSMPool(), hContext, hDevice, + UR_USM_TYPE_DEVICE, false}); + if (!pool) + return UR_RESULT_ERROR_INVALID_CONTEXT; + umf_memory_pool_handle_t umfPool = pool->umfPool.get(); + + size_t umfHandleSize = 0; + auto urRet = + umf::umf2urResult(umfPoolGetIPCHandleSize(umfPool, &umfHandleSize)); + if (urRet) + return urRet; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + + umf_ipc_handler_handle_t umfIPCHandler; + urRet = umf::umf2urResult(umfPoolGetIPCHandler(umfPool, &umfIPCHandler)); + if (urRet) + return urRet; + + return umf::umf2urResult(umfOpenIPCHandle( + umfIPCHandler, reinterpret_cast(pIPCMemHandleData), + ppMem)); +} + +ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { + return umf::umf2urResult(umfCloseIPCHandle(pMem)); +} + } // namespace ur::level_zero diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.hpp b/unified-runtime/source/adapters/level_zero/v2/memory.hpp index 61b0a00f4043b..813d09bf864c2 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.hpp @@ -20,6 +20,7 @@ #include "command_list_manager.hpp" #include "common.hpp" #include "common/ur_ref_count.hpp" +#include using usm_unique_ptr_t = std::unique_ptr>; diff --git a/unified-runtime/source/adapters/level_zero/v2/usm.hpp b/unified-runtime/source/adapters/level_zero/v2/usm.hpp index 825ecb5fcd8e3..ace4b7411e617 100644 --- a/unified-runtime/source/adapters/level_zero/v2/usm.hpp +++ b/unified-runtime/source/adapters/level_zero/v2/usm.hpp @@ -81,14 +81,14 @@ struct ur_usm_pool_handle_t_ : ur_object { size_t getTotalUsedSize(); size_t getPeakUsedSize(); + UsmPool *getPool(const usm::pool_descriptor &desc); + ur::RefCount RefCount; private: ur_context_handle_t hContext; usm::pool_manager poolManager; AllocationStats allocStats; - - UsmPool *getPool(const usm::pool_descriptor &desc); }; struct UsmPool { diff --git a/unified-runtime/source/adapters/mock/ur_mock.cpp b/unified-runtime/source/adapters/mock/ur_mock.cpp index 142a706146a9b..bd2112793a3a1 100644 --- a/unified-runtime/source/adapters/mock/ur_mock.cpp +++ b/unified-runtime/source/adapters/mock/ur_mock.cpp @@ -103,6 +103,7 @@ context_t::context_t() { urGetContextProcAddrTable(version, &urDdiTable.Context); urGetEnqueueProcAddrTable(version, &urDdiTable.Enqueue); urGetEnqueueExpProcAddrTable(version, &urDdiTable.EnqueueExp); + urGetIPCExpProcAddrTable(version, &urDdiTable.IPCExp); urGetEventProcAddrTable(version, &urDdiTable.Event); urGetKernelProcAddrTable(version, &urDdiTable.Kernel); urGetMemProcAddrTable(version, &urDdiTable.Mem); diff --git a/unified-runtime/source/adapters/mock/ur_mockddi.cpp b/unified-runtime/source/adapters/mock/ur_mockddi.cpp index bc1ef8ae6dc86..b0f045adf96e2 100644 --- a/unified-runtime/source/adapters/mock/ur_mockddi.cpp +++ b/unified-runtime/source/adapters/mock/ur_mockddi.cpp @@ -11308,6 +11308,195 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_get_mem_handle_exp_params_t params = { + &hContext, &pMem, &pIPCMemHandleData, &pIPCMemHandleDataSizeRet}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCGetMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCGetMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCGetMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &pIPCMemHandleData}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCPutMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCPutMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCPutMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *pIPCMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] pointer to a pointer to device USM memory + void **ppMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_open_mem_handle_exp_params_t params = { + &hContext, &hDevice, &pIPCMemHandleData, &ipcMemHandleDataSize, &ppMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCOpenMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCOpenMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCOpenMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_close_mem_handle_exp_params_t params = {&hContext, &pMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCCloseMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCCloseMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCCloseMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -12485,6 +12674,40 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp 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 urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_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->pfnGetMemHandleExp = driver::urIPCGetMemHandleExp; + + pDdiTable->pfnPutMemHandleExp = driver::urIPCPutMemHandleExp; + + pDdiTable->pfnOpenMemHandleExp = driver::urIPCOpenMemHandleExp; + + pDdiTable->pfnCloseMemHandleExp = driver::urIPCCloseMemHandleExp; + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses diff --git a/unified-runtime/source/adapters/native_cpu/device.cpp b/unified-runtime/source/adapters/native_cpu/device.cpp index 369b4cd7ed013..4fed1565f8cfd 100644 --- a/unified-runtime/source/adapters/native_cpu/device.cpp +++ b/unified-runtime/source/adapters/native_cpu/device.cpp @@ -376,6 +376,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: return ReturnValue( static_cast(0)); + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(false); case UR_DEVICE_INFO_ATOMIC_FENCE_ORDER_CAPABILITIES: { // Currently for Native CPU fences are implemented using OCK // builtins, so we have different capabilities than atomic operations diff --git a/unified-runtime/source/adapters/native_cpu/memory.cpp b/unified-runtime/source/adapters/native_cpu/memory.cpp index 67eb95f3d9523..15eef80246e66 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.cpp +++ b/unified-runtime/source/adapters/native_cpu/memory.cpp @@ -138,3 +138,26 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo( DIE_NO_IMPLEMENTATION; } + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp index 3f6fe061b4917..492f005c866dd 100644 --- a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp @@ -435,6 +435,21 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -457,6 +472,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/offload/memory.cpp b/unified-runtime/source/adapters/offload/memory.cpp index 1a5b0df330c23..f17b4f76c636c 100644 --- a/unified-runtime/source/adapters/offload/memory.cpp +++ b/unified-runtime/source/adapters/offload/memory.cpp @@ -161,3 +161,26 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo(ur_mem_handle_t, void *, size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp index fa3adfdaf92bd..0e1cbbf9994e4 100644 --- a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp @@ -388,6 +388,21 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -410,6 +425,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/opencl/device.cpp b/unified-runtime/source/adapters/opencl/device.cpp index f641ba100860d..002011a0d5ee9 100644 --- a/unified-runtime/source/adapters/opencl/device.cpp +++ b/unified-runtime/source/adapters/opencl/device.cpp @@ -1368,6 +1368,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, return ReturnValue(UR_EXP_DEVICE_2D_BLOCK_ARRAY_CAPABILITY_FLAG_LOAD | UR_EXP_DEVICE_2D_BLOCK_ARRAY_CAPABILITY_FLAG_STORE); } + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(false); case UR_DEVICE_INFO_BFLOAT16_CONVERSIONS_NATIVE: { bool Supported = false; UR_RETURN_ON_FAILURE(hDevice->checkDeviceExtensions( diff --git a/unified-runtime/source/adapters/opencl/memory.cpp b/unified-runtime/source/adapters/opencl/memory.cpp index 19e9509987825..cda15dfa4db81 100644 --- a/unified-runtime/source/adapters/opencl/memory.cpp +++ b/unified-runtime/source/adapters/opencl/memory.cpp @@ -579,3 +579,26 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemRelease(ur_mem_handle_t hMem) { } return UR_RESULT_SUCCESS; } + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + 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 c619fa36b1ab0..cf473f6526808 100644 --- a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp @@ -438,6 +438,21 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -460,6 +475,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp index 80993d811a397..732e89bf12d0a 100644 --- a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp +++ b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp @@ -9578,6 +9578,164 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + auto pfnGetMemHandleExp = getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; + + if (nullptr == pfnGetMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_get_mem_handle_exp_params_t params = { + &hContext, &pMem, &pIPCMemHandleData, &pIPCMemHandleDataSizeRet}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, "urIPCGetMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCGetMemHandleExp\n"); + + ur_result_t result = pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); + + getContext()->notify_end(UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, + "urIPCGetMemHandleExp", ¶ms, &result, instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCGetMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { + auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; + + if (nullptr == pfnPutMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &pIPCMemHandleData}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, "urIPCPutMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCPutMemHandleExp\n"); + + ur_result_t result = pfnPutMemHandleExp(hContext, pIPCMemHandleData); + + getContext()->notify_end(UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, + "urIPCPutMemHandleExp", ¶ms, &result, instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCPutMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *pIPCMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + auto pfnOpenMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnOpenMemHandleExp; + + if (nullptr == pfnOpenMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_open_mem_handle_exp_params_t params = { + &hContext, &hDevice, &pIPCMemHandleData, &ipcMemHandleDataSize, &ppMem}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, "urIPCOpenMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCOpenMemHandleExp\n"); + + ur_result_t result = pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, + ipcMemHandleDataSize, ppMem); + + getContext()->notify_end(UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, + "urIPCOpenMemHandleExp", ¶ms, &result, instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCOpenMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + auto pfnCloseMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnCloseMemHandleExp; + + if (nullptr == pfnCloseMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_close_mem_handle_exp_params_t params = {&hContext, &pMem}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP, "urIPCCloseMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCCloseMemHandleExp\n"); + + ur_result_t result = pfnCloseMemHandleExp(hContext, pMem); + + getContext()->notify_end(UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP, + "urIPCCloseMemHandleExp", ¶ms, &result, + instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCCloseMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -10787,6 +10945,46 @@ __urdlllocal ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } /////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp 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 urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable) { + auto &dditable = ur_tracing_layer::getContext()->urDdiTable.IPCExp; + + 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.pfnGetMemHandleExp = pDdiTable->pfnGetMemHandleExp; + pDdiTable->pfnGetMemHandleExp = ur_tracing_layer::urIPCGetMemHandleExp; + + dditable.pfnPutMemHandleExp = pDdiTable->pfnPutMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur_tracing_layer::urIPCPutMemHandleExp; + + dditable.pfnOpenMemHandleExp = pDdiTable->pfnOpenMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur_tracing_layer::urIPCOpenMemHandleExp; + + dditable.pfnCloseMemHandleExp = pDdiTable->pfnCloseMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur_tracing_layer::urIPCCloseMemHandleExp; + + return result; +} +/////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses /// @@ -11594,6 +11792,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable, &dditable->Event); } + if (UR_RESULT_SUCCESS == result) { + result = ur_tracing_layer::urGetIPCExpProcAddrTable(UR_API_VERSION_CURRENT, + &dditable->IPCExp); + } + if (UR_RESULT_SUCCESS == result) { result = ur_tracing_layer::urGetKernelProcAddrTable(UR_API_VERSION_CURRENT, &dditable->Kernel); diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index 6b6afc878eead..8924809ee4781 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -10340,6 +10340,159 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + auto pfnGetMemHandleExp = getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; + + if (nullptr == pfnGetMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == pIPCMemHandleDataSizeRet) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { + auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; + + if (nullptr == pfnPutMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnPutMemHandleExp(hContext, pIPCMemHandleData); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *pIPCMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + auto pfnOpenMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnOpenMemHandleExp; + + if (nullptr == pfnOpenMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == ppMem) + 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 (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 = pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, + ipcMemHandleDataSize, ppMem); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + auto pfnCloseMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnCloseMemHandleExp; + + if (nullptr == pfnCloseMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == pMem) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnCloseMemHandleExp(hContext, pMem); + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -11588,6 +11741,47 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp 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 urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable) { + auto &dditable = ur_validation_layer::getContext()->urDdiTable.IPCExp; + + 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.pfnGetMemHandleExp = pDdiTable->pfnGetMemHandleExp; + pDdiTable->pfnGetMemHandleExp = ur_validation_layer::urIPCGetMemHandleExp; + + dditable.pfnPutMemHandleExp = pDdiTable->pfnPutMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur_validation_layer::urIPCPutMemHandleExp; + + dditable.pfnOpenMemHandleExp = pDdiTable->pfnOpenMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur_validation_layer::urIPCOpenMemHandleExp; + + dditable.pfnCloseMemHandleExp = pDdiTable->pfnCloseMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur_validation_layer::urIPCCloseMemHandleExp; + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses @@ -12430,6 +12624,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::urGetIPCExpProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->IPCExp); + } + if (UR_RESULT_SUCCESS == result) { result = ur_validation_layer::urGetKernelProcAddrTable( UR_API_VERSION_CURRENT, &dditable->Kernel); diff --git a/unified-runtime/source/loader/loader.def.in b/unified-runtime/source/loader/loader.def.in index e86a6c65a7957..b59fae08e176e 100644 --- a/unified-runtime/source/loader/loader.def.in +++ b/unified-runtime/source/loader/loader.def.in @@ -118,6 +118,7 @@ EXPORTS urGetEnqueueExpProcAddrTable urGetEnqueueProcAddrTable urGetEventProcAddrTable + urGetIPCExpProcAddrTable urGetKernelProcAddrTable urGetMemProcAddrTable urGetMemoryExportExpProcAddrTable @@ -131,6 +132,10 @@ EXPORTS urGetUSMProcAddrTable urGetUsmP2PExpProcAddrTable urGetVirtualMemProcAddrTable + urIPCCloseMemHandleExp + urIPCGetMemHandleExp + urIPCOpenMemHandleExp + urIPCPutMemHandleExp urKernelCreate urKernelCreateWithNativeHandle urKernelGetGroupInfo @@ -362,6 +367,10 @@ EXPORTS urPrintImageDesc urPrintImageFormat urPrintImageInfo + urPrintIpcCloseMemHandleExpParams + urPrintIpcGetMemHandleExpParams + urPrintIpcOpenMemHandleExpParams + urPrintIpcPutMemHandleExpParams urPrintKernelArgLocalProperties urPrintKernelArgMemObjProperties urPrintKernelArgPointerProperties diff --git a/unified-runtime/source/loader/loader.map.in b/unified-runtime/source/loader/loader.map.in index 6a30c9186f674..29786cd51b52b 100644 --- a/unified-runtime/source/loader/loader.map.in +++ b/unified-runtime/source/loader/loader.map.in @@ -118,6 +118,7 @@ urGetEnqueueExpProcAddrTable; urGetEnqueueProcAddrTable; urGetEventProcAddrTable; + urGetIPCExpProcAddrTable; urGetKernelProcAddrTable; urGetMemProcAddrTable; urGetMemoryExportExpProcAddrTable; @@ -131,6 +132,10 @@ urGetUSMProcAddrTable; urGetUsmP2PExpProcAddrTable; urGetVirtualMemProcAddrTable; + urIPCCloseMemHandleExp; + urIPCGetMemHandleExp; + urIPCOpenMemHandleExp; + urIPCPutMemHandleExp; urKernelCreate; urKernelCreateWithNativeHandle; urKernelGetGroupInfo; @@ -362,6 +367,10 @@ urPrintImageDesc; urPrintImageFormat; urPrintImageInfo; + urPrintIpcCloseMemHandleExpParams; + urPrintIpcGetMemHandleExpParams; + urPrintIpcOpenMemHandleExpParams; + urPrintIpcPutMemHandleExpParams; urPrintKernelArgLocalProperties; urPrintKernelArgMemObjProperties; urPrintKernelArgPointerProperties; diff --git a/unified-runtime/source/loader/ur_ldrddi.cpp b/unified-runtime/source/loader/ur_ldrddi.cpp index 80ff806b0e116..2e0201e8b4142 100644 --- a/unified-runtime/source/loader/ur_ldrddi.cpp +++ b/unified-runtime/source/loader/ur_ldrddi.cpp @@ -5455,6 +5455,91 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( phEventWaitList, phEvent); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnGetMemHandleExp = dditable->IPCExp.pfnGetMemHandleExp; + if (nullptr == pfnGetMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnPutMemHandleExp = dditable->IPCExp.pfnPutMemHandleExp; + if (nullptr == pfnPutMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnPutMemHandleExp(hContext, pIPCMemHandleData); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *pIPCMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnOpenMemHandleExp = dditable->IPCExp.pfnOpenMemHandleExp; + if (nullptr == pfnOpenMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, + ipcMemHandleDataSize, ppMem); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnCloseMemHandleExp = dditable->IPCExp.pfnCloseMemHandleExp; + if (nullptr == pfnCloseMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnCloseMemHandleExp(hContext, pMem); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -6325,6 +6410,61 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp 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 urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_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(), + "urGetIPCExpProcAddrTable")); + if (!getTable) + continue; + platform.initStatus = getTable(version, &platform.dditable.IPCExp); + } + + if (UR_RESULT_SUCCESS == result) { + if (ur_loader::getContext()->platforms.size() != 1 || + ur_loader::getContext()->forceIntercept) { + // return pointers to loader's DDIs + pDdiTable->pfnGetMemHandleExp = ur_loader::urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur_loader::urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur_loader::urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur_loader::urIPCCloseMemHandleExp; + } else { + // return pointers directly to platform's DDIs + *pDdiTable = ur_loader::getContext()->platforms.front().dditable.IPCExp; + } + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses diff --git a/unified-runtime/source/loader/ur_libapi.cpp b/unified-runtime/source/loader/ur_libapi.cpp index 85a085c8fb6bf..c5f248f645ffd 100644 --- a/unified-runtime/source/loader/ur_libapi.cpp +++ b/unified-runtime/source/loader/ur_libapi.cpp @@ -10015,6 +10015,147 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets an inter-process memory handle for a pointer to device USM +/// memory +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == pIPCMemHandleDataSizeRet` +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) try { + auto pfnGetMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; + if (nullptr == pfnGetMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Releases an inter-process memory handle +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) try { + auto pfnPutMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; + if (nullptr == pfnPutMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnPutMemHandleExp(hContext, pIPCMemHandleData); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory +/// +/// @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_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == ppMem` +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *pIPCMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] pointer to a pointer to device USM memory + void **ppMem) try { + auto pfnOpenMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnOpenMemHandleExp; + if (nullptr == pfnOpenMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, + ipcMemHandleDataSize, ppMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Closes an inter-process memory handle +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) try { + auto pfnCloseMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnCloseMemHandleExp; + if (nullptr == pfnCloseMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnCloseMemHandleExp(hContext, pMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. diff --git a/unified-runtime/source/loader/ur_libddi.cpp b/unified-runtime/source/loader/ur_libddi.cpp index b06ee531cdb46..648fc87872188 100644 --- a/unified-runtime/source/loader/ur_libddi.cpp +++ b/unified-runtime/source/loader/ur_libddi.cpp @@ -56,6 +56,11 @@ __urdlllocal ur_result_t context_t::ddiInit() { result = urGetEventProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Event); } + if (UR_RESULT_SUCCESS == result) { + result = + urGetIPCExpProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.IPCExp); + } + if (UR_RESULT_SUCCESS == result) { result = urGetKernelProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Kernel); diff --git a/unified-runtime/source/loader/ur_print.cpp b/unified-runtime/source/loader/ur_print.cpp index 06619c8f7f625..6d887d494fc3e 100644 --- a/unified-runtime/source/loader/ur_print.cpp +++ b/unified-runtime/source/loader/ur_print.cpp @@ -2009,6 +2009,38 @@ ur_result_t urPrintEventSetCallbackParams( return str_copy(&ss, buffer, buff_size, out_size); } +ur_result_t urPrintIpcGetMemHandleExpParams( + const struct ur_ipc_get_mem_handle_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 urPrintIpcPutMemHandleExpParams( + const struct ur_ipc_put_mem_handle_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 urPrintIpcOpenMemHandleExpParams( + const struct ur_ipc_open_mem_handle_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 urPrintIpcCloseMemHandleExpParams( + const struct ur_ipc_close_mem_handle_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 urPrintKernelCreateParams(const struct ur_kernel_create_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 ebcdbe1a7882d..4ab0bf014958f 100644 --- a/unified-runtime/source/ur_api.cpp +++ b/unified-runtime/source/ur_api.cpp @@ -8722,6 +8722,121 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets an inter-process memory handle for a pointer to device USM +/// memory +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == pIPCMemHandleDataSizeRet` +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Releases an inter-process memory handle +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory +/// +/// @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_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == ppMem` +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *pIPCMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Closes an inter-process memory handle +/// +/// @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` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. diff --git a/unified-runtime/tools/urinfo/urinfo.hpp b/unified-runtime/tools/urinfo/urinfo.hpp index 41999350f9edf..0440269c589b9 100644 --- a/unified-runtime/tools/urinfo/urinfo.hpp +++ b/unified-runtime/tools/urinfo/urinfo.hpp @@ -445,6 +445,8 @@ inline void printDeviceInfos(ur_device_handle_t hDevice, printDeviceInfo( hDevice, UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP); std::cout << prefix; + printDeviceInfo(hDevice, UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP); + std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP); std::cout << prefix;