diff --git a/include/ur.py b/include/ur.py index 8303f67d60..21d467255e 100644 --- a/include/ur.py +++ b/include/ur.py @@ -1971,6 +1971,8 @@ class ur_function_v(IntEnum): PHYSICAL_MEM_CREATE = 160 ## Enumerator for ::urPhysicalMemCreate PHYSICAL_MEM_RETAIN = 161 ## Enumerator for ::urPhysicalMemRetain PHYSICAL_MEM_RELEASE = 162 ## Enumerator for ::urPhysicalMemRelease + USM_IMPORT_EXP = 163 ## Enumerator for ::urUSMImportExp + USM_RELEASE_EXP = 164 ## Enumerator for ::urUSMReleaseExp class ur_function_t(c_int): def __str__(self): @@ -3193,12 +3195,28 @@ class ur_usm_dditable_t(Structure): else: _urUSMPitchedAllocExp_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, ur_device_handle_t, POINTER(ur_usm_desc_t), ur_usm_pool_handle_t, c_size_t, c_size_t, c_size_t, POINTER(c_void_p), POINTER(c_size_t) ) +############################################################################### +## @brief Function-pointer for urUSMImportExp +if __use_win_types: + _urUSMImportExp_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t ) +else: + _urUSMImportExp_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t ) + +############################################################################### +## @brief Function-pointer for urUSMReleaseExp +if __use_win_types: + _urUSMReleaseExp_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p ) +else: + _urUSMReleaseExp_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p ) + ############################################################################### ## @brief Table of USMExp functions pointers class ur_usm_exp_dditable_t(Structure): _fields_ = [ - ("pfnPitchedAllocExp", c_void_p) ## _urUSMPitchedAllocExp_t + ("pfnPitchedAllocExp", c_void_p), ## _urUSMPitchedAllocExp_t + ("pfnImportExp", c_void_p), ## _urUSMImportExp_t + ("pfnReleaseExp", c_void_p) ## _urUSMReleaseExp_t ] ############################################################################### @@ -3728,6 +3746,8 @@ def __init__(self, version : ur_api_version_t): # attach function interface to function address self.urUSMPitchedAllocExp = _urUSMPitchedAllocExp_t(self.__dditable.USMExp.pfnPitchedAllocExp) + self.urUSMImportExp = _urUSMImportExp_t(self.__dditable.USMExp.pfnImportExp) + self.urUSMReleaseExp = _urUSMReleaseExp_t(self.__dditable.USMExp.pfnReleaseExp) # call driver to get function pointers CommandBufferExp = ur_command_buffer_exp_dditable_t() diff --git a/include/ur_api.h b/include/ur_api.h index 07583f789a..0470bcccc9 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -5163,6 +5163,8 @@ typedef enum ur_function_t { UR_FUNCTION_PHYSICAL_MEM_CREATE = 160, ///< Enumerator for ::urPhysicalMemCreate UR_FUNCTION_PHYSICAL_MEM_RETAIN = 161, ///< Enumerator for ::urPhysicalMemRetain UR_FUNCTION_PHYSICAL_MEM_RELEASE = 162, ///< Enumerator for ::urPhysicalMemRelease + UR_FUNCTION_USM_IMPORT_EXP = 163, ///< Enumerator for ::urUSMImportExp + UR_FUNCTION_USM_RELEASE_EXP = 164, ///< Enumerator for ::urUSMReleaseExp /// @cond UR_FUNCTION_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -7226,6 +7228,57 @@ urCommandBufferEnqueueExp( ///< command-buffer execution instance. ); +#if !defined(__GNUC__) +#pragma endregion +#endif +// Intel 'oneAPI' USM Import/Release Extension APIs +#if !defined(__GNUC__) +#pragma region usm import release(experimental) +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Import memory into USM +/// +/// @details +/// - Import memory into USM +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_SIZE +UR_APIEXPORT ur_result_t UR_APICALL +urUSMImportExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem, ///< [in] pointer to host memory object + size_t size ///< [in] size in bytes of the host memory object to be imported +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Release memory from USM +/// +/// @details +/// - Release memory from USM +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +UR_APIEXPORT ur_result_t UR_APICALL +urUSMReleaseExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem ///< [in] pointer to host memory object +); + #if !defined(__GNUC__) #pragma endregion #endif @@ -8727,6 +8780,25 @@ typedef struct ur_usm_pitched_alloc_exp_params_t { size_t **ppResultPitch; } ur_usm_pitched_alloc_exp_params_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urUSMImportExp +/// @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_usm_import_exp_params_t { + ur_context_handle_t *phContext; + void **ppMem; + size_t *psize; +} ur_usm_import_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urUSMReleaseExp +/// @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_usm_release_exp_params_t { + ur_context_handle_t *phContext; + void **ppMem; +} ur_usm_release_exp_params_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urCommandBufferCreateExp /// @details Each entry is a pointer to the parameter passed to the function; diff --git a/include/ur_ddi.h b/include/ur_ddi.h index fc4f6cad26..25e775fef1 100644 --- a/include/ur_ddi.h +++ b/include/ur_ddi.h @@ -1568,10 +1568,25 @@ typedef ur_result_t(UR_APICALL *ur_pfnUSMPitchedAllocExp_t)( void **, size_t *); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urUSMImportExp +typedef ur_result_t(UR_APICALL *ur_pfnUSMImportExp_t)( + ur_context_handle_t, + void *, + size_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urUSMReleaseExp +typedef ur_result_t(UR_APICALL *ur_pfnUSMReleaseExp_t)( + ur_context_handle_t, + void *); + /////////////////////////////////////////////////////////////////////////////// /// @brief Table of USMExp functions pointers typedef struct ur_usm_exp_dditable_t { ur_pfnUSMPitchedAllocExp_t pfnPitchedAllocExp; + ur_pfnUSMImportExp_t pfnImportExp; + ur_pfnUSMReleaseExp_t pfnReleaseExp; } ur_usm_exp_dditable_t; /////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/core/EXP-USM-IMPORT-RELEASE.rst b/scripts/core/EXP-USM-IMPORT-RELEASE.rst new file mode 100755 index 0000000000..055991755b --- /dev/null +++ b/scripts/core/EXP-USM-IMPORT-RELEASE.rst @@ -0,0 +1,58 @@ + +<% + OneApi=tags['$OneApi'] + x=tags['$x'] + X=x.upper() +%> +.. _experimental-usm-import-release: + +================== +USM Import/Release +================== + +.. 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. + + +Data transfer between Host and Device is most efficient when source and +destination are both allocated in USM memory. +In situations where host data will participate in host/device transfers +and the host data allocation is under user control, USM functions +such as malloc_host could be used to allocate USM memory instead of +system memory. +However, this is not always possible if the source code where the allocation +is made is not available, or source code changes are prohibited for portability +reasons. +In these situations a mechanism to temporarily promote system memory to USM +for the duration of the host/device data transfers is useful for maximizing +data transfer rate. + + +Import Host Memory into USM +=========================== + +Import a range of host memory into USM. + +.. parsed-literal:: + + // Import into USM + ${x}USMImportExp(hContext, hostPtr, size); + +Release Host Memory Previously Imported into USM +================================================ + +Release from USM a range of memory that had been previously imported +into USM. + + +.. parsed-literal:: + + // Release from USM + ${x}USMReleaseExp(hContext, hostPtr); + diff --git a/scripts/core/exp-usm-import-release.yml b/scripts/core/exp-usm-import-release.yml new file mode 100755 index 0000000000..869bff64e8 --- /dev/null +++ b/scripts/core/exp-usm-import-release.yml @@ -0,0 +1,40 @@ +--- #-------------------------------------------------------------------------- +type: header +desc: "Intel $OneApi USM Import/Release Extension APIs" +ordinal: "99" +--- #-------------------------------------------------------------------------- +type: function +desc: "Import memory into USM" +class: $xUSM +name: ImportExp +details: + - "Import memory into USM" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: "void*" + name: pMem + desc: "[in] pointer to host memory object" + - type: "size_t" + name: size + desc: "[in] size in bytes of the host memory object to be imported" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_SIZE +--- #-------------------------------------------------------------------------- +type: function +desc: "Release memory from USM" +class: $xUSM +name: ReleaseExp +details: + - "Release memory from USM" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: "void*" + name: pMem + desc: "[in] pointer to host memory object" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT diff --git a/scripts/core/registry.yml b/scripts/core/registry.yml index 873dc8dc07..42ef2a322a 100644 --- a/scripts/core/registry.yml +++ b/scripts/core/registry.yml @@ -475,3 +475,9 @@ etors: - name: PHYSICAL_MEM_RELEASE desc: Enumerator for $xPhysicalMemRelease value: '162' +- name: USM_IMPORT_EXP + desc: Enumerator for $xUSMImportExp + value: '163' +- name: USM_RELEASE_EXP + desc: Enumerator for $xUSMReleaseExp + value: '164' diff --git a/source/adapters/null/ur_nullddi.cpp b/source/adapters/null/ur_nullddi.cpp index b0a07d62cc..e7ba9338a5 100644 --- a/source/adapters/null/ur_nullddi.cpp +++ b/source/adapters/null/ur_nullddi.cpp @@ -4572,6 +4572,49 @@ __urdlllocal ur_result_t UR_APICALL urCommandBufferEnqueueExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMImportExp +__urdlllocal ur_result_t UR_APICALL urUSMImportExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem, ///< [in] pointer to host memory object + size_t size ///< [in] size in bytes of the host memory object to be imported + ) try { + ur_result_t result = UR_RESULT_SUCCESS; + + // if the driver has created a custom function, then call it instead of using the generic path + auto pfnImportExp = d_context.urDdiTable.USMExp.pfnImportExp; + if (nullptr != pfnImportExp) { + result = pfnImportExp(hContext, pMem, size); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMReleaseExp +__urdlllocal ur_result_t UR_APICALL urUSMReleaseExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem ///< [in] pointer to host memory object + ) try { + ur_result_t result = UR_RESULT_SUCCESS; + + // if the driver has created a custom function, then call it instead of using the generic path + auto pfnReleaseExp = d_context.urDdiTable.USMExp.pfnReleaseExp; + if (nullptr != pfnReleaseExp) { + result = pfnReleaseExp(hContext, pMem); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + } // namespace driver #if defined(__cplusplus) @@ -5300,6 +5343,10 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetUSMExpProcAddrTable( pDdiTable->pfnPitchedAllocExp = driver::urUSMPitchedAllocExp; + pDdiTable->pfnImportExp = driver::urUSMImportExp; + + pDdiTable->pfnReleaseExp = driver::urUSMReleaseExp; + return result; } catch (...) { return exceptionToResult(std::current_exception()); diff --git a/source/common/ur_params.hpp b/source/common/ur_params.hpp index 7a9bcf8a3a..f076fa1575 100644 --- a/source/common/ur_params.hpp +++ b/source/common/ur_params.hpp @@ -9001,6 +9001,14 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_function_t value) { case UR_FUNCTION_PHYSICAL_MEM_RELEASE: os << "UR_FUNCTION_PHYSICAL_MEM_RELEASE"; break; + + case UR_FUNCTION_USM_IMPORT_EXP: + os << "UR_FUNCTION_USM_IMPORT_EXP"; + break; + + case UR_FUNCTION_USM_RELEASE_EXP: + os << "UR_FUNCTION_USM_RELEASE_EXP"; + break; default: os << "unknown enumerator"; break; @@ -13534,6 +13542,41 @@ operator<<(std::ostream &os, return os; } +inline std::ostream & +operator<<(std::ostream &os, const struct ur_usm_import_exp_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pMem = "; + + ur_params::serializePtr(os, *(params->ppMem)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, const struct ur_usm_release_exp_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pMem = "; + + ur_params::serializePtr(os, *(params->ppMem)); + + return os; +} + inline std::ostream & operator<<(std::ostream &os, const struct ur_virtual_mem_granularity_get_info_params_t *params) { @@ -14444,6 +14487,12 @@ inline int serializeFunctionParams(std::ostream &os, uint32_t function, case UR_FUNCTION_USM_PITCHED_ALLOC_EXP: { os << (const struct ur_usm_pitched_alloc_exp_params_t *)params; } break; + case UR_FUNCTION_USM_IMPORT_EXP: { + os << (const struct ur_usm_import_exp_params_t *)params; + } break; + case UR_FUNCTION_USM_RELEASE_EXP: { + os << (const struct ur_usm_release_exp_params_t *)params; + } break; case UR_FUNCTION_VIRTUAL_MEM_GRANULARITY_GET_INFO: { os << (const struct ur_virtual_mem_granularity_get_info_params_t *) params; diff --git a/source/loader/layers/tracing/ur_trcddi.cpp b/source/loader/layers/tracing/ur_trcddi.cpp index 751e56d850..935938b37e 100644 --- a/source/loader/layers/tracing/ur_trcddi.cpp +++ b/source/loader/layers/tracing/ur_trcddi.cpp @@ -5241,6 +5241,55 @@ __urdlllocal ur_result_t UR_APICALL urCommandBufferEnqueueExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMImportExp +__urdlllocal ur_result_t UR_APICALL urUSMImportExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem, ///< [in] pointer to host memory object + size_t size ///< [in] size in bytes of the host memory object to be imported +) { + auto pfnImportExp = context.urDdiTable.USMExp.pfnImportExp; + + if (nullptr == pfnImportExp) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_usm_import_exp_params_t params = {&hContext, &pMem, &size}; + uint64_t instance = context.notify_begin(UR_FUNCTION_USM_IMPORT_EXP, + "urUSMImportExp", ¶ms); + + ur_result_t result = pfnImportExp(hContext, pMem, size); + + context.notify_end(UR_FUNCTION_USM_IMPORT_EXP, "urUSMImportExp", ¶ms, + &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMReleaseExp +__urdlllocal ur_result_t UR_APICALL urUSMReleaseExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem ///< [in] pointer to host memory object +) { + auto pfnReleaseExp = context.urDdiTable.USMExp.pfnReleaseExp; + + if (nullptr == pfnReleaseExp) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_usm_release_exp_params_t params = {&hContext, &pMem}; + uint64_t instance = context.notify_begin(UR_FUNCTION_USM_RELEASE_EXP, + "urUSMReleaseExp", ¶ms); + + ur_result_t result = pfnReleaseExp(hContext, pMem); + + context.notify_end(UR_FUNCTION_USM_RELEASE_EXP, "urUSMReleaseExp", ¶ms, + &result, instance); + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Global table /// with current process' addresses @@ -6162,6 +6211,12 @@ __urdlllocal ur_result_t UR_APICALL urGetUSMExpProcAddrTable( dditable.pfnPitchedAllocExp = pDdiTable->pfnPitchedAllocExp; pDdiTable->pfnPitchedAllocExp = ur_tracing_layer::urUSMPitchedAllocExp; + dditable.pfnImportExp = pDdiTable->pfnImportExp; + pDdiTable->pfnImportExp = ur_tracing_layer::urUSMImportExp; + + dditable.pfnReleaseExp = pDdiTable->pfnReleaseExp; + pDdiTable->pfnReleaseExp = ur_tracing_layer::urUSMReleaseExp; + return result; } /////////////////////////////////////////////////////////////////////////////// diff --git a/source/loader/layers/validation/ur_valddi.cpp b/source/loader/layers/validation/ur_valddi.cpp index 4d5b417e01..593e5418b2 100644 --- a/source/loader/layers/validation/ur_valddi.cpp +++ b/source/loader/layers/validation/ur_valddi.cpp @@ -6509,6 +6509,65 @@ __urdlllocal ur_result_t UR_APICALL urCommandBufferEnqueueExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMImportExp +__urdlllocal ur_result_t UR_APICALL urUSMImportExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem, ///< [in] pointer to host memory object + size_t size ///< [in] size in bytes of the host memory object to be imported +) { + auto pfnImportExp = context.urDdiTable.USMExp.pfnImportExp; + + if (nullptr == pfnImportExp) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == pMem) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + } + + ur_result_t result = pfnImportExp(hContext, pMem, size); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMReleaseExp +__urdlllocal ur_result_t UR_APICALL urUSMReleaseExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem ///< [in] pointer to host memory object +) { + auto pfnReleaseExp = context.urDdiTable.USMExp.pfnReleaseExp; + + if (nullptr == pfnReleaseExp) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == pMem) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + } + + ur_result_t result = pfnReleaseExp(hContext, pMem); + + if (context.enableLeakChecking && result == UR_RESULT_SUCCESS) { + refCountContext.decrementRefCount(pMem); + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Global table /// with current process' addresses @@ -7453,6 +7512,12 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetUSMExpProcAddrTable( dditable.pfnPitchedAllocExp = pDdiTable->pfnPitchedAllocExp; pDdiTable->pfnPitchedAllocExp = ur_validation_layer::urUSMPitchedAllocExp; + dditable.pfnImportExp = pDdiTable->pfnImportExp; + pDdiTable->pfnImportExp = ur_validation_layer::urUSMImportExp; + + dditable.pfnReleaseExp = pDdiTable->pfnReleaseExp; + pDdiTable->pfnReleaseExp = ur_validation_layer::urUSMReleaseExp; + return result; } diff --git a/source/loader/ur_ldrddi.cpp b/source/loader/ur_ldrddi.cpp index 4feceb7aba..8a2a7f4f85 100644 --- a/source/loader/ur_ldrddi.cpp +++ b/source/loader/ur_ldrddi.cpp @@ -6370,6 +6370,55 @@ __urdlllocal ur_result_t UR_APICALL urCommandBufferEnqueueExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMImportExp +__urdlllocal ur_result_t UR_APICALL urUSMImportExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem, ///< [in] pointer to host memory object + size_t size ///< [in] size in bytes of the host memory object to be imported +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnImportExp = dditable->ur.USMExp.pfnImportExp; + if (nullptr == pfnImportExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // forward to device-platform + result = pfnImportExp(hContext, pMem, size); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urUSMReleaseExp +__urdlllocal ur_result_t UR_APICALL urUSMReleaseExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem ///< [in] pointer to host memory object +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnReleaseExp = dditable->ur.USMExp.pfnReleaseExp; + if (nullptr == pfnReleaseExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // forward to device-platform + result = pfnReleaseExp(hContext, pMem); + + return result; +} + } // namespace ur_loader #if defined(__cplusplus) @@ -7334,6 +7383,8 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetUSMExpProcAddrTable( ur_loader::context->forceIntercept) { // return pointers to loader's DDIs pDdiTable->pfnPitchedAllocExp = ur_loader::urUSMPitchedAllocExp; + pDdiTable->pfnImportExp = ur_loader::urUSMImportExp; + pDdiTable->pfnReleaseExp = ur_loader::urUSMReleaseExp; } else { // return pointers directly to platform's DDIs *pDdiTable = diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index f82cd8d18b..b47ff9b8f1 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -6727,4 +6727,64 @@ ur_result_t UR_APICALL urCommandBufferEnqueueExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Import memory into USM +/// +/// @details +/// - Import memory into USM +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_SIZE +ur_result_t UR_APICALL urUSMImportExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem, ///< [in] pointer to host memory object + size_t size ///< [in] size in bytes of the host memory object to be imported + ) try { + auto pfnImportExp = ur_lib::context->urDdiTable.USMExp.pfnImportExp; + if (nullptr == pfnImportExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnImportExp(hContext, pMem, size); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Release memory from USM +/// +/// @details +/// - Release memory from USM +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +ur_result_t UR_APICALL urUSMReleaseExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem ///< [in] pointer to host memory object + ) try { + auto pfnReleaseExp = ur_lib::context->urDdiTable.USMExp.pfnReleaseExp; + if (nullptr == pfnReleaseExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnReleaseExp(hContext, pMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + } // extern "C" diff --git a/source/ur_api.cpp b/source/ur_api.cpp index d5d4888570..e511ee4554 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -5619,3 +5619,51 @@ ur_result_t UR_APICALL urCommandBufferEnqueueExp( ur_result_t result = UR_RESULT_SUCCESS; return result; } + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Import memory into USM +/// +/// @details +/// - Import memory into USM +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_SIZE +ur_result_t UR_APICALL urUSMImportExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem, ///< [in] pointer to host memory object + size_t size ///< [in] size in bytes of the host memory object to be imported +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Release memory from USM +/// +/// @details +/// - Release memory from USM +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pMem` +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +ur_result_t UR_APICALL urUSMReleaseExp( + ur_context_handle_t hContext, ///< [in] handle of the context object + void *pMem ///< [in] pointer to host memory object +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +}