diff --git a/include/ur.py b/include/ur.py index 2031477aa4..8303f67d60 100644 --- a/include/ur.py +++ b/include/ur.py @@ -105,6 +105,11 @@ class ur_sampler_handle_t(c_void_p): class ur_mem_handle_t(c_void_p): pass +############################################################################### +## @brief Handle of physical memory object +class ur_physical_mem_handle_t(c_void_p): + pass + ############################################################################### ## @brief Generic macro for enumerator bit masks def UR_BIT( _i ): @@ -234,6 +239,7 @@ class ur_structure_type_v(IntEnum): EXP_COMMAND_BUFFER_DESC = 27 ## ::ur_exp_command_buffer_desc_t EXP_SAMPLER_MIP_PROPERTIES = 28 ## ::ur_exp_sampler_mip_properties_t KERNEL_ARG_MEM_OBJ_PROPERTIES = 29 ## ::ur_kernel_arg_mem_obj_properties_t + PHYSICAL_MEM_PROPERTIES = 30 ## ::ur_physical_mem_properties_t class ur_structure_type_t(c_int): def __str__(self): @@ -1304,6 +1310,59 @@ def __str__(self): return str(ur_usm_pool_info_v(self.value)) +############################################################################### +## @brief Virtual memory granularity info +class ur_virtual_mem_granularity_info_v(IntEnum): + MINIMUM = 0x30100 ## [size_t] size in bytes of the minimum virtual memory granularity. + RECOMMENDED = 0x30101 ## [size_t] size in bytes of the recommended virtual memory granularity. + +class ur_virtual_mem_granularity_info_t(c_int): + def __str__(self): + return str(ur_virtual_mem_granularity_info_v(self.value)) + + +############################################################################### +## @brief Virtual memory access mode flags. +class ur_virtual_mem_access_flags_v(IntEnum): + READ_WRITE = UR_BIT(0) ## Virtual memory both read and write accessible + READ_ONLY = UR_BIT(1) ## + +class ur_virtual_mem_access_flags_t(c_int): + def __str__(self): + return hex(self.value) + + +############################################################################### +## @brief Virtual memory range info queries. +class ur_virtual_mem_info_v(IntEnum): + ACCESS_MODE = 0 ## [::ur_virtual_mem_access_flags_t] access flags of a mapped virtual + ## memory range. + +class ur_virtual_mem_info_t(c_int): + def __str__(self): + return str(ur_virtual_mem_info_v(self.value)) + + +############################################################################### +## @brief Physical memory creation properties. +class ur_physical_mem_flags_v(IntEnum): + TBD = UR_BIT(0) ## reserved for future use. + +class ur_physical_mem_flags_t(c_int): + def __str__(self): + return hex(self.value) + + +############################################################################### +## @brief Physical memory creation properties. +class ur_physical_mem_properties_t(Structure): + _fields_ = [ + ("stype", ur_structure_type_t), ## [in] type of this structure, must be + ## ::UR_STRUCTURE_TYPE_PHYSICAL_MEM_PROPERTIES + ("pNext", c_void_p), ## [in,out][optional] pointer to extension-specific structure + ("flags", ur_physical_mem_flags_t) ## [in] physical memory creation flags + ] + ############################################################################### ## @brief Program metadata property type. class ur_program_metadata_type_v(IntEnum): @@ -1902,6 +1961,16 @@ class ur_function_v(IntEnum): PLATFORM_GET_LAST_ERROR = 150 ## Enumerator for ::urPlatformGetLastError ENQUEUE_USM_FILL_2D = 151 ## Enumerator for ::urEnqueueUSMFill2D ENQUEUE_USM_MEMCPY_2D = 152 ## Enumerator for ::urEnqueueUSMMemcpy2D + VIRTUAL_MEM_GRANULARITY_GET_INFO = 153 ## Enumerator for ::urVirtualMemGranularityGetInfo + VIRTUAL_MEM_RESERVE = 154 ## Enumerator for ::urVirtualMemReserve + VIRTUAL_MEM_FREE = 155 ## Enumerator for ::urVirtualMemFree + VIRTUAL_MEM_MAP = 156 ## Enumerator for ::urVirtualMemMap + VIRTUAL_MEM_UNMAP = 157 ## Enumerator for ::urVirtualMemUnmap + VIRTUAL_MEM_SET_ACCESS = 158 ## Enumerator for ::urVirtualMemSetAccess + VIRTUAL_MEM_GET_INFO = 159 ## Enumerator for ::urVirtualMemGetInfo + PHYSICAL_MEM_CREATE = 160 ## Enumerator for ::urPhysicalMemCreate + PHYSICAL_MEM_RETAIN = 161 ## Enumerator for ::urPhysicalMemRetain + PHYSICAL_MEM_RELEASE = 162 ## Enumerator for ::urPhysicalMemRelease class ur_function_t(c_int): def __str__(self): @@ -2586,6 +2655,37 @@ class ur_mem_dditable_t(Structure): ("pfnImageGetInfo", c_void_p) ## _urMemImageGetInfo_t ] +############################################################################### +## @brief Function-pointer for urPhysicalMemCreate +if __use_win_types: + _urPhysicalMemCreate_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, ur_device_handle_t, c_size_t, POINTER(ur_physical_mem_properties_t), POINTER(ur_physical_mem_handle_t) ) +else: + _urPhysicalMemCreate_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, ur_device_handle_t, c_size_t, POINTER(ur_physical_mem_properties_t), POINTER(ur_physical_mem_handle_t) ) + +############################################################################### +## @brief Function-pointer for urPhysicalMemRetain +if __use_win_types: + _urPhysicalMemRetain_t = WINFUNCTYPE( ur_result_t, ur_physical_mem_handle_t ) +else: + _urPhysicalMemRetain_t = CFUNCTYPE( ur_result_t, ur_physical_mem_handle_t ) + +############################################################################### +## @brief Function-pointer for urPhysicalMemRelease +if __use_win_types: + _urPhysicalMemRelease_t = WINFUNCTYPE( ur_result_t, ur_physical_mem_handle_t ) +else: + _urPhysicalMemRelease_t = CFUNCTYPE( ur_result_t, ur_physical_mem_handle_t ) + + +############################################################################### +## @brief Table of PhysicalMem functions pointers +class ur_physical_mem_dditable_t(Structure): + _fields_ = [ + ("pfnCreate", c_void_p), ## _urPhysicalMemCreate_t + ("pfnRetain", c_void_p), ## _urPhysicalMemRetain_t + ("pfnRelease", c_void_p) ## _urPhysicalMemRelease_t + ] + ############################################################################### ## @brief Function-pointer for urEnqueueKernelLaunch if __use_win_types: @@ -3203,6 +3303,69 @@ class ur_global_dditable_t(Structure): ("pfnTearDown", c_void_p) ## _urTearDown_t ] +############################################################################### +## @brief Function-pointer for urVirtualMemGranularityGetInfo +if __use_win_types: + _urVirtualMemGranularityGetInfo_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, ur_device_handle_t, ur_virtual_mem_granularity_info_t, c_size_t, c_void_p, POINTER(c_size_t) ) +else: + _urVirtualMemGranularityGetInfo_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, ur_device_handle_t, ur_virtual_mem_granularity_info_t, c_size_t, c_void_p, POINTER(c_size_t) ) + +############################################################################### +## @brief Function-pointer for urVirtualMemReserve +if __use_win_types: + _urVirtualMemReserve_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, POINTER(c_void_p) ) +else: + _urVirtualMemReserve_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, POINTER(c_void_p) ) + +############################################################################### +## @brief Function-pointer for urVirtualMemFree +if __use_win_types: + _urVirtualMemFree_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t ) +else: + _urVirtualMemFree_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t ) + +############################################################################### +## @brief Function-pointer for urVirtualMemMap +if __use_win_types: + _urVirtualMemMap_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, ur_physical_mem_handle_t, c_size_t, ur_virtual_mem_access_flags_t ) +else: + _urVirtualMemMap_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, ur_physical_mem_handle_t, c_size_t, ur_virtual_mem_access_flags_t ) + +############################################################################### +## @brief Function-pointer for urVirtualMemUnmap +if __use_win_types: + _urVirtualMemUnmap_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t ) +else: + _urVirtualMemUnmap_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t ) + +############################################################################### +## @brief Function-pointer for urVirtualMemSetAccess +if __use_win_types: + _urVirtualMemSetAccess_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, ur_virtual_mem_access_flags_t ) +else: + _urVirtualMemSetAccess_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, ur_virtual_mem_access_flags_t ) + +############################################################################### +## @brief Function-pointer for urVirtualMemGetInfo +if __use_win_types: + _urVirtualMemGetInfo_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, ur_virtual_mem_info_t, c_size_t, c_void_p, POINTER(c_size_t) ) +else: + _urVirtualMemGetInfo_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, c_void_p, c_size_t, ur_virtual_mem_info_t, c_size_t, c_void_p, POINTER(c_size_t) ) + + +############################################################################### +## @brief Table of VirtualMem functions pointers +class ur_virtual_mem_dditable_t(Structure): + _fields_ = [ + ("pfnGranularityGetInfo", c_void_p), ## _urVirtualMemGranularityGetInfo_t + ("pfnReserve", c_void_p), ## _urVirtualMemReserve_t + ("pfnFree", c_void_p), ## _urVirtualMemFree_t + ("pfnMap", c_void_p), ## _urVirtualMemMap_t + ("pfnUnmap", c_void_p), ## _urVirtualMemUnmap_t + ("pfnSetAccess", c_void_p), ## _urVirtualMemSetAccess_t + ("pfnGetInfo", c_void_p) ## _urVirtualMemGetInfo_t + ] + ############################################################################### ## @brief Function-pointer for urDeviceGet if __use_win_types: @@ -3292,6 +3455,7 @@ class ur_dditable_t(Structure): ("Kernel", ur_kernel_dditable_t), ("Sampler", ur_sampler_dditable_t), ("Mem", ur_mem_dditable_t), + ("PhysicalMem", ur_physical_mem_dditable_t), ("Enqueue", ur_enqueue_dditable_t), ("Queue", ur_queue_dditable_t), ("BindlessImagesExp", ur_bindless_images_exp_dditable_t), @@ -3299,6 +3463,7 @@ class ur_dditable_t(Structure): ("USMExp", ur_usm_exp_dditable_t), ("CommandBufferExp", ur_command_buffer_exp_dditable_t), ("Global", ur_global_dditable_t), + ("VirtualMem", ur_virtual_mem_dditable_t), ("Device", ur_device_dditable_t) ] @@ -3447,6 +3612,18 @@ def __init__(self, version : ur_api_version_t): self.urMemGetInfo = _urMemGetInfo_t(self.__dditable.Mem.pfnGetInfo) self.urMemImageGetInfo = _urMemImageGetInfo_t(self.__dditable.Mem.pfnImageGetInfo) + # call driver to get function pointers + PhysicalMem = ur_physical_mem_dditable_t() + r = ur_result_v(self.__dll.urGetPhysicalMemProcAddrTable(version, byref(PhysicalMem))) + if r != ur_result_v.SUCCESS: + raise Exception(r) + self.__dditable.PhysicalMem = PhysicalMem + + # attach function interface to function address + self.urPhysicalMemCreate = _urPhysicalMemCreate_t(self.__dditable.PhysicalMem.pfnCreate) + self.urPhysicalMemRetain = _urPhysicalMemRetain_t(self.__dditable.PhysicalMem.pfnRetain) + self.urPhysicalMemRelease = _urPhysicalMemRelease_t(self.__dditable.PhysicalMem.pfnRelease) + # call driver to get function pointers Enqueue = ur_enqueue_dditable_t() r = ur_result_v(self.__dll.urGetEnqueueProcAddrTable(version, byref(Enqueue))) @@ -3581,6 +3758,22 @@ def __init__(self, version : ur_api_version_t): self.urInit = _urInit_t(self.__dditable.Global.pfnInit) self.urTearDown = _urTearDown_t(self.__dditable.Global.pfnTearDown) + # call driver to get function pointers + VirtualMem = ur_virtual_mem_dditable_t() + r = ur_result_v(self.__dll.urGetVirtualMemProcAddrTable(version, byref(VirtualMem))) + if r != ur_result_v.SUCCESS: + raise Exception(r) + self.__dditable.VirtualMem = VirtualMem + + # attach function interface to function address + self.urVirtualMemGranularityGetInfo = _urVirtualMemGranularityGetInfo_t(self.__dditable.VirtualMem.pfnGranularityGetInfo) + self.urVirtualMemReserve = _urVirtualMemReserve_t(self.__dditable.VirtualMem.pfnReserve) + self.urVirtualMemFree = _urVirtualMemFree_t(self.__dditable.VirtualMem.pfnFree) + self.urVirtualMemMap = _urVirtualMemMap_t(self.__dditable.VirtualMem.pfnMap) + self.urVirtualMemUnmap = _urVirtualMemUnmap_t(self.__dditable.VirtualMem.pfnUnmap) + self.urVirtualMemSetAccess = _urVirtualMemSetAccess_t(self.__dditable.VirtualMem.pfnSetAccess) + self.urVirtualMemGetInfo = _urVirtualMemGetInfo_t(self.__dditable.VirtualMem.pfnGetInfo) + # call driver to get function pointers Device = ur_device_dditable_t() r = ur_result_v(self.__dll.urGetDeviceProcAddrTable(version, byref(Device))) diff --git a/include/ur_api.h b/include/ur_api.h index ece0f74dbd..07583f789a 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -128,6 +128,10 @@ typedef struct ur_sampler_handle_t_ *ur_sampler_handle_t; /// @brief Handle of memory object which can either be buffer or image typedef struct ur_mem_handle_t_ *ur_mem_handle_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of physical memory object +typedef struct ur_physical_mem_handle_t_ *ur_physical_mem_handle_t; + /////////////////////////////////////////////////////////////////////////////// #ifndef UR_BIT /// @brief Generic macro for enumerator bit masks @@ -258,6 +262,7 @@ typedef enum ur_structure_type_t { UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_DESC = 27, ///< ::ur_exp_command_buffer_desc_t UR_STRUCTURE_TYPE_EXP_SAMPLER_MIP_PROPERTIES = 28, ///< ::ur_exp_sampler_mip_properties_t UR_STRUCTURE_TYPE_KERNEL_ARG_MEM_OBJ_PROPERTIES = 29, ///< ::ur_kernel_arg_mem_obj_properties_t + UR_STRUCTURE_TYPE_PHYSICAL_MEM_PROPERTIES = 30, ///< ::ur_physical_mem_properties_t /// @cond UR_STRUCTURE_TYPE_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -2962,6 +2967,282 @@ urUSMPoolGetInfo( size_t *pPropSizeRet ///< [out][optional] size in bytes returned in pool property value ); +#if !defined(__GNUC__) +#pragma endregion +#endif +// Intel 'oneAPI' Unified Runtime APIs +#if !defined(__GNUC__) +#pragma region virtual memory +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Virtual memory granularity info +typedef enum ur_virtual_mem_granularity_info_t { + UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM = 0x30100, ///< [size_t] size in bytes of the minimum virtual memory granularity. + UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED = 0x30101, ///< [size_t] size in bytes of the recommended virtual memory granularity. + /// @cond + UR_VIRTUAL_MEM_GRANULARITY_INFO_FORCE_UINT32 = 0x7fffffff + /// @endcond + +} ur_virtual_mem_granularity_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get information about the minimum and recommended granularity of +/// physical and virtual memory. +/// +/// @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_ENUMERATION +/// + `::UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED < propName` +UR_APIEXPORT ur_result_t UR_APICALL +urVirtualMemGranularityGetInfo( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in][optional] is the device to get the granularity from, if the + ///< device is null then the granularity is suitable for all devices in context. + ur_virtual_mem_granularity_info_t propName, ///< [in] type of the info to query. + size_t propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void *pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t *pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reserve a virtual memory range. +/// +/// @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 == ppStart` +UR_APIEXPORT ur_result_t UR_APICALL +urVirtualMemReserve( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void *pStart, ///< [in][optional] pointer to the start of the virtual memory region to + ///< reserve, specifying a null value causes the implementation to select a + ///< start address. + size_t size, ///< [in] size in bytes of the virtual address range to reserve. + void **ppStart ///< [out] pointer to the returned address at the start of reserved virtual + ///< memory range. +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Free a virtual memory range. +/// +/// @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 == pStart` +UR_APIEXPORT ur_result_t UR_APICALL +urVirtualMemFree( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void *pStart, ///< [in] pointer to the start of the virtual memory range to free. + size_t size ///< [in] size in bytes of the virtual memory range to free. +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Virtual memory access mode flags. +typedef uint32_t ur_virtual_mem_access_flags_t; +typedef enum ur_virtual_mem_access_flag_t { + UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE = UR_BIT(0), ///< Virtual memory both read and write accessible + UR_VIRTUAL_MEM_ACCESS_FLAG_READ_ONLY = UR_BIT(1), ///< + /// @cond + UR_VIRTUAL_MEM_ACCESS_FLAG_FORCE_UINT32 = 0x7fffffff + /// @endcond + +} ur_virtual_mem_access_flag_t; +/// @brief Bit Mask for validating ur_virtual_mem_access_flags_t +#define UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK 0xfffffffc + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Map a virtual memory range to a physical memory handle. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hPhysicalMem` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags` +UR_APIEXPORT ur_result_t UR_APICALL +urVirtualMemMap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range to map. + ur_physical_mem_handle_t hPhysicalMem, ///< [in] handle of the physical memory to map pStart to. + size_t offset, ///< [in] offset in bytes into the physical memory to map pStart to. + ur_virtual_mem_access_flags_t flags ///< [in] access flags for the physical memory mapping. +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Unmap a virtual memory range previously mapped in a context. +/// +/// @details +/// - After a call to this function, the virtual memory range is left in a +/// state ready to be remapped. +/// +/// @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 == pStart` +UR_APIEXPORT ur_result_t UR_APICALL +urVirtualMemUnmap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void *pStart, ///< [in] pointer to the start of the mapped virtual memory range + size_t size ///< [in] size in bytes of the virtual memory range. +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the access mode of a mapped virtual memory range. +/// +/// @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 == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags` +UR_APIEXPORT ur_result_t UR_APICALL +urVirtualMemSetAccess( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virutal memory range. + ur_virtual_mem_access_flags_t flags ///< [in] access flags to set for the mapped virtual memory range. +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Virtual memory range info queries. +typedef enum ur_virtual_mem_info_t { + UR_VIRTUAL_MEM_INFO_ACCESS_MODE = 0, ///< [::ur_virtual_mem_access_flags_t] access flags of a mapped virtual + ///< memory range. + /// @cond + UR_VIRTUAL_MEM_INFO_FORCE_UINT32 = 0x7fffffff + /// @endcond + +} ur_virtual_mem_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get information about a mapped virtual memory range. +/// +/// @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 == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_INFO_ACCESS_MODE < propName` +UR_APIEXPORT ur_result_t UR_APICALL +urVirtualMemGetInfo( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range. + ur_virtual_mem_info_t propName, ///< [in] type of the info to query. + size_t propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void *pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t *pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Physical memory creation properties. +typedef uint32_t ur_physical_mem_flags_t; +typedef enum ur_physical_mem_flag_t { + UR_PHYSICAL_MEM_FLAG_TBD = UR_BIT(0), ///< reserved for future use. + /// @cond + UR_PHYSICAL_MEM_FLAG_FORCE_UINT32 = 0x7fffffff + /// @endcond + +} ur_physical_mem_flag_t; +/// @brief Bit Mask for validating ur_physical_mem_flags_t +#define UR_PHYSICAL_MEM_FLAGS_MASK 0xfffffffe + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Physical memory creation properties. +typedef struct ur_physical_mem_properties_t { + ur_structure_type_t stype; ///< [in] type of this structure, must be + ///< ::UR_STRUCTURE_TYPE_PHYSICAL_MEM_PROPERTIES + void *pNext; ///< [in,out][optional] pointer to extension-specific structure + ur_physical_mem_flags_t flags; ///< [in] physical memory creation flags + +} ur_physical_mem_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Create a physical memory handle that virtual memory can be mapped to. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phPhysicalMem` +UR_APIEXPORT ur_result_t UR_APICALL +urPhysicalMemCreate( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in] handle of the device object. + size_t size, ///< [in] size in bytes of phyisical memory to allocate, must be a multiple + ///< of ::UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + const ur_physical_mem_properties_t *pProperties, ///< [in][optional] pointer to physical memory creation properties. + ur_physical_mem_handle_t *phPhysicalMem ///< [out] pointer to handle of physical memory object created. +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Retain a physical memory handle, increment its reference count. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hPhysicalMem` +UR_APIEXPORT ur_result_t UR_APICALL +urPhysicalMemRetain( + ur_physical_mem_handle_t hPhysicalMem ///< [in] handle of the physical memory object to retain. +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Release a physical memory handle, decrement its reference count. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hPhysicalMem` +UR_APIEXPORT ur_result_t UR_APICALL +urPhysicalMemRelease( + ur_physical_mem_handle_t hPhysicalMem ///< [in] handle of the physical memory object to release. +); + #if !defined(__GNUC__) #pragma endregion #endif @@ -4872,6 +5153,16 @@ typedef enum ur_function_t { UR_FUNCTION_PLATFORM_GET_LAST_ERROR = 150, ///< Enumerator for ::urPlatformGetLastError UR_FUNCTION_ENQUEUE_USM_FILL_2D = 151, ///< Enumerator for ::urEnqueueUSMFill2D UR_FUNCTION_ENQUEUE_USM_MEMCPY_2D = 152, ///< Enumerator for ::urEnqueueUSMMemcpy2D + UR_FUNCTION_VIRTUAL_MEM_GRANULARITY_GET_INFO = 153, ///< Enumerator for ::urVirtualMemGranularityGetInfo + UR_FUNCTION_VIRTUAL_MEM_RESERVE = 154, ///< Enumerator for ::urVirtualMemReserve + UR_FUNCTION_VIRTUAL_MEM_FREE = 155, ///< Enumerator for ::urVirtualMemFree + UR_FUNCTION_VIRTUAL_MEM_MAP = 156, ///< Enumerator for ::urVirtualMemMap + UR_FUNCTION_VIRTUAL_MEM_UNMAP = 157, ///< Enumerator for ::urVirtualMemUnmap + UR_FUNCTION_VIRTUAL_MEM_SET_ACCESS = 158, ///< Enumerator for ::urVirtualMemSetAccess + UR_FUNCTION_VIRTUAL_MEM_GET_INFO = 159, ///< Enumerator for ::urVirtualMemGetInfo + 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 /// @cond UR_FUNCTION_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -7627,6 +7918,34 @@ typedef struct ur_mem_image_get_info_params_t { size_t **ppPropSizeRet; } ur_mem_image_get_info_params_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urPhysicalMemCreate +/// @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_physical_mem_create_params_t { + ur_context_handle_t *phContext; + ur_device_handle_t *phDevice; + size_t *psize; + const ur_physical_mem_properties_t **ppProperties; + ur_physical_mem_handle_t **pphPhysicalMem; +} ur_physical_mem_create_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urPhysicalMemRetain +/// @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_physical_mem_retain_params_t { + ur_physical_mem_handle_t *phPhysicalMem; +} ur_physical_mem_retain_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urPhysicalMemRelease +/// @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_physical_mem_release_params_t { + ur_physical_mem_handle_t *phPhysicalMem; +} ur_physical_mem_release_params_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urEnqueueKernelLaunch /// @details Each entry is a pointer to the parameter passed to the function; @@ -8537,6 +8856,88 @@ typedef struct ur_tear_down_params_t { void **ppParams; } ur_tear_down_params_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urVirtualMemGranularityGetInfo +/// @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_virtual_mem_granularity_get_info_params_t { + ur_context_handle_t *phContext; + ur_device_handle_t *phDevice; + ur_virtual_mem_granularity_info_t *ppropName; + size_t *ppropSize; + void **ppPropValue; + size_t **ppPropSizeRet; +} ur_virtual_mem_granularity_get_info_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urVirtualMemReserve +/// @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_virtual_mem_reserve_params_t { + ur_context_handle_t *phContext; + const void **ppStart; + size_t *psize; + void ***pppStart; +} ur_virtual_mem_reserve_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urVirtualMemFree +/// @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_virtual_mem_free_params_t { + ur_context_handle_t *phContext; + const void **ppStart; + size_t *psize; +} ur_virtual_mem_free_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urVirtualMemMap +/// @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_virtual_mem_map_params_t { + ur_context_handle_t *phContext; + const void **ppStart; + size_t *psize; + ur_physical_mem_handle_t *phPhysicalMem; + size_t *poffset; + ur_virtual_mem_access_flags_t *pflags; +} ur_virtual_mem_map_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urVirtualMemUnmap +/// @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_virtual_mem_unmap_params_t { + ur_context_handle_t *phContext; + const void **ppStart; + size_t *psize; +} ur_virtual_mem_unmap_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urVirtualMemSetAccess +/// @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_virtual_mem_set_access_params_t { + ur_context_handle_t *phContext; + const void **ppStart; + size_t *psize; + ur_virtual_mem_access_flags_t *pflags; +} ur_virtual_mem_set_access_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urVirtualMemGetInfo +/// @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_virtual_mem_get_info_params_t { + ur_context_handle_t *phContext; + const void **ppStart; + size_t *psize; + ur_virtual_mem_info_t *ppropName; + size_t *ppropSize; + void **ppPropValue; + size_t **ppPropSizeRet; +} ur_virtual_mem_get_info_params_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urDeviceGet /// @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 a2d92bdeef..fc4f6cad26 100644 --- a/include/ur_ddi.h +++ b/include/ur_ddi.h @@ -756,6 +756,54 @@ typedef ur_result_t(UR_APICALL *ur_pfnGetMemProcAddrTable_t)( ur_api_version_t, ur_mem_dditable_t *); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urPhysicalMemCreate +typedef ur_result_t(UR_APICALL *ur_pfnPhysicalMemCreate_t)( + ur_context_handle_t, + ur_device_handle_t, + size_t, + const ur_physical_mem_properties_t *, + ur_physical_mem_handle_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urPhysicalMemRetain +typedef ur_result_t(UR_APICALL *ur_pfnPhysicalMemRetain_t)( + ur_physical_mem_handle_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urPhysicalMemRelease +typedef ur_result_t(UR_APICALL *ur_pfnPhysicalMemRelease_t)( + ur_physical_mem_handle_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Table of PhysicalMem functions pointers +typedef struct ur_physical_mem_dditable_t { + ur_pfnPhysicalMemCreate_t pfnCreate; + ur_pfnPhysicalMemRetain_t pfnRetain; + ur_pfnPhysicalMemRelease_t pfnRelease; +} ur_physical_mem_dditable_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's PhysicalMem 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 +urGetPhysicalMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_physical_mem_dditable_t *pDdiTable ///< [in,out] pointer to table of DDI function pointers +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urGetPhysicalMemProcAddrTable +typedef ur_result_t(UR_APICALL *ur_pfnGetPhysicalMemProcAddrTable_t)( + ur_api_version_t, + ur_physical_mem_dditable_t *); + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urEnqueueKernelLaunch typedef ur_result_t(UR_APICALL *ur_pfnEnqueueKernelLaunch_t)( @@ -1706,6 +1754,100 @@ typedef ur_result_t(UR_APICALL *ur_pfnGetGlobalProcAddrTable_t)( ur_api_version_t, ur_global_dditable_t *); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urVirtualMemGranularityGetInfo +typedef ur_result_t(UR_APICALL *ur_pfnVirtualMemGranularityGetInfo_t)( + ur_context_handle_t, + ur_device_handle_t, + ur_virtual_mem_granularity_info_t, + size_t, + void *, + size_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urVirtualMemReserve +typedef ur_result_t(UR_APICALL *ur_pfnVirtualMemReserve_t)( + ur_context_handle_t, + const void *, + size_t, + void **); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urVirtualMemFree +typedef ur_result_t(UR_APICALL *ur_pfnVirtualMemFree_t)( + ur_context_handle_t, + const void *, + size_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urVirtualMemMap +typedef ur_result_t(UR_APICALL *ur_pfnVirtualMemMap_t)( + ur_context_handle_t, + const void *, + size_t, + ur_physical_mem_handle_t, + size_t, + ur_virtual_mem_access_flags_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urVirtualMemUnmap +typedef ur_result_t(UR_APICALL *ur_pfnVirtualMemUnmap_t)( + ur_context_handle_t, + const void *, + size_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urVirtualMemSetAccess +typedef ur_result_t(UR_APICALL *ur_pfnVirtualMemSetAccess_t)( + ur_context_handle_t, + const void *, + size_t, + ur_virtual_mem_access_flags_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urVirtualMemGetInfo +typedef ur_result_t(UR_APICALL *ur_pfnVirtualMemGetInfo_t)( + ur_context_handle_t, + const void *, + size_t, + ur_virtual_mem_info_t, + size_t, + void *, + size_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Table of VirtualMem functions pointers +typedef struct ur_virtual_mem_dditable_t { + ur_pfnVirtualMemGranularityGetInfo_t pfnGranularityGetInfo; + ur_pfnVirtualMemReserve_t pfnReserve; + ur_pfnVirtualMemFree_t pfnFree; + ur_pfnVirtualMemMap_t pfnMap; + ur_pfnVirtualMemUnmap_t pfnUnmap; + ur_pfnVirtualMemSetAccess_t pfnSetAccess; + ur_pfnVirtualMemGetInfo_t pfnGetInfo; +} ur_virtual_mem_dditable_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's VirtualMem 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 +urGetVirtualMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_virtual_mem_dditable_t *pDdiTable ///< [in,out] pointer to table of DDI function pointers +); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urGetVirtualMemProcAddrTable +typedef ur_result_t(UR_APICALL *ur_pfnGetVirtualMemProcAddrTable_t)( + ur_api_version_t, + ur_virtual_mem_dditable_t *); + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urDeviceGet typedef ur_result_t(UR_APICALL *ur_pfnDeviceGet_t)( @@ -1817,6 +1959,7 @@ typedef struct ur_dditable_t { ur_kernel_dditable_t Kernel; ur_sampler_dditable_t Sampler; ur_mem_dditable_t Mem; + ur_physical_mem_dditable_t PhysicalMem; ur_enqueue_dditable_t Enqueue; ur_queue_dditable_t Queue; ur_bindless_images_exp_dditable_t BindlessImagesExp; @@ -1824,6 +1967,7 @@ typedef struct ur_dditable_t { ur_usm_exp_dditable_t USMExp; ur_command_buffer_exp_dditable_t CommandBufferExp; ur_global_dditable_t Global; + ur_virtual_mem_dditable_t VirtualMem; ur_device_dditable_t Device; } ur_dditable_t; diff --git a/scripts/core/common.yml b/scripts/core/common.yml index 9a066d8d7a..191656d475 100644 --- a/scripts/core/common.yml +++ b/scripts/core/common.yml @@ -109,6 +109,11 @@ desc: "Handle of memory object which can either be buffer or image" class: $xMem name: "$x_mem_handle_t" --- #-------------------------------------------------------------------------- +type: handle +desc: "Handle of physical memory object" +class: $xPhysicalMem +name: "$x_physical_mem_handle_t" +--- #-------------------------------------------------------------------------- type: macro desc: "Generic macro for enumerator bit masks" name: "$X_BIT( _i )" @@ -333,6 +338,8 @@ etors: desc: $x_exp_sampler_mip_properties_t - name: KERNEL_ARG_MEM_OBJ_PROPERTIES desc: $x_kernel_arg_mem_obj_properties_t + - name: PHYSICAL_MEM_PROPERTIES + desc: $x_physical_mem_properties_t --- #-------------------------------------------------------------------------- type: struct desc: "Base for all properties types" diff --git a/scripts/core/registry.yml b/scripts/core/registry.yml index 791c73f0cc..873dc8dc07 100644 --- a/scripts/core/registry.yml +++ b/scripts/core/registry.yml @@ -445,3 +445,33 @@ etors: - name: ENQUEUE_USM_MEMCPY_2D desc: Enumerator for $xEnqueueUSMMemcpy2D value: '152' +- name: VIRTUAL_MEM_GRANULARITY_GET_INFO + desc: Enumerator for $xVirtualMemGranularityGetInfo + value: '153' +- name: VIRTUAL_MEM_RESERVE + desc: Enumerator for $xVirtualMemReserve + value: '154' +- name: VIRTUAL_MEM_FREE + desc: Enumerator for $xVirtualMemFree + value: '155' +- name: VIRTUAL_MEM_MAP + desc: Enumerator for $xVirtualMemMap + value: '156' +- name: VIRTUAL_MEM_UNMAP + desc: Enumerator for $xVirtualMemUnmap + value: '157' +- name: VIRTUAL_MEM_SET_ACCESS + desc: Enumerator for $xVirtualMemSetAccess + value: '158' +- name: VIRTUAL_MEM_GET_INFO + desc: Enumerator for $xVirtualMemGetInfo + value: '159' +- name: PHYSICAL_MEM_CREATE + desc: Enumerator for $xPhysicalMemCreate + value: '160' +- name: PHYSICAL_MEM_RETAIN + desc: Enumerator for $xPhysicalMemRetain + value: '161' +- name: PHYSICAL_MEM_RELEASE + desc: Enumerator for $xPhysicalMemRelease + value: '162' diff --git a/scripts/core/virtual_memory.yml b/scripts/core/virtual_memory.yml new file mode 100644 index 0000000000..f10380ce62 --- /dev/null +++ b/scripts/core/virtual_memory.yml @@ -0,0 +1,287 @@ +# +# Copyright (C) 2022 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 APIs" +ordinal: "4" + +--- #-------------------------------------------------------------------------- +type: enum +desc: "Virtual memory granularity info" +class: $xVirtualMem +name: $x_virtual_mem_granularity_info_t +typed_etors: True +etors: + - name: MINIMUM + value: "0x30100" + desc: "[size_t] size in bytes of the minimum virtual memory granularity." + - name: RECOMMENDED + value: "0x30101" + desc: "[size_t] size in bytes of the recommended virtual memory granularity." + +--- #-------------------------------------------------------------------------- +type: function +desc: "Get information about the minimum and recommended granularity of physical and virtual memory." +class: $xVirtualMem +name: GranularityGetInfo +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object." + - type: $x_device_handle_t + name: hDevice + desc: > + [in][optional] is the device to get the granularity from, if the + device is null then the granularity is suitable for all devices in + context. + - type: $x_virtual_mem_granularity_info_t + name: propName + desc: "[in] type of the info to query." + - type: size_t + name: propSize + desc: "[in] size in bytes of the memory pointed to by pPropValue." + - type: void* + name: pPropValue + desc: > + [out][optional][typename(propName, propSize)] array of bytes holding + the info. If propSize is less than the real number of bytes needed to + return the info then the $X_RESULT_ERROR_INVALID_SIZE error is + returned and pPropValue is not used. + - type: size_t* + name: pPropSizeRet + desc: > + [out][optional] pointer to the actual size in bytes of the queried + propName." + +--- #-------------------------------------------------------------------------- +type: function +desc: "Reserve a virtual memory range." +class: $xVirtualMem +name: Reserve +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object." + - type: const void* + name: pStart + desc: > + [in][optional] pointer to the start of the virtual memory region to + reserve, specifying a null value causes the implementation to select + a start address. + - type: size_t + name: size + desc: "[in] size in bytes of the virtual address range to reserve." + - type: void** + name: ppStart + desc: > + [out] pointer to the returned address at the start of reserved + virtual memory range. + +--- #-------------------------------------------------------------------------- +type: function +desc: "Free a virtual memory range." +class: $xVirtualMem +name: Free +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object." + - type: const void* + name: pStart + desc: "[in] pointer to the start of the virtual memory range to free." + - type: size_t + name: size + desc: "[in] size in bytes of the virtual memory range to free." + +--- #-------------------------------------------------------------------------- +type: enum +desc: "Virtual memory access mode flags." +class: $xVirtualMem +name: $x_virtual_mem_access_flags_t +etors: + - name: READ_WRITE + value: $X_BIT(0) + desc: "Virtual memory both read and write accessible" + - name: READ_ONLY + value: $X_BIT(1) + desc: "" + +--- #-------------------------------------------------------------------------- +type: function +desc: "Map a virtual memory range to a physical memory handle." +class: $xVirtualMem +name: Map +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle to the context object." + - type: const void* + name: pStart + desc: "[in] pointer to the start of the virtual memory range." + - type: size_t + name: size + desc: "[in] size in bytes of the virtual memory range to map." + - type: $x_physical_mem_handle_t + name: hPhysicalMem + desc: "[in] handle of the physical memory to map pStart to." + - type: size_t + name: offset + desc: "[in] offset in bytes into the physical memory to map pStart to." + - type: $x_virtual_mem_access_flags_t + name: flags + desc: "[in] access flags for the physical memory mapping." + +--- #-------------------------------------------------------------------------- +type: function +desc: "Unmap a virtual memory range previously mapped in a context." +details: + - After a call to this function, the virtual memory range is left in a + state ready to be remapped. +class: $xVirtualMem +name: Unmap +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle to the context object." + - type: const void* + name: pStart + desc: "[in] pointer to the start of the mapped virtual memory range" + - type: size_t + name: size + desc: "[in] size in bytes of the virtual memory range." + +--- #-------------------------------------------------------------------------- +type: function +desc: "Set the access mode of a mapped virtual memory range." +class: $xVirtualMem +name: SetAccess +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle to the context object." + - type: const void* + name: pStart + desc: "[in] pointer to the start of the virtual memory range." + - type: size_t + name: size + desc: "[in] size in bytes of the virutal memory range." + - type: $x_virtual_mem_access_flags_t + name: flags + desc: "[in] access flags to set for the mapped virtual memory range." + +--- #-------------------------------------------------------------------------- +type: enum +desc: "Virtual memory range info queries." +class: $xVirtualMem +name: $x_virtual_mem_info_t +typed_etors: True +etors: + - name: ACCESS_MODE + desc: > + [$x_virtual_mem_access_flags_t] access flags of a mapped virtual + memory range. + +--- #-------------------------------------------------------------------------- +type: function +desc: "Get information about a mapped virtual memory range." +class: $xVirtualMem +name: GetInfo +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle to the context object." + - type: const void* + name: pStart + desc: "[in] pointer to the start of the virtual memory range." + - type: size_t + name: size + desc: "[in] size in bytes of the virtual memory range." + - type: $x_virtual_mem_info_t + name: propName + desc: "[in] type of the info to query." + - type: size_t + name: propSize + desc: "[in] size in bytes of the memory pointed to by pPropValue." + - type: void* + name: pPropValue + desc: > + [out][optional][typename(propName, propSize)] array of bytes holding + the info. If propSize is less than the real number of bytes needed to + return the info then the $X_RESULT_ERROR_INVALID_SIZE error is + returned and pPropValue is not used. + - type: size_t* + name: pPropSizeRet + desc: > + [out][optional] pointer to the actual size in bytes of the queried + propName." + +--- #-------------------------------------------------------------------------- +type: enum +desc: "Physical memory creation properties." +class: $xPhysicalMem +name: $x_physical_mem_flags_t +etors: + - name: TBD + desc: "reserved for future use." + +--- #-------------------------------------------------------------------------- +type: struct +desc: "Physical memory creation properties." +class: $xPhysicalMem +name: $x_physical_mem_properties_t +base: $x_base_properties_t +members: + - type: $x_physical_mem_flags_t + name: flags + desc: "[in] physical memory creation flags" + +--- #-------------------------------------------------------------------------- +type: function +desc: "Create a physical memory handle that virtual memory can be mapped to." +class: $xPhysicalMem +name: Create +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." + - type: size_t + name: size + desc: > + [in] size in bytes of phyisical memory to allocate, must be a + multiple of $X_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + - type: const $x_physical_mem_properties_t* + name: pProperties + desc: "[in][optional] pointer to physical memory creation properties." + - type: $x_physical_mem_handle_t* + name: phPhysicalMem + desc: "[out] pointer to handle of physical memory object created." + +--- #-------------------------------------------------------------------------- +type: function +desc: "Retain a physical memory handle, increment its reference count." +class: $xPhysicalMem +name: Retain +params: + - type: $x_physical_mem_handle_t + name: hPhysicalMem + desc: "[in] handle of the physical memory object to retain." + +--- #-------------------------------------------------------------------------- +type: function +desc: "Release a physical memory handle, decrement its reference count." +class: $xPhysicalMem +name: Release +params: + - type: $x_physical_mem_handle_t + name: hPhysicalMem + desc: "[in] handle of the physical memory object to release." diff --git a/source/adapters/null/ur_nullddi.cpp b/source/adapters/null/ur_nullddi.cpp index 328720aa46..b0a07d62cc 100644 --- a/source/adapters/null/ur_nullddi.cpp +++ b/source/adapters/null/ur_nullddi.cpp @@ -1326,6 +1326,277 @@ __urdlllocal ur_result_t UR_APICALL urUSMPoolGetInfo( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGranularityGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGranularityGetInfo( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t + hDevice, ///< [in][optional] is the device to get the granularity from, if the + ///< device is null then the granularity is suitable for all devices in context. + ur_virtual_mem_granularity_info_t + propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." + ) 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 pfnGranularityGetInfo = + d_context.urDdiTable.VirtualMem.pfnGranularityGetInfo; + if (nullptr != pfnGranularityGetInfo) { + result = pfnGranularityGetInfo(hContext, hDevice, propName, propSize, + pPropValue, pPropSizeRet); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemReserve +__urdlllocal ur_result_t UR_APICALL urVirtualMemReserve( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in][optional] pointer to the start of the virtual memory region to + ///< reserve, specifying a null value causes the implementation to select a + ///< start address. + size_t + size, ///< [in] size in bytes of the virtual address range to reserve. + void ** + ppStart ///< [out] pointer to the returned address at the start of reserved virtual + ///< memory range. + ) 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 pfnReserve = d_context.urDdiTable.VirtualMem.pfnReserve; + if (nullptr != pfnReserve) { + result = pfnReserve(hContext, pStart, size, ppStart); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemFree +__urdlllocal ur_result_t UR_APICALL urVirtualMemFree( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in] pointer to the start of the virtual memory range to free. + size_t size ///< [in] size in bytes of the virtual memory range to free. + ) 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 pfnFree = d_context.urDdiTable.VirtualMem.pfnFree; + if (nullptr != pfnFree) { + result = pfnFree(hContext, pStart, size); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemMap +__urdlllocal ur_result_t UR_APICALL urVirtualMemMap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range to map. + ur_physical_mem_handle_t + hPhysicalMem, ///< [in] handle of the physical memory to map pStart to. + size_t + offset, ///< [in] offset in bytes into the physical memory to map pStart to. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags for the physical memory mapping. + ) 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 pfnMap = d_context.urDdiTable.VirtualMem.pfnMap; + if (nullptr != pfnMap) { + result = pfnMap(hContext, pStart, size, hPhysicalMem, offset, flags); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemUnmap +__urdlllocal ur_result_t UR_APICALL urVirtualMemUnmap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void * + pStart, ///< [in] pointer to the start of the mapped virtual memory range + size_t size ///< [in] size in bytes of the virtual memory range. + ) 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 pfnUnmap = d_context.urDdiTable.VirtualMem.pfnUnmap; + if (nullptr != pfnUnmap) { + result = pfnUnmap(hContext, pStart, size); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemSetAccess +__urdlllocal ur_result_t UR_APICALL urVirtualMemSetAccess( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virutal memory range. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags to set for the mapped virtual memory range. + ) 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 pfnSetAccess = d_context.urDdiTable.VirtualMem.pfnSetAccess; + if (nullptr != pfnSetAccess) { + result = pfnSetAccess(hContext, pStart, size, flags); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGetInfo( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range. + ur_virtual_mem_info_t propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." + ) 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 pfnGetInfo = d_context.urDdiTable.VirtualMem.pfnGetInfo; + if (nullptr != pfnGetInfo) { + result = pfnGetInfo(hContext, pStart, size, propName, propSize, + pPropValue, pPropSizeRet); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemCreate +__urdlllocal ur_result_t UR_APICALL urPhysicalMemCreate( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in] handle of the device object. + size_t + size, ///< [in] size in bytes of phyisical memory to allocate, must be a multiple + ///< of ::UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + const ur_physical_mem_properties_t * + pProperties, ///< [in][optional] pointer to physical memory creation properties. + ur_physical_mem_handle_t * + phPhysicalMem ///< [out] pointer to handle of physical memory object created. + ) 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 pfnCreate = d_context.urDdiTable.PhysicalMem.pfnCreate; + if (nullptr != pfnCreate) { + result = pfnCreate(hContext, hDevice, size, pProperties, phPhysicalMem); + } else { + // generic implementation + *phPhysicalMem = + reinterpret_cast(d_context.get()); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRetain +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRetain( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to retain. + ) 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 pfnRetain = d_context.urDdiTable.PhysicalMem.pfnRetain; + if (nullptr != pfnRetain) { + result = pfnRetain(hPhysicalMem); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRelease +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRelease( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to release. + ) 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 pfnRelease = d_context.urDdiTable.PhysicalMem.pfnRelease; + if (nullptr != pfnRelease) { + result = pfnRelease(hPhysicalMem); + } else { + // generic implementation + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urProgramCreateWithIL __urdlllocal ur_result_t UR_APICALL urProgramCreateWithIL( @@ -4739,6 +5010,40 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetMemProcAddrTable( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's PhysicalMem 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 urGetPhysicalMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_physical_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers + ) 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->pfnCreate = driver::urPhysicalMemCreate; + + pDdiTable->pfnRetain = driver::urPhysicalMemRetain; + + pDdiTable->pfnRelease = driver::urPhysicalMemRelease; + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Platform table /// with current process' addresses @@ -5000,6 +5305,48 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetUSMExpProcAddrTable( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's VirtualMem 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 urGetVirtualMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_virtual_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers + ) 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->pfnGranularityGetInfo = driver::urVirtualMemGranularityGetInfo; + + pDdiTable->pfnReserve = driver::urVirtualMemReserve; + + pDdiTable->pfnFree = driver::urVirtualMemFree; + + pDdiTable->pfnMap = driver::urVirtualMemMap; + + pDdiTable->pfnUnmap = driver::urVirtualMemUnmap; + + pDdiTable->pfnSetAccess = driver::urVirtualMemSetAccess; + + pDdiTable->pfnGetInfo = driver::urVirtualMemGetInfo; + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Device table /// with current process' addresses diff --git a/source/common/ur_params.hpp b/source/common/ur_params.hpp index db68b62a3a..7a9bcf8a3a 100644 --- a/source/common/ur_params.hpp +++ b/source/common/ur_params.hpp @@ -108,6 +108,23 @@ template <> inline void serializeTagged(std::ostream &os, const void *ptr, ur_usm_pool_info_t value, size_t size); +template <> +inline void serializeTagged(std::ostream &os, const void *ptr, + ur_virtual_mem_granularity_info_t value, + size_t size); + +template <> +inline void serializeFlag(std::ostream &os, + uint32_t flag); + +template <> +inline void serializeTagged(std::ostream &os, const void *ptr, + ur_virtual_mem_info_t value, size_t size); + +template <> +inline void serializeFlag(std::ostream &os, + uint32_t flag); + template <> inline void serializeTagged(std::ostream &os, const void *ptr, ur_program_info_t value, size_t size); @@ -279,6 +296,16 @@ inline std::ostream &operator<<(std::ostream &os, const struct ur_usm_pool_limits_desc_t params); inline std::ostream &operator<<(std::ostream &os, enum ur_usm_pool_info_t value); +inline std::ostream &operator<<(std::ostream &os, + enum ur_virtual_mem_granularity_info_t value); +inline std::ostream &operator<<(std::ostream &os, + enum ur_virtual_mem_access_flag_t value); +inline std::ostream &operator<<(std::ostream &os, + enum ur_virtual_mem_info_t value); +inline std::ostream &operator<<(std::ostream &os, + enum ur_physical_mem_flag_t value); +inline std::ostream & +operator<<(std::ostream &os, const struct ur_physical_mem_properties_t params); inline std::ostream &operator<<(std::ostream &os, enum ur_program_metadata_type_t value); inline std::ostream &operator<<(std::ostream &os, @@ -764,6 +791,10 @@ inline std::ostream &operator<<(std::ostream &os, case UR_STRUCTURE_TYPE_KERNEL_ARG_MEM_OBJ_PROPERTIES: os << "UR_STRUCTURE_TYPE_KERNEL_ARG_MEM_OBJ_PROPERTIES"; break; + + case UR_STRUCTURE_TYPE_PHYSICAL_MEM_PROPERTIES: + os << "UR_STRUCTURE_TYPE_PHYSICAL_MEM_PROPERTIES"; + break; default: os << "unknown enumerator"; break; @@ -951,6 +982,12 @@ inline void serializeStruct(std::ostream &os, const void *ptr) { (const ur_kernel_arg_mem_obj_properties_t *)ptr; ur_params::serializePtr(os, pstruct); } break; + + case UR_STRUCTURE_TYPE_PHYSICAL_MEM_PROPERTIES: { + const ur_physical_mem_properties_t *pstruct = + (const ur_physical_mem_properties_t *)ptr; + ur_params::serializePtr(os, pstruct); + } break; default: os << "unknown enumerator"; break; @@ -6334,6 +6371,233 @@ inline void serializeTagged(std::ostream &os, const void *ptr, } } } // namespace ur_params +inline std::ostream &operator<<(std::ostream &os, + enum ur_virtual_mem_granularity_info_t value) { + switch (value) { + + case UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM: + os << "UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM"; + break; + + case UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED: + os << "UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED"; + break; + default: + os << "unknown enumerator"; + break; + } + return os; +} +namespace ur_params { +template <> +inline void serializeTagged(std::ostream &os, const void *ptr, + ur_virtual_mem_granularity_info_t value, + size_t size) { + if (ptr == NULL) { + serializePtr(os, ptr); + return; + } + + switch (value) { + + case UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM: { + const size_t *tptr = (const size_t *)ptr; + if (sizeof(size_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(size_t) << ")"; + return; + } + os << (void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; + + case UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED: { + const size_t *tptr = (const size_t *)ptr; + if (sizeof(size_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(size_t) << ")"; + return; + } + os << (void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; + default: + os << "unknown enumerator"; + break; + } +} +} // namespace ur_params +inline std::ostream &operator<<(std::ostream &os, + enum ur_virtual_mem_access_flag_t value) { + switch (value) { + + case UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE: + os << "UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE"; + break; + + case UR_VIRTUAL_MEM_ACCESS_FLAG_READ_ONLY: + os << "UR_VIRTUAL_MEM_ACCESS_FLAG_READ_ONLY"; + break; + default: + os << "unknown enumerator"; + break; + } + return os; +} +namespace ur_params { + +template <> +inline void serializeFlag(std::ostream &os, + uint32_t flag) { + uint32_t val = flag; + bool first = true; + + if ((val & UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE) == + (uint32_t)UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE) { + val ^= (uint32_t)UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE; + if (!first) { + os << " | "; + } else { + first = false; + } + os << UR_VIRTUAL_MEM_ACCESS_FLAG_READ_WRITE; + } + + if ((val & UR_VIRTUAL_MEM_ACCESS_FLAG_READ_ONLY) == + (uint32_t)UR_VIRTUAL_MEM_ACCESS_FLAG_READ_ONLY) { + val ^= (uint32_t)UR_VIRTUAL_MEM_ACCESS_FLAG_READ_ONLY; + if (!first) { + os << " | "; + } else { + first = false; + } + os << UR_VIRTUAL_MEM_ACCESS_FLAG_READ_ONLY; + } + if (val != 0) { + std::bitset<32> bits(val); + if (!first) { + os << " | "; + } + os << "unknown bit flags " << bits; + } else if (first) { + os << "0"; + } +} +} // namespace ur_params +inline std::ostream &operator<<(std::ostream &os, + enum ur_virtual_mem_info_t value) { + switch (value) { + + case UR_VIRTUAL_MEM_INFO_ACCESS_MODE: + os << "UR_VIRTUAL_MEM_INFO_ACCESS_MODE"; + break; + default: + os << "unknown enumerator"; + break; + } + return os; +} +namespace ur_params { +template <> +inline void serializeTagged(std::ostream &os, const void *ptr, + ur_virtual_mem_info_t value, size_t size) { + if (ptr == NULL) { + serializePtr(os, ptr); + return; + } + + switch (value) { + + case UR_VIRTUAL_MEM_INFO_ACCESS_MODE: { + const ur_virtual_mem_access_flags_t *tptr = + (const ur_virtual_mem_access_flags_t *)ptr; + if (sizeof(ur_virtual_mem_access_flags_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(ur_virtual_mem_access_flags_t) + << ")"; + return; + } + os << (void *)(tptr) << " ("; + + ur_params::serializeFlag(os, *tptr); + + os << ")"; + } break; + default: + os << "unknown enumerator"; + break; + } +} +} // namespace ur_params +inline std::ostream &operator<<(std::ostream &os, + enum ur_physical_mem_flag_t value) { + switch (value) { + + case UR_PHYSICAL_MEM_FLAG_TBD: + os << "UR_PHYSICAL_MEM_FLAG_TBD"; + break; + default: + os << "unknown enumerator"; + break; + } + return os; +} +namespace ur_params { + +template <> +inline void serializeFlag(std::ostream &os, + uint32_t flag) { + uint32_t val = flag; + bool first = true; + + if ((val & UR_PHYSICAL_MEM_FLAG_TBD) == + (uint32_t)UR_PHYSICAL_MEM_FLAG_TBD) { + val ^= (uint32_t)UR_PHYSICAL_MEM_FLAG_TBD; + if (!first) { + os << " | "; + } else { + first = false; + } + os << UR_PHYSICAL_MEM_FLAG_TBD; + } + if (val != 0) { + std::bitset<32> bits(val); + if (!first) { + os << " | "; + } + os << "unknown bit flags " << bits; + } else if (first) { + os << "0"; + } +} +} // namespace ur_params +inline std::ostream & +operator<<(std::ostream &os, const struct ur_physical_mem_properties_t params) { + os << "(struct ur_physical_mem_properties_t){"; + + os << ".stype = "; + + os << (params.stype); + + os << ", "; + os << ".pNext = "; + + ur_params::serializeStruct(os, (params.pNext)); + + os << ", "; + os << ".flags = "; + + ur_params::serializeFlag(os, (params.flags)); + + os << "}"; + return os; +} inline std::ostream &operator<<(std::ostream &os, enum ur_program_metadata_type_t value) { switch (value) { @@ -8697,6 +8961,46 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_function_t value) { case UR_FUNCTION_ENQUEUE_USM_MEMCPY_2D: os << "UR_FUNCTION_ENQUEUE_USM_MEMCPY_2D"; break; + + case UR_FUNCTION_VIRTUAL_MEM_GRANULARITY_GET_INFO: + os << "UR_FUNCTION_VIRTUAL_MEM_GRANULARITY_GET_INFO"; + break; + + case UR_FUNCTION_VIRTUAL_MEM_RESERVE: + os << "UR_FUNCTION_VIRTUAL_MEM_RESERVE"; + break; + + case UR_FUNCTION_VIRTUAL_MEM_FREE: + os << "UR_FUNCTION_VIRTUAL_MEM_FREE"; + break; + + case UR_FUNCTION_VIRTUAL_MEM_MAP: + os << "UR_FUNCTION_VIRTUAL_MEM_MAP"; + break; + + case UR_FUNCTION_VIRTUAL_MEM_UNMAP: + os << "UR_FUNCTION_VIRTUAL_MEM_UNMAP"; + break; + + case UR_FUNCTION_VIRTUAL_MEM_SET_ACCESS: + os << "UR_FUNCTION_VIRTUAL_MEM_SET_ACCESS"; + break; + + case UR_FUNCTION_VIRTUAL_MEM_GET_INFO: + os << "UR_FUNCTION_VIRTUAL_MEM_GET_INFO"; + break; + + case UR_FUNCTION_PHYSICAL_MEM_CREATE: + os << "UR_FUNCTION_PHYSICAL_MEM_CREATE"; + break; + + case UR_FUNCTION_PHYSICAL_MEM_RETAIN: + os << "UR_FUNCTION_PHYSICAL_MEM_RETAIN"; + break; + + case UR_FUNCTION_PHYSICAL_MEM_RELEASE: + os << "UR_FUNCTION_PHYSICAL_MEM_RELEASE"; + break; default: os << "unknown enumerator"; break; @@ -12161,6 +12465,59 @@ operator<<(std::ostream &os, return os; } +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_physical_mem_create_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".hDevice = "; + + ur_params::serializePtr(os, *(params->phDevice)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + os << ", "; + os << ".pProperties = "; + + ur_params::serializePtr(os, *(params->ppProperties)); + + os << ", "; + os << ".phPhysicalMem = "; + + ur_params::serializePtr(os, *(params->pphPhysicalMem)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_physical_mem_retain_params_t *params) { + + os << ".hPhysicalMem = "; + + ur_params::serializePtr(os, *(params->phPhysicalMem)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_physical_mem_release_params_t *params) { + + os << ".hPhysicalMem = "; + + ur_params::serializePtr(os, *(params->phPhysicalMem)); + + return os; +} + inline std::ostream &operator<<(std::ostream &os, const struct ur_platform_get_params_t *params) { @@ -13177,6 +13534,214 @@ operator<<(std::ostream &os, return os; } +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_virtual_mem_granularity_get_info_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".hDevice = "; + + ur_params::serializePtr(os, *(params->phDevice)); + + os << ", "; + os << ".propName = "; + + os << *(params->ppropName); + + os << ", "; + os << ".propSize = "; + + os << *(params->ppropSize); + + os << ", "; + os << ".pPropValue = "; + ur_params::serializeTagged(os, *(params->ppPropValue), *(params->ppropName), + *(params->ppropSize)); + + os << ", "; + os << ".pPropSizeRet = "; + + ur_params::serializePtr(os, *(params->ppPropSizeRet)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_virtual_mem_reserve_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pStart = "; + + ur_params::serializePtr(os, *(params->ppStart)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + os << ", "; + os << ".ppStart = "; + + ur_params::serializePtr(os, *(params->pppStart)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_virtual_mem_free_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pStart = "; + + ur_params::serializePtr(os, *(params->ppStart)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, const struct ur_virtual_mem_map_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pStart = "; + + ur_params::serializePtr(os, *(params->ppStart)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + os << ", "; + os << ".hPhysicalMem = "; + + ur_params::serializePtr(os, *(params->phPhysicalMem)); + + os << ", "; + os << ".offset = "; + + os << *(params->poffset); + + os << ", "; + os << ".flags = "; + + ur_params::serializeFlag(os, + *(params->pflags)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_virtual_mem_unmap_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pStart = "; + + ur_params::serializePtr(os, *(params->ppStart)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_virtual_mem_set_access_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pStart = "; + + ur_params::serializePtr(os, *(params->ppStart)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + os << ", "; + os << ".flags = "; + + ur_params::serializeFlag(os, + *(params->pflags)); + + return os; +} + +inline std::ostream & +operator<<(std::ostream &os, + const struct ur_virtual_mem_get_info_params_t *params) { + + os << ".hContext = "; + + ur_params::serializePtr(os, *(params->phContext)); + + os << ", "; + os << ".pStart = "; + + ur_params::serializePtr(os, *(params->ppStart)); + + os << ", "; + os << ".size = "; + + os << *(params->psize); + + os << ", "; + os << ".propName = "; + + os << *(params->ppropName); + + os << ", "; + os << ".propSize = "; + + os << *(params->ppropSize); + + os << ", "; + os << ".pPropValue = "; + ur_params::serializeTagged(os, *(params->ppPropValue), *(params->ppropName), + *(params->ppropSize)); + + os << ", "; + os << ".pPropSizeRet = "; + + ur_params::serializePtr(os, *(params->ppPropSizeRet)); + + return os; +} + inline std::ostream &operator<<(std::ostream &os, const struct ur_device_get_params_t *params) { @@ -13733,6 +14298,15 @@ inline int serializeFunctionParams(std::ostream &os, uint32_t function, case UR_FUNCTION_MEM_IMAGE_GET_INFO: { os << (const struct ur_mem_image_get_info_params_t *)params; } break; + case UR_FUNCTION_PHYSICAL_MEM_CREATE: { + os << (const struct ur_physical_mem_create_params_t *)params; + } break; + case UR_FUNCTION_PHYSICAL_MEM_RETAIN: { + os << (const struct ur_physical_mem_retain_params_t *)params; + } break; + case UR_FUNCTION_PHYSICAL_MEM_RELEASE: { + os << (const struct ur_physical_mem_release_params_t *)params; + } break; case UR_FUNCTION_PLATFORM_GET: { os << (const struct ur_platform_get_params_t *)params; } break; @@ -13870,6 +14444,28 @@ 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_VIRTUAL_MEM_GRANULARITY_GET_INFO: { + os << (const struct ur_virtual_mem_granularity_get_info_params_t *) + params; + } break; + case UR_FUNCTION_VIRTUAL_MEM_RESERVE: { + os << (const struct ur_virtual_mem_reserve_params_t *)params; + } break; + case UR_FUNCTION_VIRTUAL_MEM_FREE: { + os << (const struct ur_virtual_mem_free_params_t *)params; + } break; + case UR_FUNCTION_VIRTUAL_MEM_MAP: { + os << (const struct ur_virtual_mem_map_params_t *)params; + } break; + case UR_FUNCTION_VIRTUAL_MEM_UNMAP: { + os << (const struct ur_virtual_mem_unmap_params_t *)params; + } break; + case UR_FUNCTION_VIRTUAL_MEM_SET_ACCESS: { + os << (const struct ur_virtual_mem_set_access_params_t *)params; + } break; + case UR_FUNCTION_VIRTUAL_MEM_GET_INFO: { + os << (const struct ur_virtual_mem_get_info_params_t *)params; + } break; case UR_FUNCTION_DEVICE_GET: { os << (const struct ur_device_get_params_t *)params; } break; diff --git a/source/loader/layers/tracing/ur_trcddi.cpp b/source/loader/layers/tracing/ur_trcddi.cpp index 395837e85a..751e56d850 100644 --- a/source/loader/layers/tracing/ur_trcddi.cpp +++ b/source/loader/layers/tracing/ur_trcddi.cpp @@ -1505,6 +1505,316 @@ __urdlllocal ur_result_t UR_APICALL urUSMPoolGetInfo( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGranularityGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGranularityGetInfo( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t + hDevice, ///< [in][optional] is the device to get the granularity from, if the + ///< device is null then the granularity is suitable for all devices in context. + ur_virtual_mem_granularity_info_t + propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + auto pfnGranularityGetInfo = + context.urDdiTable.VirtualMem.pfnGranularityGetInfo; + + if (nullptr == pfnGranularityGetInfo) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_virtual_mem_granularity_get_info_params_t params = { + &hContext, &hDevice, &propName, &propSize, &pPropValue, &pPropSizeRet}; + uint64_t instance = + context.notify_begin(UR_FUNCTION_VIRTUAL_MEM_GRANULARITY_GET_INFO, + "urVirtualMemGranularityGetInfo", ¶ms); + + ur_result_t result = pfnGranularityGetInfo( + hContext, hDevice, propName, propSize, pPropValue, pPropSizeRet); + + context.notify_end(UR_FUNCTION_VIRTUAL_MEM_GRANULARITY_GET_INFO, + "urVirtualMemGranularityGetInfo", ¶ms, &result, + instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemReserve +__urdlllocal ur_result_t UR_APICALL urVirtualMemReserve( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in][optional] pointer to the start of the virtual memory region to + ///< reserve, specifying a null value causes the implementation to select a + ///< start address. + size_t + size, ///< [in] size in bytes of the virtual address range to reserve. + void ** + ppStart ///< [out] pointer to the returned address at the start of reserved virtual + ///< memory range. +) { + auto pfnReserve = context.urDdiTable.VirtualMem.pfnReserve; + + if (nullptr == pfnReserve) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_virtual_mem_reserve_params_t params = {&hContext, &pStart, &size, + &ppStart}; + uint64_t instance = context.notify_begin(UR_FUNCTION_VIRTUAL_MEM_RESERVE, + "urVirtualMemReserve", ¶ms); + + ur_result_t result = pfnReserve(hContext, pStart, size, ppStart); + + context.notify_end(UR_FUNCTION_VIRTUAL_MEM_RESERVE, "urVirtualMemReserve", + ¶ms, &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemFree +__urdlllocal ur_result_t UR_APICALL urVirtualMemFree( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in] pointer to the start of the virtual memory range to free. + size_t size ///< [in] size in bytes of the virtual memory range to free. +) { + auto pfnFree = context.urDdiTable.VirtualMem.pfnFree; + + if (nullptr == pfnFree) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_virtual_mem_free_params_t params = {&hContext, &pStart, &size}; + uint64_t instance = context.notify_begin(UR_FUNCTION_VIRTUAL_MEM_FREE, + "urVirtualMemFree", ¶ms); + + ur_result_t result = pfnFree(hContext, pStart, size); + + context.notify_end(UR_FUNCTION_VIRTUAL_MEM_FREE, "urVirtualMemFree", + ¶ms, &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemMap +__urdlllocal ur_result_t UR_APICALL urVirtualMemMap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range to map. + ur_physical_mem_handle_t + hPhysicalMem, ///< [in] handle of the physical memory to map pStart to. + size_t + offset, ///< [in] offset in bytes into the physical memory to map pStart to. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags for the physical memory mapping. +) { + auto pfnMap = context.urDdiTable.VirtualMem.pfnMap; + + if (nullptr == pfnMap) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_virtual_mem_map_params_t params = {&hContext, &pStart, &size, + &hPhysicalMem, &offset, &flags}; + uint64_t instance = context.notify_begin(UR_FUNCTION_VIRTUAL_MEM_MAP, + "urVirtualMemMap", ¶ms); + + ur_result_t result = + pfnMap(hContext, pStart, size, hPhysicalMem, offset, flags); + + context.notify_end(UR_FUNCTION_VIRTUAL_MEM_MAP, "urVirtualMemMap", ¶ms, + &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemUnmap +__urdlllocal ur_result_t UR_APICALL urVirtualMemUnmap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void * + pStart, ///< [in] pointer to the start of the mapped virtual memory range + size_t size ///< [in] size in bytes of the virtual memory range. +) { + auto pfnUnmap = context.urDdiTable.VirtualMem.pfnUnmap; + + if (nullptr == pfnUnmap) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_virtual_mem_unmap_params_t params = {&hContext, &pStart, &size}; + uint64_t instance = context.notify_begin(UR_FUNCTION_VIRTUAL_MEM_UNMAP, + "urVirtualMemUnmap", ¶ms); + + ur_result_t result = pfnUnmap(hContext, pStart, size); + + context.notify_end(UR_FUNCTION_VIRTUAL_MEM_UNMAP, "urVirtualMemUnmap", + ¶ms, &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemSetAccess +__urdlllocal ur_result_t UR_APICALL urVirtualMemSetAccess( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virutal memory range. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags to set for the mapped virtual memory range. +) { + auto pfnSetAccess = context.urDdiTable.VirtualMem.pfnSetAccess; + + if (nullptr == pfnSetAccess) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_virtual_mem_set_access_params_t params = {&hContext, &pStart, &size, + &flags}; + uint64_t instance = context.notify_begin(UR_FUNCTION_VIRTUAL_MEM_SET_ACCESS, + "urVirtualMemSetAccess", ¶ms); + + ur_result_t result = pfnSetAccess(hContext, pStart, size, flags); + + context.notify_end(UR_FUNCTION_VIRTUAL_MEM_SET_ACCESS, + "urVirtualMemSetAccess", ¶ms, &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGetInfo( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range. + ur_virtual_mem_info_t propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + auto pfnGetInfo = context.urDdiTable.VirtualMem.pfnGetInfo; + + if (nullptr == pfnGetInfo) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_virtual_mem_get_info_params_t params = { + &hContext, &pStart, &size, &propName, + &propSize, &pPropValue, &pPropSizeRet}; + uint64_t instance = context.notify_begin(UR_FUNCTION_VIRTUAL_MEM_GET_INFO, + "urVirtualMemGetInfo", ¶ms); + + ur_result_t result = pfnGetInfo(hContext, pStart, size, propName, propSize, + pPropValue, pPropSizeRet); + + context.notify_end(UR_FUNCTION_VIRTUAL_MEM_GET_INFO, "urVirtualMemGetInfo", + ¶ms, &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemCreate +__urdlllocal ur_result_t UR_APICALL urPhysicalMemCreate( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in] handle of the device object. + size_t + size, ///< [in] size in bytes of phyisical memory to allocate, must be a multiple + ///< of ::UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + const ur_physical_mem_properties_t * + pProperties, ///< [in][optional] pointer to physical memory creation properties. + ur_physical_mem_handle_t * + phPhysicalMem ///< [out] pointer to handle of physical memory object created. +) { + auto pfnCreate = context.urDdiTable.PhysicalMem.pfnCreate; + + if (nullptr == pfnCreate) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_physical_mem_create_params_t params = {&hContext, &hDevice, &size, + &pProperties, &phPhysicalMem}; + uint64_t instance = context.notify_begin(UR_FUNCTION_PHYSICAL_MEM_CREATE, + "urPhysicalMemCreate", ¶ms); + + ur_result_t result = + pfnCreate(hContext, hDevice, size, pProperties, phPhysicalMem); + + context.notify_end(UR_FUNCTION_PHYSICAL_MEM_CREATE, "urPhysicalMemCreate", + ¶ms, &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRetain +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRetain( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to retain. +) { + auto pfnRetain = context.urDdiTable.PhysicalMem.pfnRetain; + + if (nullptr == pfnRetain) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_physical_mem_retain_params_t params = {&hPhysicalMem}; + uint64_t instance = context.notify_begin(UR_FUNCTION_PHYSICAL_MEM_RETAIN, + "urPhysicalMemRetain", ¶ms); + + ur_result_t result = pfnRetain(hPhysicalMem); + + context.notify_end(UR_FUNCTION_PHYSICAL_MEM_RETAIN, "urPhysicalMemRetain", + ¶ms, &result, instance); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRelease +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRelease( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to release. +) { + auto pfnRelease = context.urDdiTable.PhysicalMem.pfnRelease; + + if (nullptr == pfnRelease) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + ur_physical_mem_release_params_t params = {&hPhysicalMem}; + uint64_t instance = context.notify_begin(UR_FUNCTION_PHYSICAL_MEM_RELEASE, + "urPhysicalMemRelease", ¶ms); + + ur_result_t result = pfnRelease(hPhysicalMem); + + context.notify_end(UR_FUNCTION_PHYSICAL_MEM_RELEASE, "urPhysicalMemRelease", + ¶ms, &result, instance); + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urProgramCreateWithIL __urdlllocal ur_result_t UR_APICALL urProgramCreateWithIL( @@ -5495,6 +5805,45 @@ __urdlllocal ur_result_t UR_APICALL urGetMemProcAddrTable( return result; } /////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's PhysicalMem 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 urGetPhysicalMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_physical_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers +) { + auto &dditable = ur_tracing_layer::context.urDdiTable.PhysicalMem; + + if (nullptr == pDdiTable) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (UR_MAJOR_VERSION(ur_tracing_layer::context.version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_tracing_layer::context.version) > + UR_MINOR_VERSION(version)) { + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + } + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnCreate = pDdiTable->pfnCreate; + pDdiTable->pfnCreate = ur_tracing_layer::urPhysicalMemCreate; + + dditable.pfnRetain = pDdiTable->pfnRetain; + pDdiTable->pfnRetain = ur_tracing_layer::urPhysicalMemRetain; + + dditable.pfnRelease = pDdiTable->pfnRelease; + pDdiTable->pfnRelease = ur_tracing_layer::urPhysicalMemRelease; + + return result; +} +/////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Platform table /// with current process' addresses /// @@ -5816,6 +6165,58 @@ __urdlllocal ur_result_t UR_APICALL urGetUSMExpProcAddrTable( return result; } /////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's VirtualMem 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 urGetVirtualMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_virtual_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers +) { + auto &dditable = ur_tracing_layer::context.urDdiTable.VirtualMem; + + if (nullptr == pDdiTable) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (UR_MAJOR_VERSION(ur_tracing_layer::context.version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_tracing_layer::context.version) > + UR_MINOR_VERSION(version)) { + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + } + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnGranularityGetInfo = pDdiTable->pfnGranularityGetInfo; + pDdiTable->pfnGranularityGetInfo = + ur_tracing_layer::urVirtualMemGranularityGetInfo; + + dditable.pfnReserve = pDdiTable->pfnReserve; + pDdiTable->pfnReserve = ur_tracing_layer::urVirtualMemReserve; + + dditable.pfnFree = pDdiTable->pfnFree; + pDdiTable->pfnFree = ur_tracing_layer::urVirtualMemFree; + + dditable.pfnMap = pDdiTable->pfnMap; + pDdiTable->pfnMap = ur_tracing_layer::urVirtualMemMap; + + dditable.pfnUnmap = pDdiTable->pfnUnmap; + pDdiTable->pfnUnmap = ur_tracing_layer::urVirtualMemUnmap; + + dditable.pfnSetAccess = pDdiTable->pfnSetAccess; + pDdiTable->pfnSetAccess = ur_tracing_layer::urVirtualMemSetAccess; + + dditable.pfnGetInfo = pDdiTable->pfnGetInfo; + pDdiTable->pfnGetInfo = ur_tracing_layer::urVirtualMemGetInfo; + + return result; +} +/////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Device table /// with current process' addresses /// @@ -5918,6 +6319,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable) { &dditable->Mem); } + if (UR_RESULT_SUCCESS == result) { + result = ur_tracing_layer::urGetPhysicalMemProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->PhysicalMem); + } + if (UR_RESULT_SUCCESS == result) { result = ur_tracing_layer::urGetPlatformProcAddrTable( UR_API_VERSION_CURRENT, &dditable->Platform); @@ -5948,6 +6354,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable) { UR_API_VERSION_CURRENT, &dditable->USMExp); } + if (UR_RESULT_SUCCESS == result) { + result = ur_tracing_layer::urGetVirtualMemProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->VirtualMem); + } + if (UR_RESULT_SUCCESS == result) { result = ur_tracing_layer::urGetDeviceProcAddrTable( UR_API_VERSION_CURRENT, &dditable->Device); diff --git a/source/loader/layers/validation/ur_valddi.cpp b/source/loader/layers/validation/ur_valddi.cpp index 10450b92bc..4d5b417e01 100644 --- a/source/loader/layers/validation/ur_valddi.cpp +++ b/source/loader/layers/validation/ur_valddi.cpp @@ -1847,6 +1847,361 @@ __urdlllocal ur_result_t UR_APICALL urUSMPoolGetInfo( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGranularityGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGranularityGetInfo( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t + hDevice, ///< [in][optional] is the device to get the granularity from, if the + ///< device is null then the granularity is suitable for all devices in context. + ur_virtual_mem_granularity_info_t + propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + auto pfnGranularityGetInfo = + context.urDdiTable.VirtualMem.pfnGranularityGetInfo; + + if (nullptr == pfnGranularityGetInfo) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED < propName) { + return UR_RESULT_ERROR_INVALID_ENUMERATION; + } + } + + ur_result_t result = pfnGranularityGetInfo( + hContext, hDevice, propName, propSize, pPropValue, pPropSizeRet); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemReserve +__urdlllocal ur_result_t UR_APICALL urVirtualMemReserve( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in][optional] pointer to the start of the virtual memory region to + ///< reserve, specifying a null value causes the implementation to select a + ///< start address. + size_t + size, ///< [in] size in bytes of the virtual address range to reserve. + void ** + ppStart ///< [out] pointer to the returned address at the start of reserved virtual + ///< memory range. +) { + auto pfnReserve = context.urDdiTable.VirtualMem.pfnReserve; + + if (nullptr == pfnReserve) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == ppStart) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + } + + ur_result_t result = pfnReserve(hContext, pStart, size, ppStart); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemFree +__urdlllocal ur_result_t UR_APICALL urVirtualMemFree( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in] pointer to the start of the virtual memory range to free. + size_t size ///< [in] size in bytes of the virtual memory range to free. +) { + auto pfnFree = context.urDdiTable.VirtualMem.pfnFree; + + if (nullptr == pfnFree) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == pStart) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + } + + ur_result_t result = pfnFree(hContext, pStart, size); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemMap +__urdlllocal ur_result_t UR_APICALL urVirtualMemMap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range to map. + ur_physical_mem_handle_t + hPhysicalMem, ///< [in] handle of the physical memory to map pStart to. + size_t + offset, ///< [in] offset in bytes into the physical memory to map pStart to. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags for the physical memory mapping. +) { + auto pfnMap = context.urDdiTable.VirtualMem.pfnMap; + + if (nullptr == pfnMap) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == hPhysicalMem) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == pStart) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags) { + return UR_RESULT_ERROR_INVALID_ENUMERATION; + } + } + + ur_result_t result = + pfnMap(hContext, pStart, size, hPhysicalMem, offset, flags); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemUnmap +__urdlllocal ur_result_t UR_APICALL urVirtualMemUnmap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void * + pStart, ///< [in] pointer to the start of the mapped virtual memory range + size_t size ///< [in] size in bytes of the virtual memory range. +) { + auto pfnUnmap = context.urDdiTable.VirtualMem.pfnUnmap; + + if (nullptr == pfnUnmap) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == pStart) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + } + + ur_result_t result = pfnUnmap(hContext, pStart, size); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemSetAccess +__urdlllocal ur_result_t UR_APICALL urVirtualMemSetAccess( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virutal memory range. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags to set for the mapped virtual memory range. +) { + auto pfnSetAccess = context.urDdiTable.VirtualMem.pfnSetAccess; + + if (nullptr == pfnSetAccess) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == pStart) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags) { + return UR_RESULT_ERROR_INVALID_ENUMERATION; + } + } + + ur_result_t result = pfnSetAccess(hContext, pStart, size, flags); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGetInfo( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range. + ur_virtual_mem_info_t propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + auto pfnGetInfo = context.urDdiTable.VirtualMem.pfnGetInfo; + + if (nullptr == pfnGetInfo) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == pStart) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (UR_VIRTUAL_MEM_INFO_ACCESS_MODE < propName) { + return UR_RESULT_ERROR_INVALID_ENUMERATION; + } + } + + ur_result_t result = pfnGetInfo(hContext, pStart, size, propName, propSize, + pPropValue, pPropSizeRet); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemCreate +__urdlllocal ur_result_t UR_APICALL urPhysicalMemCreate( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in] handle of the device object. + size_t + size, ///< [in] size in bytes of phyisical memory to allocate, must be a multiple + ///< of ::UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + const ur_physical_mem_properties_t * + pProperties, ///< [in][optional] pointer to physical memory creation properties. + ur_physical_mem_handle_t * + phPhysicalMem ///< [out] pointer to handle of physical memory object created. +) { + auto pfnCreate = context.urDdiTable.PhysicalMem.pfnCreate; + + if (nullptr == pfnCreate) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hContext) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == hDevice) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (NULL == phPhysicalMem) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + } + + ur_result_t result = + pfnCreate(hContext, hDevice, size, pProperties, phPhysicalMem); + + if (context.enableLeakChecking && result == UR_RESULT_SUCCESS) { + refCountContext.createRefCount(*phPhysicalMem); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRetain +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRetain( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to retain. +) { + auto pfnRetain = context.urDdiTable.PhysicalMem.pfnRetain; + + if (nullptr == pfnRetain) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hPhysicalMem) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + } + + ur_result_t result = pfnRetain(hPhysicalMem); + + if (context.enableLeakChecking && result == UR_RESULT_SUCCESS) { + refCountContext.incrementRefCount(hPhysicalMem); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRelease +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRelease( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to release. +) { + auto pfnRelease = context.urDdiTable.PhysicalMem.pfnRelease; + + if (nullptr == pfnRelease) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + if (context.enableParameterValidation) { + if (NULL == hPhysicalMem) { + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + } + + ur_result_t result = pfnRelease(hPhysicalMem); + + if (context.enableLeakChecking && result == UR_RESULT_SUCCESS) { + refCountContext.decrementRefCount(hPhysicalMem); + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urProgramCreateWithIL __urdlllocal ur_result_t UR_APICALL urProgramCreateWithIL( @@ -6731,6 +7086,46 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetMemProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's PhysicalMem 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 urGetPhysicalMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_physical_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers +) { + auto &dditable = ur_validation_layer::context.urDdiTable.PhysicalMem; + + if (nullptr == pDdiTable) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (UR_MAJOR_VERSION(ur_validation_layer::context.version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_validation_layer::context.version) > + UR_MINOR_VERSION(version)) { + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + } + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnCreate = pDdiTable->pfnCreate; + pDdiTable->pfnCreate = ur_validation_layer::urPhysicalMemCreate; + + dditable.pfnRetain = pDdiTable->pfnRetain; + pDdiTable->pfnRetain = ur_validation_layer::urPhysicalMemRetain; + + dditable.pfnRelease = pDdiTable->pfnRelease; + pDdiTable->pfnRelease = ur_validation_layer::urPhysicalMemRelease; + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Platform table /// with current process' addresses @@ -7061,6 +7456,59 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetUSMExpProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's VirtualMem 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 urGetVirtualMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_virtual_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers +) { + auto &dditable = ur_validation_layer::context.urDdiTable.VirtualMem; + + if (nullptr == pDdiTable) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (UR_MAJOR_VERSION(ur_validation_layer::context.version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_validation_layer::context.version) > + UR_MINOR_VERSION(version)) { + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + } + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnGranularityGetInfo = pDdiTable->pfnGranularityGetInfo; + pDdiTable->pfnGranularityGetInfo = + ur_validation_layer::urVirtualMemGranularityGetInfo; + + dditable.pfnReserve = pDdiTable->pfnReserve; + pDdiTable->pfnReserve = ur_validation_layer::urVirtualMemReserve; + + dditable.pfnFree = pDdiTable->pfnFree; + pDdiTable->pfnFree = ur_validation_layer::urVirtualMemFree; + + dditable.pfnMap = pDdiTable->pfnMap; + pDdiTable->pfnMap = ur_validation_layer::urVirtualMemMap; + + dditable.pfnUnmap = pDdiTable->pfnUnmap; + pDdiTable->pfnUnmap = ur_validation_layer::urVirtualMemUnmap; + + dditable.pfnSetAccess = pDdiTable->pfnSetAccess; + pDdiTable->pfnSetAccess = ur_validation_layer::urVirtualMemSetAccess; + + dditable.pfnGetInfo = pDdiTable->pfnGetInfo; + pDdiTable->pfnGetInfo = ur_validation_layer::urVirtualMemGetInfo; + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Device table /// with current process' addresses @@ -7165,6 +7613,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable) { UR_API_VERSION_CURRENT, &dditable->Mem); } + if (UR_RESULT_SUCCESS == result) { + result = ur_validation_layer::urGetPhysicalMemProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->PhysicalMem); + } + if (UR_RESULT_SUCCESS == result) { result = ur_validation_layer::urGetPlatformProcAddrTable( UR_API_VERSION_CURRENT, &dditable->Platform); @@ -7195,6 +7648,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable) { UR_API_VERSION_CURRENT, &dditable->USMExp); } + if (UR_RESULT_SUCCESS == result) { + result = ur_validation_layer::urGetVirtualMemProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->VirtualMem); + } + if (UR_RESULT_SUCCESS == result) { result = ur_validation_layer::urGetDeviceProcAddrTable( UR_API_VERSION_CURRENT, &dditable->Device); diff --git a/source/loader/ur_ldrddi.cpp b/source/loader/ur_ldrddi.cpp index e54469c151..4feceb7aba 100644 --- a/source/loader/ur_ldrddi.cpp +++ b/source/loader/ur_ldrddi.cpp @@ -24,6 +24,7 @@ ur_queue_factory_t ur_queue_factory; ur_native_factory_t ur_native_factory; ur_sampler_factory_t ur_sampler_factory; ur_mem_factory_t ur_mem_factory; +ur_physical_mem_factory_t ur_physical_mem_factory; ur_usm_pool_factory_t ur_usm_pool_factory; ur_exp_image_factory_t ur_exp_image_factory; ur_exp_image_mem_factory_t ur_exp_image_mem_factory; @@ -1769,6 +1770,332 @@ __urdlllocal ur_result_t UR_APICALL urUSMPoolGetInfo( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGranularityGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGranularityGetInfo( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t + hDevice, ///< [in][optional] is the device to get the granularity from, if the + ///< device is null then the granularity is suitable for all devices in context. + ur_virtual_mem_granularity_info_t + propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnGranularityGetInfo = dditable->ur.VirtualMem.pfnGranularityGetInfo; + if (nullptr == pfnGranularityGetInfo) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // convert loader handle to platform handle + hDevice = (hDevice) + ? reinterpret_cast(hDevice)->handle + : nullptr; + + // forward to device-platform + result = pfnGranularityGetInfo(hContext, hDevice, propName, propSize, + pPropValue, pPropSizeRet); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemReserve +__urdlllocal ur_result_t UR_APICALL urVirtualMemReserve( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in][optional] pointer to the start of the virtual memory region to + ///< reserve, specifying a null value causes the implementation to select a + ///< start address. + size_t + size, ///< [in] size in bytes of the virtual address range to reserve. + void ** + ppStart ///< [out] pointer to the returned address at the start of reserved virtual + ///< memory range. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnReserve = dditable->ur.VirtualMem.pfnReserve; + if (nullptr == pfnReserve) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // forward to device-platform + result = pfnReserve(hContext, pStart, size, ppStart); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemFree +__urdlllocal ur_result_t UR_APICALL urVirtualMemFree( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in] pointer to the start of the virtual memory range to free. + size_t size ///< [in] size in bytes of the virtual memory range to free. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnFree = dditable->ur.VirtualMem.pfnFree; + if (nullptr == pfnFree) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // forward to device-platform + result = pfnFree(hContext, pStart, size); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemMap +__urdlllocal ur_result_t UR_APICALL urVirtualMemMap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range to map. + ur_physical_mem_handle_t + hPhysicalMem, ///< [in] handle of the physical memory to map pStart to. + size_t + offset, ///< [in] offset in bytes into the physical memory to map pStart to. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags for the physical memory mapping. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnMap = dditable->ur.VirtualMem.pfnMap; + if (nullptr == pfnMap) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // convert loader handle to platform handle + hPhysicalMem = + reinterpret_cast(hPhysicalMem)->handle; + + // forward to device-platform + result = pfnMap(hContext, pStart, size, hPhysicalMem, offset, flags); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemUnmap +__urdlllocal ur_result_t UR_APICALL urVirtualMemUnmap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void * + pStart, ///< [in] pointer to the start of the mapped virtual memory range + size_t size ///< [in] size in bytes of the virtual memory range. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnUnmap = dditable->ur.VirtualMem.pfnUnmap; + if (nullptr == pfnUnmap) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // forward to device-platform + result = pfnUnmap(hContext, pStart, size); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemSetAccess +__urdlllocal ur_result_t UR_APICALL urVirtualMemSetAccess( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virutal memory range. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags to set for the mapped virtual memory range. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnSetAccess = dditable->ur.VirtualMem.pfnSetAccess; + if (nullptr == pfnSetAccess) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // forward to device-platform + result = pfnSetAccess(hContext, pStart, size, flags); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urVirtualMemGetInfo +__urdlllocal ur_result_t UR_APICALL urVirtualMemGetInfo( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range. + ur_virtual_mem_info_t propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnGetInfo = dditable->ur.VirtualMem.pfnGetInfo; + if (nullptr == pfnGetInfo) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // forward to device-platform + result = pfnGetInfo(hContext, pStart, size, propName, propSize, pPropValue, + pPropSizeRet); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemCreate +__urdlllocal ur_result_t UR_APICALL urPhysicalMemCreate( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in] handle of the device object. + size_t + size, ///< [in] size in bytes of phyisical memory to allocate, must be a multiple + ///< of ::UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + const ur_physical_mem_properties_t * + pProperties, ///< [in][optional] pointer to physical memory creation properties. + ur_physical_mem_handle_t * + phPhysicalMem ///< [out] pointer to handle of physical memory object created. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = reinterpret_cast(hContext)->dditable; + auto pfnCreate = dditable->ur.PhysicalMem.pfnCreate; + if (nullptr == pfnCreate) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hContext = reinterpret_cast(hContext)->handle; + + // convert loader handle to platform handle + hDevice = reinterpret_cast(hDevice)->handle; + + // forward to device-platform + result = pfnCreate(hContext, hDevice, size, pProperties, phPhysicalMem); + + if (UR_RESULT_SUCCESS != result) { + return result; + } + + try { + // convert platform handle to loader handle + *phPhysicalMem = reinterpret_cast( + ur_physical_mem_factory.getInstance(*phPhysicalMem, dditable)); + } catch (std::bad_alloc &) { + result = UR_RESULT_ERROR_OUT_OF_HOST_MEMORY; + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRetain +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRetain( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to retain. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = + reinterpret_cast(hPhysicalMem)->dditable; + auto pfnRetain = dditable->ur.PhysicalMem.pfnRetain; + if (nullptr == pfnRetain) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hPhysicalMem = + reinterpret_cast(hPhysicalMem)->handle; + + // forward to device-platform + result = pfnRetain(hPhysicalMem); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urPhysicalMemRelease +__urdlllocal ur_result_t UR_APICALL urPhysicalMemRelease( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to release. +) { + ur_result_t result = UR_RESULT_SUCCESS; + + // extract platform's function pointer table + auto dditable = + reinterpret_cast(hPhysicalMem)->dditable; + auto pfnRelease = dditable->ur.PhysicalMem.pfnRelease; + if (nullptr == pfnRelease) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + // convert loader handle to platform handle + hPhysicalMem = + reinterpret_cast(hPhysicalMem)->handle; + + // forward to device-platform + result = pfnRelease(hPhysicalMem); + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urProgramCreateWithIL __urdlllocal ur_result_t UR_APICALL urProgramCreateWithIL( @@ -6597,6 +6924,62 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetMemProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's PhysicalMem 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 urGetPhysicalMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_physical_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers +) { + if (nullptr == pDdiTable) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (ur_loader::context->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::context->platforms) { + if (platform.initStatus != UR_RESULT_SUCCESS) { + continue; + } + auto getTable = reinterpret_cast( + ur_loader::LibLoader::getFunctionPtr( + platform.handle.get(), "urGetPhysicalMemProcAddrTable")); + if (!getTable) { + continue; + } + platform.initStatus = + getTable(version, &platform.dditable.ur.PhysicalMem); + } + + if (UR_RESULT_SUCCESS == result) { + if (ur_loader::context->platforms.size() != 1 || + ur_loader::context->forceIntercept) { + // return pointers to loader's DDIs + pDdiTable->pfnCreate = ur_loader::urPhysicalMemCreate; + pDdiTable->pfnRetain = ur_loader::urPhysicalMemRetain; + pDdiTable->pfnRelease = ur_loader::urPhysicalMemRelease; + } else { + // return pointers directly to platform's DDIs + *pDdiTable = + ur_loader::context->platforms.front().dditable.ur.PhysicalMem; + } + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Platform table /// with current process' addresses @@ -6961,6 +7344,67 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetUSMExpProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's VirtualMem 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 urGetVirtualMemProcAddrTable( + ur_api_version_t version, ///< [in] API version requested + ur_virtual_mem_dditable_t + *pDdiTable ///< [in,out] pointer to table of DDI function pointers +) { + if (nullptr == pDdiTable) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (ur_loader::context->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::context->platforms) { + if (platform.initStatus != UR_RESULT_SUCCESS) { + continue; + } + auto getTable = reinterpret_cast( + ur_loader::LibLoader::getFunctionPtr( + platform.handle.get(), "urGetVirtualMemProcAddrTable")); + if (!getTable) { + continue; + } + platform.initStatus = + getTable(version, &platform.dditable.ur.VirtualMem); + } + + if (UR_RESULT_SUCCESS == result) { + if (ur_loader::context->platforms.size() != 1 || + ur_loader::context->forceIntercept) { + // return pointers to loader's DDIs + pDdiTable->pfnGranularityGetInfo = + ur_loader::urVirtualMemGranularityGetInfo; + pDdiTable->pfnReserve = ur_loader::urVirtualMemReserve; + pDdiTable->pfnFree = ur_loader::urVirtualMemFree; + pDdiTable->pfnMap = ur_loader::urVirtualMemMap; + pDdiTable->pfnUnmap = ur_loader::urVirtualMemUnmap; + pDdiTable->pfnSetAccess = ur_loader::urVirtualMemSetAccess; + pDdiTable->pfnGetInfo = ur_loader::urVirtualMemGetInfo; + } else { + // return pointers directly to platform's DDIs + *pDdiTable = + ur_loader::context->platforms.front().dditable.ur.VirtualMem; + } + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Device table /// with current process' addresses diff --git a/source/loader/ur_ldrddi.hpp b/source/loader/ur_ldrddi.hpp index c5d6da5c27..9ebaeed9d9 100644 --- a/source/loader/ur_ldrddi.hpp +++ b/source/loader/ur_ldrddi.hpp @@ -56,6 +56,10 @@ using ur_sampler_factory_t = using ur_mem_object_t = object_t; using ur_mem_factory_t = singleton_factory_t; +using ur_physical_mem_object_t = object_t; +using ur_physical_mem_factory_t = + singleton_factory_t; + using ur_usm_pool_object_t = object_t; using ur_usm_pool_factory_t = singleton_factory_t; diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index 7389bc1ee7..f82cd8d18b 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -2071,6 +2071,324 @@ ur_result_t UR_APICALL urUSMPoolGetInfo( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get information about the minimum and recommended granularity of +/// physical and virtual memory. +/// +/// @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_ENUMERATION +/// + `::UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED < propName` +ur_result_t UR_APICALL urVirtualMemGranularityGetInfo( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t + hDevice, ///< [in][optional] is the device to get the granularity from, if the + ///< device is null then the granularity is suitable for all devices in context. + ur_virtual_mem_granularity_info_t + propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." + ) try { + auto pfnGranularityGetInfo = + ur_lib::context->urDdiTable.VirtualMem.pfnGranularityGetInfo; + if (nullptr == pfnGranularityGetInfo) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnGranularityGetInfo(hContext, hDevice, propName, propSize, + pPropValue, pPropSizeRet); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reserve a virtual memory range. +/// +/// @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 == ppStart` +ur_result_t UR_APICALL urVirtualMemReserve( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in][optional] pointer to the start of the virtual memory region to + ///< reserve, specifying a null value causes the implementation to select a + ///< start address. + size_t + size, ///< [in] size in bytes of the virtual address range to reserve. + void ** + ppStart ///< [out] pointer to the returned address at the start of reserved virtual + ///< memory range. + ) try { + auto pfnReserve = ur_lib::context->urDdiTable.VirtualMem.pfnReserve; + if (nullptr == pfnReserve) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnReserve(hContext, pStart, size, ppStart); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Free a virtual memory range. +/// +/// @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 == pStart` +ur_result_t UR_APICALL urVirtualMemFree( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in] pointer to the start of the virtual memory range to free. + size_t size ///< [in] size in bytes of the virtual memory range to free. + ) try { + auto pfnFree = ur_lib::context->urDdiTable.VirtualMem.pfnFree; + if (nullptr == pfnFree) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnFree(hContext, pStart, size); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Map a virtual memory range to a physical memory handle. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hPhysicalMem` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags` +ur_result_t UR_APICALL urVirtualMemMap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range to map. + ur_physical_mem_handle_t + hPhysicalMem, ///< [in] handle of the physical memory to map pStart to. + size_t + offset, ///< [in] offset in bytes into the physical memory to map pStart to. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags for the physical memory mapping. + ) try { + auto pfnMap = ur_lib::context->urDdiTable.VirtualMem.pfnMap; + if (nullptr == pfnMap) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnMap(hContext, pStart, size, hPhysicalMem, offset, flags); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Unmap a virtual memory range previously mapped in a context. +/// +/// @details +/// - After a call to this function, the virtual memory range is left in a +/// state ready to be remapped. +/// +/// @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 == pStart` +ur_result_t UR_APICALL urVirtualMemUnmap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void * + pStart, ///< [in] pointer to the start of the mapped virtual memory range + size_t size ///< [in] size in bytes of the virtual memory range. + ) try { + auto pfnUnmap = ur_lib::context->urDdiTable.VirtualMem.pfnUnmap; + if (nullptr == pfnUnmap) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnUnmap(hContext, pStart, size); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the access mode of a mapped virtual memory range. +/// +/// @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 == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags` +ur_result_t UR_APICALL urVirtualMemSetAccess( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virutal memory range. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags to set for the mapped virtual memory range. + ) try { + auto pfnSetAccess = ur_lib::context->urDdiTable.VirtualMem.pfnSetAccess; + if (nullptr == pfnSetAccess) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnSetAccess(hContext, pStart, size, flags); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get information about a mapped virtual memory range. +/// +/// @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 == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_INFO_ACCESS_MODE < propName` +ur_result_t UR_APICALL urVirtualMemGetInfo( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range. + ur_virtual_mem_info_t propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." + ) try { + auto pfnGetInfo = ur_lib::context->urDdiTable.VirtualMem.pfnGetInfo; + if (nullptr == pfnGetInfo) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnGetInfo(hContext, pStart, size, propName, propSize, pPropValue, + pPropSizeRet); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Create a physical memory handle that virtual memory can be mapped to. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phPhysicalMem` +ur_result_t UR_APICALL urPhysicalMemCreate( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in] handle of the device object. + size_t + size, ///< [in] size in bytes of phyisical memory to allocate, must be a multiple + ///< of ::UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + const ur_physical_mem_properties_t * + pProperties, ///< [in][optional] pointer to physical memory creation properties. + ur_physical_mem_handle_t * + phPhysicalMem ///< [out] pointer to handle of physical memory object created. + ) try { + auto pfnCreate = ur_lib::context->urDdiTable.PhysicalMem.pfnCreate; + if (nullptr == pfnCreate) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnCreate(hContext, hDevice, size, pProperties, phPhysicalMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Retain a physical memory handle, increment its reference count. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hPhysicalMem` +ur_result_t UR_APICALL urPhysicalMemRetain( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to retain. + ) try { + auto pfnRetain = ur_lib::context->urDdiTable.PhysicalMem.pfnRetain; + if (nullptr == pfnRetain) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnRetain(hPhysicalMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Release a physical memory handle, decrement its reference count. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hPhysicalMem` +ur_result_t UR_APICALL urPhysicalMemRelease( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to release. + ) try { + auto pfnRelease = ur_lib::context->urDdiTable.PhysicalMem.pfnRelease; + if (nullptr == pfnRelease) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + return pfnRelease(hPhysicalMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Create a program object from input intermediate language. /// diff --git a/source/loader/ur_libddi.cpp b/source/loader/ur_libddi.cpp index 0a43553059..1c8ccd5593 100644 --- a/source/loader/ur_libddi.cpp +++ b/source/loader/ur_libddi.cpp @@ -59,6 +59,11 @@ __urdlllocal ur_result_t context_t::urInit() { result = urGetMemProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Mem); } + if (UR_RESULT_SUCCESS == result) { + result = urGetPhysicalMemProcAddrTable(UR_API_VERSION_CURRENT, + &urDdiTable.PhysicalMem); + } + if (UR_RESULT_SUCCESS == result) { result = urGetPlatformProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Platform); @@ -88,6 +93,11 @@ __urdlllocal ur_result_t context_t::urInit() { &urDdiTable.USMExp); } + if (UR_RESULT_SUCCESS == result) { + result = urGetVirtualMemProcAddrTable(UR_API_VERSION_CURRENT, + &urDdiTable.VirtualMem); + } + if (UR_RESULT_SUCCESS == result) { result = urGetDeviceProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Device); diff --git a/source/ur_api.cpp b/source/ur_api.cpp index d326f7f3c7..d5d4888570 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -1733,6 +1733,261 @@ ur_result_t UR_APICALL urUSMPoolGetInfo( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get information about the minimum and recommended granularity of +/// physical and virtual memory. +/// +/// @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_ENUMERATION +/// + `::UR_VIRTUAL_MEM_GRANULARITY_INFO_RECOMMENDED < propName` +ur_result_t UR_APICALL urVirtualMemGranularityGetInfo( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t + hDevice, ///< [in][optional] is the device to get the granularity from, if the + ///< device is null then the granularity is suitable for all devices in context. + ur_virtual_mem_granularity_info_t + propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reserve a virtual memory range. +/// +/// @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 == ppStart` +ur_result_t UR_APICALL urVirtualMemReserve( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in][optional] pointer to the start of the virtual memory region to + ///< reserve, specifying a null value causes the implementation to select a + ///< start address. + size_t + size, ///< [in] size in bytes of the virtual address range to reserve. + void ** + ppStart ///< [out] pointer to the returned address at the start of reserved virtual + ///< memory range. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Free a virtual memory range. +/// +/// @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 == pStart` +ur_result_t UR_APICALL urVirtualMemFree( + ur_context_handle_t hContext, ///< [in] handle of the context object. + const void * + pStart, ///< [in] pointer to the start of the virtual memory range to free. + size_t size ///< [in] size in bytes of the virtual memory range to free. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Map a virtual memory range to a physical memory handle. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hPhysicalMem` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags` +ur_result_t UR_APICALL urVirtualMemMap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range to map. + ur_physical_mem_handle_t + hPhysicalMem, ///< [in] handle of the physical memory to map pStart to. + size_t + offset, ///< [in] offset in bytes into the physical memory to map pStart to. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags for the physical memory mapping. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Unmap a virtual memory range previously mapped in a context. +/// +/// @details +/// - After a call to this function, the virtual memory range is left in a +/// state ready to be remapped. +/// +/// @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 == pStart` +ur_result_t UR_APICALL urVirtualMemUnmap( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void * + pStart, ///< [in] pointer to the start of the mapped virtual memory range + size_t size ///< [in] size in bytes of the virtual memory range. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the access mode of a mapped virtual memory range. +/// +/// @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 == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_ACCESS_FLAGS_MASK & flags` +ur_result_t UR_APICALL urVirtualMemSetAccess( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virutal memory range. + ur_virtual_mem_access_flags_t + flags ///< [in] access flags to set for the mapped virtual memory range. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get information about a mapped virtual memory range. +/// +/// @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 == pStart` +/// - ::UR_RESULT_ERROR_INVALID_ENUMERATION +/// + `::UR_VIRTUAL_MEM_INFO_ACCESS_MODE < propName` +ur_result_t UR_APICALL urVirtualMemGetInfo( + ur_context_handle_t hContext, ///< [in] handle to the context object. + const void + *pStart, ///< [in] pointer to the start of the virtual memory range. + size_t size, ///< [in] size in bytes of the virtual memory range. + ur_virtual_mem_info_t propName, ///< [in] type of the info to query. + size_t + propSize, ///< [in] size in bytes of the memory pointed to by pPropValue. + void * + pPropValue, ///< [out][optional][typename(propName, propSize)] array of bytes holding + ///< the info. If propSize is less than the real number of bytes needed to + ///< return the info then the ::UR_RESULT_ERROR_INVALID_SIZE error is + ///< returned and pPropValue is not used. + size_t * + pPropSizeRet ///< [out][optional] pointer to the actual size in bytes of the queried propName." +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Create a physical memory handle that virtual memory can be mapped to. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phPhysicalMem` +ur_result_t UR_APICALL urPhysicalMemCreate( + ur_context_handle_t hContext, ///< [in] handle of the context object. + ur_device_handle_t hDevice, ///< [in] handle of the device object. + size_t + size, ///< [in] size in bytes of phyisical memory to allocate, must be a multiple + ///< of ::UR_VIRTUAL_MEM_GRANULARITY_INFO_MINIMUM. + const ur_physical_mem_properties_t * + pProperties, ///< [in][optional] pointer to physical memory creation properties. + ur_physical_mem_handle_t * + phPhysicalMem ///< [out] pointer to handle of physical memory object created. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Retain a physical memory handle, increment its reference count. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hPhysicalMem` +ur_result_t UR_APICALL urPhysicalMemRetain( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to retain. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Release a physical memory handle, decrement its reference count. +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hPhysicalMem` +ur_result_t UR_APICALL urPhysicalMemRelease( + ur_physical_mem_handle_t + hPhysicalMem ///< [in] handle of the physical memory object to release. +) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Create a program object from input intermediate language. ///