@@ -44,20 +44,26 @@ void fini_ze_global_state(void) {
4444
4545// Level Zero Memory Provider settings struct
4646typedef struct umf_level_zero_memory_provider_params_t {
47- ze_context_handle_t
48- level_zero_context_handle ; ///< Handle to the Level Zero context
49- ze_device_handle_t
50- level_zero_device_handle ; ///< Handle to the Level Zero device
47+ // Handle to the Level Zero context
48+ ze_context_handle_t level_zero_context_handle ;
5149
52- umf_usm_memory_type_t memory_type ; ///< Allocation memory type
50+ // Handle to the Level Zero device
51+ ze_device_handle_t level_zero_device_handle ;
5352
54- ze_device_handle_t *
55- resident_device_handles ; ///< Array of devices for which the memory should be made resident
56- uint32_t
57- resident_device_count ; ///< Number of devices for which the memory should be made resident
53+ // Allocation memory type
54+ umf_usm_memory_type_t memory_type ;
5855
59- umf_level_zero_memory_provider_free_policy_t
60- freePolicy ; ///< Memory free policy
56+ // Array of devices for which the memory should be made resident
57+ ze_device_handle_t * resident_device_handles ;
58+
59+ // Number of devices for which the memory should be made resident
60+ uint32_t resident_device_count ;
61+
62+ // Memory free policy
63+ umf_level_zero_memory_provider_free_policy_t freePolicy ;
64+
65+ // Memory exchange policy
66+ umf_level_zero_memory_provider_memory_exchange_policy_t exchangePolicy ;
6167
6268 uint32_t device_ordinal ;
6369 char name [64 ];
@@ -77,6 +83,8 @@ typedef struct ze_memory_provider_t {
7783
7884 ze_driver_memory_free_policy_ext_flags_t freePolicyFlags ;
7985
86+ umf_level_zero_memory_provider_memory_exchange_policy_t exchangePolicy ;
87+
8088 size_t min_page_size ;
8189
8290 uint32_t device_ordinal ;
@@ -134,7 +142,62 @@ static void store_last_native_error(int32_t native_error) {
134142struct ctl ze_memory_ctl_root ;
135143static UTIL_ONCE_FLAG ctl_initialized = UTIL_ONCE_FLAG_INIT ;
136144
145+ static ze_relaxed_allocation_limits_exp_desc_t relaxed_device_allocation_desc =
146+ {.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC ,
147+ .pNext = NULL ,
148+ .flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE };
149+
150+ static ze_external_memory_export_desc_t memory_export_desc = {
151+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC ,
152+ .pNext = NULL ,
153+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 };
154+
155+ static umf_result_t CTL_READ_HANDLER (memory_exchange_policy )(
156+ void * ctx , umf_ctl_query_source_t source , void * arg , size_t size ,
157+ umf_ctl_index_utlist_t * indexes ) {
158+ /* suppress unused-parameter errors */
159+ (void )source , (void )indexes ;
160+
161+ size_t expected_size =
162+ sizeof (umf_level_zero_memory_provider_memory_exchange_policy_t );
163+ if (arg == NULL || size != expected_size ) {
164+ LOG_ERR ("arg is NULL or size is not valid" );
165+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
166+ }
167+
168+ umf_level_zero_memory_provider_memory_exchange_policy_t * arg_out = arg ;
169+ ze_memory_provider_t * ze_provider = (ze_memory_provider_t * )ctx ;
170+ * arg_out = ze_provider -> exchangePolicy ;
171+ return UMF_RESULT_SUCCESS ;
172+ }
173+
174+ static umf_result_t CTL_WRITE_HANDLER (memory_exchange_policy )(
175+ void * ctx , umf_ctl_query_source_t source , void * arg , size_t size ,
176+ umf_ctl_index_utlist_t * indexes ) {
177+ /* suppress unused-parameter errors */
178+ (void )source , (void )indexes ;
179+
180+ size_t expected_size =
181+ sizeof (umf_level_zero_memory_provider_memory_exchange_policy_t );
182+ if (arg == NULL || size != expected_size ) {
183+ LOG_ERR ("arg is NULL or size is not valid" );
184+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
185+ }
186+
187+ umf_level_zero_memory_provider_memory_exchange_policy_t arg_in =
188+ * (umf_level_zero_memory_provider_memory_exchange_policy_t * )arg ;
189+ ze_memory_provider_t * ze_provider = (ze_memory_provider_t * )ctx ;
190+ ze_provider -> exchangePolicy = arg_in ;
191+ return UMF_RESULT_SUCCESS ;
192+ }
193+
194+ static const struct ctl_argument CTL_ARG (memory_exchange_policy ) = CTL_ARG_INT ;
195+
196+ static const umf_ctl_node_t CTL_NODE (params )[] = {
197+ CTL_LEAF_RW (memory_exchange_policy ), CTL_NODE_END };
198+
137199static void initialize_ze_ctl (void ) {
200+ CTL_REGISTER_MODULE (& ze_memory_ctl_root , params );
138201 CTL_REGISTER_MODULE (& ze_memory_ctl_root , stats );
139202}
140203
@@ -268,6 +331,8 @@ umf_result_t umfLevelZeroMemoryProviderParamsCreate(
268331 params -> resident_device_handles = NULL ;
269332 params -> resident_device_count = 0 ;
270333 params -> freePolicy = UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT ;
334+ params -> exchangePolicy =
335+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ;
271336 params -> device_ordinal = 0 ;
272337 strncpy (params -> name , DEFAULT_NAME , sizeof (params -> name ) - 1 );
273338 params -> name [sizeof (params -> name ) - 1 ] = '\0' ;
@@ -421,11 +486,6 @@ static bool use_relaxed_allocation(ze_memory_provider_t *ze_provider,
421486 return size > ze_provider -> device_properties .maxMemAllocSize ;
422487}
423488
424- static ze_relaxed_allocation_limits_exp_desc_t relaxed_device_allocation_desc =
425- {.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC ,
426- .pNext = NULL ,
427- .flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE };
428-
429489static umf_result_t ze_memory_provider_free_helper (void * provider , void * ptr ,
430490 size_t bytes ,
431491 int update_stats ) {
@@ -483,11 +543,29 @@ static umf_result_t ze_memory_provider_alloc_helper(void *provider, size_t size,
483543 case UMF_MEMORY_TYPE_DEVICE : {
484544 ze_device_mem_alloc_desc_t dev_desc = {
485545 .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
486- .pNext = use_relaxed_allocation (ze_provider , size )
487- ? & relaxed_device_allocation_desc
488- : NULL ,
546+ .pNext = NULL ,
489547 .flags = 0 ,
490548 .ordinal = ze_provider -> device_ordinal };
549+ void * lastNext = & dev_desc .pNext ;
550+
551+ ze_relaxed_allocation_limits_exp_desc_t
552+ relaxed_device_allocation_desc_copy =
553+ relaxed_device_allocation_desc ;
554+ if (use_relaxed_allocation (ze_provider , size )) {
555+ // add relaxed allocation desc to the pNext chain
556+ * (void * * )lastNext = & relaxed_device_allocation_desc_copy ;
557+ lastNext = & relaxed_device_allocation_desc_copy .pNext ;
558+ }
559+
560+ ze_external_memory_export_desc_t memory_export_desc_copy =
561+ memory_export_desc ;
562+ if (ze_provider -> exchangePolicy ==
563+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT ) {
564+ // add external memory export desc to the pNext chain
565+ * (void * * )lastNext = & memory_export_desc_copy ;
566+ lastNext = & memory_export_desc_copy .pNext ;
567+ }
568+
491569 ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & dev_desc ,
492570 size , alignment ,
493571 ze_provider -> device , resultPtr );
@@ -647,6 +725,7 @@ static umf_result_t ze_memory_provider_initialize(const void *params,
647725 ze_provider -> memory_type = umf2ze_memory_type (ze_params -> memory_type );
648726 ze_provider -> freePolicyFlags =
649727 umfFreePolicyToZePolicy (ze_params -> freePolicy );
728+ ze_provider -> exchangePolicy = ze_params -> exchangePolicy ;
650729 ze_provider -> min_page_size = 0 ;
651730 ze_provider -> device_ordinal = ze_params -> device_ordinal ;
652731
@@ -812,6 +891,7 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
812891
813892typedef struct ze_ipc_data_t {
814893 int pid ;
894+ size_t size ;
815895 ze_ipc_mem_handle_t ze_handle ;
816896} ze_ipc_data_t ;
817897
@@ -827,20 +907,45 @@ static umf_result_t ze_memory_provider_get_ipc_handle(void *provider,
827907 const void * ptr ,
828908 size_t size ,
829909 void * providerIpcData ) {
830- (void )size ;
831-
832910 ze_result_t ze_result ;
833911 ze_ipc_data_t * ze_ipc_data = (ze_ipc_data_t * )providerIpcData ;
834912 struct ze_memory_provider_t * ze_provider =
835913 (struct ze_memory_provider_t * )provider ;
836914
837- ze_result = g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr ,
838- & ze_ipc_data -> ze_handle );
839- if (ze_result != ZE_RESULT_SUCCESS ) {
840- LOG_ERR ("zeMemGetIpcHandle() failed." );
841- return ze2umf_result (ze_result );
915+ if (ze_provider -> exchangePolicy ==
916+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
917+ ze_result = g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr ,
918+ & ze_ipc_data -> ze_handle );
919+
920+ if (ze_result != ZE_RESULT_SUCCESS ) {
921+ LOG_ERR ("zeMemGetIpcHandle() failed." );
922+ return ze2umf_result (ze_result );
923+ }
924+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
925+ ze_external_memory_export_fd_t fd_desc = {
926+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD ,
927+ .pNext = NULL ,
928+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 ,
929+ .fd = 0 };
930+
931+ ze_memory_allocation_properties_t mem_alloc_props = {
932+ .stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES ,
933+ .pNext = & fd_desc ,
934+ .type = 0 ,
935+ .id = 0 ,
936+ .pageSize = 0 };
937+
938+ ze_result = g_ze_ops .zeMemGetAllocProperties (ze_provider -> context , ptr ,
939+ & mem_alloc_props , NULL );
940+ if (ze_result != ZE_RESULT_SUCCESS ) {
941+ LOG_ERR ("zeMemGetAllocProperties() failed." );
942+ return ze2umf_result (ze_result );
943+ }
944+
945+ memcpy (& ze_ipc_data -> ze_handle , & fd_desc .fd , sizeof (fd_desc .fd ));
842946 }
843947
948+ ze_ipc_data -> size = size ;
844949 ze_ipc_data -> pid = utils_getpid ();
845950
846951 return UMF_RESULT_SUCCESS ;
@@ -891,14 +996,40 @@ static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
891996 memcpy (& ze_ipc_handle , & fd_local , sizeof (fd_local ));
892997 }
893998
894- ze_result = g_ze_ops .zeMemOpenIpcHandle (
895- ze_provider -> context , ze_provider -> device , ze_ipc_handle , 0 , ptr );
896- if (fd_local != -1 ) {
897- (void )utils_close_fd (fd_local );
898- }
899- if (ze_result != ZE_RESULT_SUCCESS ) {
900- LOG_ERR ("zeMemOpenIpcHandle() failed." );
901- return ze2umf_result (ze_result );
999+ if (ze_provider -> exchangePolicy ==
1000+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
1001+ ze_result = g_ze_ops .zeMemOpenIpcHandle (
1002+ ze_provider -> context , ze_provider -> device , ze_ipc_handle , 0 , ptr );
1003+ if (fd_local != -1 ) {
1004+ (void )utils_close_fd (fd_local );
1005+ }
1006+ if (ze_result != ZE_RESULT_SUCCESS ) {
1007+ LOG_ERR ("zeMemOpenIpcHandle() failed." );
1008+ return ze2umf_result (ze_result );
1009+ }
1010+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
1011+ ze_external_memory_import_fd_t import_fd = {
1012+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD ,
1013+ .pNext = NULL ,
1014+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF ,
1015+ .fd = fd_local };
1016+
1017+ ze_device_mem_alloc_desc_t alloc_desc = {
1018+ .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
1019+ .pNext = & import_fd ,
1020+ .flags = 0 ,
1021+ .ordinal = 0 };
1022+ ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & alloc_desc ,
1023+ ze_ipc_data -> size , 0 ,
1024+ ze_provider -> device , ptr );
1025+ if (fd_local != -1 ) {
1026+ (void )utils_close_fd (fd_local );
1027+ }
1028+
1029+ if (ze_result != ZE_RESULT_SUCCESS ) {
1030+ LOG_ERR ("zeMemAllocDevice() failed." );
1031+ return ze2umf_result (ze_result );
1032+ }
9021033 }
9031034
9041035 return UMF_RESULT_SUCCESS ;
0 commit comments