@@ -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,48 @@ 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 , (void )size ;
160+
161+ umf_level_zero_memory_provider_memory_exchange_policy_t * arg_out = arg ;
162+ ze_memory_provider_t * ze_provider = (ze_memory_provider_t * )ctx ;
163+ * arg_out = ze_provider -> exchangePolicy ;
164+ return UMF_RESULT_SUCCESS ;
165+ }
166+
167+ static umf_result_t CTL_WRITE_HANDLER (memory_exchange_policy )(
168+ void * ctx , umf_ctl_query_source_t source , void * arg , size_t size ,
169+ umf_ctl_index_utlist_t * indexes ) {
170+ /* suppress unused-parameter errors */
171+ (void )source , (void )indexes , (void )size ;
172+
173+ umf_level_zero_memory_provider_memory_exchange_policy_t arg_in =
174+ * (umf_level_zero_memory_provider_memory_exchange_policy_t * )arg ;
175+ ze_memory_provider_t * ze_provider = (ze_memory_provider_t * )ctx ;
176+ ze_provider -> exchangePolicy = arg_in ;
177+ return UMF_RESULT_SUCCESS ;
178+ }
179+
180+ static const struct ctl_argument CTL_ARG (memory_exchange_policy ) = CTL_ARG_INT ;
181+
182+ static const umf_ctl_node_t CTL_NODE (params )[] = {
183+ CTL_LEAF_RW (memory_exchange_policy ), CTL_NODE_END };
184+
137185static void initialize_ze_ctl (void ) {
186+ CTL_REGISTER_MODULE (& ze_memory_ctl_root , params );
138187 CTL_REGISTER_MODULE (& ze_memory_ctl_root , stats );
139188}
140189
@@ -268,6 +317,8 @@ umf_result_t umfLevelZeroMemoryProviderParamsCreate(
268317 params -> resident_device_handles = NULL ;
269318 params -> resident_device_count = 0 ;
270319 params -> freePolicy = UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT ;
320+ params -> exchangePolicy =
321+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ;
271322 params -> device_ordinal = 0 ;
272323 strncpy (params -> name , DEFAULT_NAME , sizeof (params -> name ) - 1 );
273324 params -> name [sizeof (params -> name ) - 1 ] = '\0' ;
@@ -421,11 +472,6 @@ static bool use_relaxed_allocation(ze_memory_provider_t *ze_provider,
421472 return size > ze_provider -> device_properties .maxMemAllocSize ;
422473}
423474
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-
429475static umf_result_t ze_memory_provider_free_helper (void * provider , void * ptr ,
430476 size_t bytes ,
431477 int update_stats ) {
@@ -483,11 +529,29 @@ static umf_result_t ze_memory_provider_alloc_helper(void *provider, size_t size,
483529 case UMF_MEMORY_TYPE_DEVICE : {
484530 ze_device_mem_alloc_desc_t dev_desc = {
485531 .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
486- .pNext = use_relaxed_allocation (ze_provider , size )
487- ? & relaxed_device_allocation_desc
488- : NULL ,
532+ .pNext = NULL ,
489533 .flags = 0 ,
490534 .ordinal = ze_provider -> device_ordinal };
535+ void * lastNext = & dev_desc .pNext ;
536+
537+ ze_relaxed_allocation_limits_exp_desc_t
538+ relaxed_device_allocation_desc_copy =
539+ relaxed_device_allocation_desc ;
540+ if (use_relaxed_allocation (ze_provider , size )) {
541+ // add relaxed allocation desc to the pNext chain
542+ * (void * * )lastNext = & relaxed_device_allocation_desc_copy ;
543+ lastNext = & relaxed_device_allocation_desc_copy .pNext ;
544+ }
545+
546+ ze_external_memory_export_desc_t memory_export_desc_copy =
547+ memory_export_desc ;
548+ if (ze_provider -> exchangePolicy ==
549+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT ) {
550+ // add external memory export desc to the pNext chain
551+ * (void * * )lastNext = & memory_export_desc_copy ;
552+ lastNext = & memory_export_desc_copy .pNext ;
553+ }
554+
491555 ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & dev_desc ,
492556 size , alignment ,
493557 ze_provider -> device , resultPtr );
@@ -647,6 +711,7 @@ static umf_result_t ze_memory_provider_initialize(const void *params,
647711 ze_provider -> memory_type = umf2ze_memory_type (ze_params -> memory_type );
648712 ze_provider -> freePolicyFlags =
649713 umfFreePolicyToZePolicy (ze_params -> freePolicy );
714+ ze_provider -> exchangePolicy = ze_params -> exchangePolicy ;
650715 ze_provider -> min_page_size = 0 ;
651716 ze_provider -> device_ordinal = ze_params -> device_ordinal ;
652717
@@ -812,6 +877,7 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
812877
813878typedef struct ze_ipc_data_t {
814879 int pid ;
880+ size_t size ;
815881 ze_ipc_mem_handle_t ze_handle ;
816882} ze_ipc_data_t ;
817883
@@ -827,20 +893,45 @@ static umf_result_t ze_memory_provider_get_ipc_handle(void *provider,
827893 const void * ptr ,
828894 size_t size ,
829895 void * providerIpcData ) {
830- (void )size ;
831-
832896 ze_result_t ze_result ;
833897 ze_ipc_data_t * ze_ipc_data = (ze_ipc_data_t * )providerIpcData ;
834898 struct ze_memory_provider_t * ze_provider =
835899 (struct ze_memory_provider_t * )provider ;
836900
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 );
901+ if (ze_provider -> exchangePolicy ==
902+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
903+ ze_result = g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr ,
904+ & ze_ipc_data -> ze_handle );
905+
906+ if (ze_result != ZE_RESULT_SUCCESS ) {
907+ LOG_ERR ("zeMemGetIpcHandle() failed." );
908+ return ze2umf_result (ze_result );
909+ }
910+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
911+ ze_external_memory_export_fd_t fd_desc = {
912+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD ,
913+ .pNext = NULL ,
914+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 ,
915+ .fd = 0 };
916+
917+ ze_memory_allocation_properties_t mem_alloc_props = {
918+ .stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES ,
919+ .pNext = & fd_desc ,
920+ .type = 0 ,
921+ .id = 0 ,
922+ .pageSize = 0 };
923+
924+ ze_result = g_ze_ops .zeMemGetAllocProperties (ze_provider -> context , ptr ,
925+ & mem_alloc_props , NULL );
926+ if (ze_result != ZE_RESULT_SUCCESS ) {
927+ LOG_ERR ("zeMemGetAllocProperties() failed." );
928+ return ze2umf_result (ze_result );
929+ }
930+
931+ memcpy (& ze_ipc_data -> ze_handle , & fd_desc .fd , sizeof (fd_desc .fd ));
842932 }
843933
934+ ze_ipc_data -> size = size ;
844935 ze_ipc_data -> pid = utils_getpid ();
845936
846937 return UMF_RESULT_SUCCESS ;
@@ -891,14 +982,40 @@ static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
891982 memcpy (& ze_ipc_handle , & fd_local , sizeof (fd_local ));
892983 }
893984
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 );
985+ if (ze_provider -> exchangePolicy ==
986+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
987+ ze_result = g_ze_ops .zeMemOpenIpcHandle (
988+ ze_provider -> context , ze_provider -> device , ze_ipc_handle , 0 , ptr );
989+ if (fd_local != -1 ) {
990+ (void )utils_close_fd (fd_local );
991+ }
992+ if (ze_result != ZE_RESULT_SUCCESS ) {
993+ LOG_ERR ("zeMemOpenIpcHandle() failed." );
994+ return ze2umf_result (ze_result );
995+ }
996+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
997+ ze_external_memory_import_fd_t import_fd = {
998+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD ,
999+ .pNext = NULL ,
1000+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF ,
1001+ .fd = fd_local };
1002+
1003+ ze_device_mem_alloc_desc_t alloc_desc = {
1004+ .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
1005+ .pNext = & import_fd ,
1006+ .flags = 0 ,
1007+ .ordinal = 0 };
1008+ ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & alloc_desc ,
1009+ ze_ipc_data -> size , 0 ,
1010+ ze_provider -> device , ptr );
1011+ if (fd_local != -1 ) {
1012+ (void )utils_close_fd (fd_local );
1013+ }
1014+
1015+ if (ze_result != ZE_RESULT_SUCCESS ) {
1016+ LOG_ERR ("zeMemAllocDevice() failed." );
1017+ return ze2umf_result (ze_result );
1018+ }
9021019 }
9031020
9041021 return UMF_RESULT_SUCCESS ;
0 commit comments