@@ -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 ;
@@ -132,6 +140,16 @@ static void store_last_native_error(int32_t native_error) {
132140struct ctl ze_memory_ctl_root ;
133141static UTIL_ONCE_FLAG ctl_initialized = UTIL_ONCE_FLAG_INIT ;
134142
143+ static ze_relaxed_allocation_limits_exp_desc_t relaxed_device_allocation_desc =
144+ {.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC ,
145+ .pNext = NULL ,
146+ .flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE };
147+
148+ static ze_external_memory_export_desc_t memory_export_desc = {
149+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC ,
150+ .pNext = NULL ,
151+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 };
152+
135153static void initialize_ze_ctl (void ) {
136154 CTL_REGISTER_MODULE (& ze_memory_ctl_root , stats );
137155}
@@ -263,6 +281,8 @@ umf_result_t umfLevelZeroMemoryProviderParamsCreate(
263281 params -> resident_device_handles = NULL ;
264282 params -> resident_device_count = 0 ;
265283 params -> freePolicy = UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT ;
284+ params -> exchangePolicy =
285+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ;
266286 params -> device_ordinal = 0 ;
267287 strncpy (params -> name , DEFAULT_NAME , sizeof (params -> name ) - 1 );
268288 params -> name [sizeof (params -> name ) - 1 ] = '\0' ;
@@ -394,6 +414,18 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
394414 return UMF_RESULT_SUCCESS ;
395415}
396416
417+ umf_result_t umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy (
418+ umf_level_zero_memory_provider_params_handle_t hParams ,
419+ umf_level_zero_memory_provider_memory_exchange_policy_t policy ) {
420+ if (!hParams ) {
421+ LOG_ERR ("Level Zero memory provider params handle is NULL" );
422+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
423+ }
424+
425+ hParams -> exchangePolicy = policy ;
426+ return UMF_RESULT_SUCCESS ;
427+ }
428+
397429static ze_driver_memory_free_policy_ext_flags_t
398430umfFreePolicyToZePolicy (umf_level_zero_memory_provider_free_policy_t policy ) {
399431 switch (policy ) {
@@ -416,11 +448,6 @@ static bool use_relaxed_allocation(ze_memory_provider_t *ze_provider,
416448 return size > ze_provider -> device_properties .maxMemAllocSize ;
417449}
418450
419- static ze_relaxed_allocation_limits_exp_desc_t relaxed_device_allocation_desc =
420- {.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC ,
421- .pNext = NULL ,
422- .flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE };
423-
424451static umf_result_t ze_memory_provider_free_helper (void * provider , void * ptr ,
425452 size_t bytes ,
426453 int update_stats ) {
@@ -478,11 +505,29 @@ static umf_result_t ze_memory_provider_alloc_helper(void *provider, size_t size,
478505 case UMF_MEMORY_TYPE_DEVICE : {
479506 ze_device_mem_alloc_desc_t dev_desc = {
480507 .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
481- .pNext = use_relaxed_allocation (ze_provider , size )
482- ? & relaxed_device_allocation_desc
483- : NULL ,
508+ .pNext = NULL ,
484509 .flags = 0 ,
485510 .ordinal = ze_provider -> device_ordinal };
511+ void * lastNext = & dev_desc .pNext ;
512+
513+ ze_relaxed_allocation_limits_exp_desc_t
514+ relaxed_device_allocation_desc_copy =
515+ relaxed_device_allocation_desc ;
516+ if (use_relaxed_allocation (ze_provider , size )) {
517+ // add relaxed allocation desc to the pNext chain
518+ * (void * * )lastNext = & relaxed_device_allocation_desc_copy ;
519+ lastNext = & relaxed_device_allocation_desc_copy .pNext ;
520+ }
521+
522+ ze_external_memory_export_desc_t memory_export_desc_copy =
523+ memory_export_desc ;
524+ if (ze_provider -> exchangePolicy ==
525+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT ) {
526+ // add external memory export desc to the pNext chain
527+ * (void * * )lastNext = & memory_export_desc_copy ;
528+ lastNext = & memory_export_desc_copy .pNext ;
529+ }
530+
486531 ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & dev_desc ,
487532 size , alignment ,
488533 ze_provider -> device , resultPtr );
@@ -642,6 +687,7 @@ static umf_result_t ze_memory_provider_initialize(const void *params,
642687 ze_provider -> memory_type = umf2ze_memory_type (ze_params -> memory_type );
643688 ze_provider -> freePolicyFlags =
644689 umfFreePolicyToZePolicy (ze_params -> freePolicy );
690+ ze_provider -> exchangePolicy = ze_params -> exchangePolicy ;
645691 ze_provider -> min_page_size = 0 ;
646692 ze_provider -> device_ordinal = ze_params -> device_ordinal ;
647693
@@ -807,6 +853,7 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
807853
808854typedef struct ze_ipc_data_t {
809855 int pid ;
856+ size_t size ;
810857 ze_ipc_mem_handle_t ze_handle ;
811858} ze_ipc_data_t ;
812859
@@ -822,20 +869,45 @@ static umf_result_t ze_memory_provider_get_ipc_handle(void *provider,
822869 const void * ptr ,
823870 size_t size ,
824871 void * providerIpcData ) {
825- (void )size ;
826-
827872 ze_result_t ze_result ;
828873 ze_ipc_data_t * ze_ipc_data = (ze_ipc_data_t * )providerIpcData ;
829874 struct ze_memory_provider_t * ze_provider =
830875 (struct ze_memory_provider_t * )provider ;
831876
832- ze_result = g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr ,
833- & ze_ipc_data -> ze_handle );
834- if (ze_result != ZE_RESULT_SUCCESS ) {
835- LOG_ERR ("zeMemGetIpcHandle() failed." );
836- return ze2umf_result (ze_result );
877+ if (ze_provider -> exchangePolicy ==
878+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
879+ ze_result = g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr ,
880+ & ze_ipc_data -> ze_handle );
881+
882+ if (ze_result != ZE_RESULT_SUCCESS ) {
883+ LOG_ERR ("zeMemGetIpcHandle() failed." );
884+ return ze2umf_result (ze_result );
885+ }
886+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
887+ ze_external_memory_export_fd_t fd_desc = {
888+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD ,
889+ .pNext = NULL ,
890+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 ,
891+ .fd = 0 };
892+
893+ ze_memory_allocation_properties_t mem_alloc_props = {
894+ .stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES ,
895+ .pNext = & fd_desc ,
896+ .type = 0 ,
897+ .id = 0 ,
898+ .pageSize = 0 };
899+
900+ ze_result = g_ze_ops .zeMemGetAllocProperties (ze_provider -> context , ptr ,
901+ & mem_alloc_props , NULL );
902+ if (ze_result != ZE_RESULT_SUCCESS ) {
903+ LOG_ERR ("zeMemGetAllocProperties() failed." );
904+ return ze2umf_result (ze_result );
905+ }
906+
907+ memcpy (& ze_ipc_data -> ze_handle , & fd_desc .fd , sizeof (fd_desc .fd ));
837908 }
838909
910+ ze_ipc_data -> size = size ;
839911 ze_ipc_data -> pid = utils_getpid ();
840912
841913 return UMF_RESULT_SUCCESS ;
@@ -886,14 +958,40 @@ static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
886958 memcpy (& ze_ipc_handle , & fd_local , sizeof (fd_local ));
887959 }
888960
889- ze_result = g_ze_ops .zeMemOpenIpcHandle (
890- ze_provider -> context , ze_provider -> device , ze_ipc_handle , 0 , ptr );
891- if (fd_local != -1 ) {
892- (void )utils_close_fd (fd_local );
893- }
894- if (ze_result != ZE_RESULT_SUCCESS ) {
895- LOG_ERR ("zeMemOpenIpcHandle() failed." );
896- return ze2umf_result (ze_result );
961+ if (ze_provider -> exchangePolicy ==
962+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
963+ ze_result = g_ze_ops .zeMemOpenIpcHandle (
964+ ze_provider -> context , ze_provider -> device , ze_ipc_handle , 0 , ptr );
965+ if (fd_local != -1 ) {
966+ (void )utils_close_fd (fd_local );
967+ }
968+ if (ze_result != ZE_RESULT_SUCCESS ) {
969+ LOG_ERR ("zeMemOpenIpcHandle() failed." );
970+ return ze2umf_result (ze_result );
971+ }
972+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
973+ ze_external_memory_import_fd_t import_fd = {
974+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD ,
975+ .pNext = NULL ,
976+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF ,
977+ .fd = fd_local };
978+
979+ ze_device_mem_alloc_desc_t alloc_desc = {
980+ .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
981+ .pNext = & import_fd ,
982+ .flags = 0 ,
983+ .ordinal = 0 };
984+ ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & alloc_desc ,
985+ ze_ipc_data -> size , 0 ,
986+ ze_provider -> device , ptr );
987+ if (fd_local != -1 ) {
988+ (void )utils_close_fd (fd_local );
989+ }
990+
991+ if (ze_result != ZE_RESULT_SUCCESS ) {
992+ LOG_ERR ("zeMemAllocDevice() failed." );
993+ return ze2umf_result (ze_result );
994+ }
897995 }
898996
899997 return UMF_RESULT_SUCCESS ;
@@ -1238,6 +1336,14 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
12381336 return UMF_RESULT_ERROR_NOT_SUPPORTED ;
12391337}
12401338
1339+ umf_result_t umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy (
1340+ umf_level_zero_memory_provider_params_handle_t hParams ,
1341+ umf_level_zero_memory_provider_memory_exchange_policy_t policy ) {
1342+ (void )hParams ;
1343+ (void )policy ;
1344+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
1345+ }
1346+
12411347umf_result_t umfLevelZeroMemoryProviderParamsSetDeviceOrdinal (
12421348 umf_level_zero_memory_provider_params_handle_t hParams ,
12431349 uint32_t deviceOrdinal ) {
0 commit comments