@@ -58,6 +58,9 @@ typedef struct umf_level_zero_memory_provider_params_t {
5858 umf_level_zero_memory_provider_free_policy_t
5959 freePolicy ; ///< Memory free policy
6060
61+ umf_level_zero_memory_provider_memory_exchange_policy_t
62+ exchangePolicy ; ///< Memory exchange policy
63+
6164 uint32_t device_ordinal ;
6265 char name [64 ];
6366} umf_level_zero_memory_provider_params_t ;
@@ -74,6 +77,8 @@ typedef struct ze_memory_provider_t {
7477
7578 ze_driver_memory_free_policy_ext_flags_t freePolicyFlags ;
7679
80+ umf_level_zero_memory_provider_memory_exchange_policy_t exchangePolicy ;
81+
7782 size_t min_page_size ;
7883
7984 uint32_t device_ordinal ;
@@ -253,6 +258,8 @@ umf_result_t umfLevelZeroMemoryProviderParamsCreate(
253258 params -> resident_device_handles = NULL ;
254259 params -> resident_device_count = 0 ;
255260 params -> freePolicy = UMF_LEVEL_ZERO_MEMORY_PROVIDER_FREE_POLICY_DEFAULT ;
261+ params -> exchangePolicy =
262+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ;
256263 params -> device_ordinal = 0 ;
257264 strncpy (params -> name , DEFAULT_NAME , sizeof (params -> name ) - 1 );
258265 params -> name [sizeof (params -> name ) - 1 ] = '\0' ;
@@ -374,6 +381,18 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
374381 return UMF_RESULT_SUCCESS ;
375382}
376383
384+ umf_result_t umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy (
385+ umf_level_zero_memory_provider_params_handle_t hParams ,
386+ umf_level_zero_memory_provider_memory_exchange_policy_t policy ) {
387+ if (!hParams ) {
388+ LOG_ERR ("Level Zero memory provider params handle is NULL" );
389+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
390+ }
391+
392+ hParams -> exchangePolicy = policy ;
393+ return UMF_RESULT_SUCCESS ;
394+ }
395+
377396static ze_driver_memory_free_policy_ext_flags_t
378397umfFreePolicyToZePolicy (umf_level_zero_memory_provider_free_policy_t policy ) {
379398 switch (policy ) {
@@ -401,6 +420,11 @@ static ze_relaxed_allocation_limits_exp_desc_t relaxed_device_allocation_desc =
401420 .pNext = NULL ,
402421 .flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE };
403422
423+ static ze_external_memory_export_desc_t export_desc = {
424+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC ,
425+ .pNext = NULL ,
426+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 };
427+
404428static umf_result_t ze_memory_provider_alloc_helper (void * provider , size_t size ,
405429 size_t alignment ,
406430 int update_stats ,
@@ -421,14 +445,32 @@ static umf_result_t ze_memory_provider_alloc_helper(void *provider, size_t size,
421445 case UMF_MEMORY_TYPE_DEVICE : {
422446 ze_device_mem_alloc_desc_t dev_desc = {
423447 .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
424- .pNext = use_relaxed_allocation (ze_provider , size )
425- ? & relaxed_device_allocation_desc
426- : NULL ,
448+ .pNext = NULL ,
427449 .flags = 0 ,
428450 .ordinal = ze_provider -> device_ordinal };
451+ void * lastNext = & dev_desc .pNext ;
452+
453+ ze_relaxed_allocation_limits_exp_desc_t
454+ relaxed_device_allocation_desc_copy =
455+ relaxed_device_allocation_desc ;
456+ if (use_relaxed_allocation (ze_provider , size )) {
457+ * (uintptr_t * )lastNext =
458+ (uintptr_t )& relaxed_device_allocation_desc_copy ;
459+ lastNext = & relaxed_device_allocation_desc_copy .pNext ;
460+ }
461+
462+ // TODO - win only? other mem types?
463+ ze_external_memory_export_desc_t export_desc_copy = export_desc ;
464+ if (ze_provider -> exchangePolicy ==
465+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT ) {
466+ * (uintptr_t * )lastNext = (uintptr_t )& export_desc_copy ;
467+ lastNext = & export_desc_copy .pNext ;
468+ }
469+
429470 ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & dev_desc ,
430471 size , alignment ,
431472 ze_provider -> device , resultPtr );
473+ //LOG_ERR("alloc on device size %zu ptr %p", size, *resultPtr);
432474 break ;
433475 }
434476 case UMF_MEMORY_TYPE_SHARED : {
@@ -599,6 +641,7 @@ static umf_result_t ze_memory_provider_initialize(const void *params,
599641 ze_provider -> memory_type = umf2ze_memory_type (ze_params -> memory_type );
600642 ze_provider -> freePolicyFlags =
601643 umfFreePolicyToZePolicy (ze_params -> freePolicy );
644+ ze_provider -> exchangePolicy = ze_params -> exchangePolicy ;
602645 ze_provider -> min_page_size = 0 ;
603646 ze_provider -> device_ordinal = ze_params -> device_ordinal ;
604647
@@ -755,6 +798,7 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
755798
756799typedef struct ze_ipc_data_t {
757800 int pid ;
801+ size_t size ;
758802 ze_ipc_mem_handle_t ze_handle ;
759803} ze_ipc_data_t ;
760804
@@ -770,20 +814,51 @@ static umf_result_t ze_memory_provider_get_ipc_handle(void *provider,
770814 const void * ptr ,
771815 size_t size ,
772816 void * providerIpcData ) {
773- (void )size ;
774-
775817 ze_result_t ze_result ;
776818 ze_ipc_data_t * ze_ipc_data = (ze_ipc_data_t * )providerIpcData ;
777819 struct ze_memory_provider_t * ze_provider =
778820 (struct ze_memory_provider_t * )provider ;
779821
780- ze_result = g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr ,
781- & ze_ipc_data -> ze_handle );
782- if (ze_result != ZE_RESULT_SUCCESS ) {
783- LOG_ERR ("zeMemGetIpcHandle() failed." );
784- return ze2umf_result (ze_result );
822+ if (ze_provider -> exchangePolicy ==
823+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
824+ ze_result = g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr ,
825+ & ze_ipc_data -> ze_handle );
826+
827+ if (ze_result != ZE_RESULT_SUCCESS ) {
828+ LOG_ERR ("zeMemGetIpcHandle() failed." );
829+ return ze2umf_result (ze_result );
830+ }
831+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
832+ ze_external_memory_export_fd_t fd_desc = {
833+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD ,
834+ .pNext = NULL ,
835+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 ,
836+ .fd = 0 };
837+
838+ ze_memory_allocation_properties_t mem_alloc_props = {
839+ .stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES ,
840+ .pNext = & fd_desc ,
841+ .type = 0 ,
842+ .id = 0 ,
843+ .pageSize = 0 };
844+
845+ ze_result = g_ze_ops .zeMemGetAllocProperties (ze_provider -> context , ptr ,
846+ & mem_alloc_props , NULL );
847+ if (ze_result != ZE_RESULT_SUCCESS ) {
848+ LOG_ERR ("zeMemGetAllocProperties() failed." );
849+ return ze2umf_result (ze_result );
850+ }
851+
852+ memcpy (& ze_ipc_data -> ze_handle , & fd_desc .fd , sizeof (fd_desc .fd ));
853+ //LOG_ERR("ptr is %p", ptr);
854+ //LOG_ERR("context is %p, device is %p", ze_provider->context,
855+ // ze_provider->device);
856+ // LOG_ERR("Exporting file descriptor %d", fd_desc.fd);
857+ // LOG_ERR("size is %zu", size);
858+ // LOG_ERR("pid: %d", utils_getpid());
785859 }
786860
861+ ze_ipc_data -> size = size ;
787862 ze_ipc_data -> pid = utils_getpid ();
788863
789864 return UMF_RESULT_SUCCESS ;
@@ -831,17 +906,44 @@ static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
831906 LOG_PERR ("duplicating file descriptor failed" );
832907 return umf_result ;
833908 }
909+ LOG_ERR ("Duplicated fd %d to fd %d" , fd_remote , fd_local );
834910 memcpy (& ze_ipc_handle , & fd_local , sizeof (fd_local ));
835911 }
836912
837- ze_result = g_ze_ops .zeMemOpenIpcHandle (
838- ze_provider -> context , ze_provider -> device , ze_ipc_handle , 0 , ptr );
839- if (fd_local != -1 ) {
840- (void )utils_close_fd (fd_local );
841- }
842- if (ze_result != ZE_RESULT_SUCCESS ) {
843- LOG_ERR ("zeMemOpenIpcHandle() failed." );
844- return ze2umf_result (ze_result );
913+ if (ze_provider -> exchangePolicy ==
914+ UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IPC ) {
915+ ze_result = g_ze_ops .zeMemOpenIpcHandle (
916+ ze_provider -> context , ze_provider -> device , ze_ipc_handle , 0 , ptr );
917+ if (fd_local != -1 ) {
918+ (void )utils_close_fd (fd_local );
919+ }
920+ if (ze_result != ZE_RESULT_SUCCESS ) {
921+ LOG_ERR ("zeMemOpenIpcHandle() failed." );
922+ return ze2umf_result (ze_result );
923+ }
924+ } else { // UMF_LEVEL_ZERO_MEMORY_PROVIDER_MEMORY_EXCHANGE_POLICY_IMPORT_EXPORT
925+ ze_external_memory_import_fd_t import_fd = {
926+ .stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD ,
927+ .pNext = NULL ,
928+ .flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF ,
929+ .fd = fd_local };
930+
931+ ze_device_mem_alloc_desc_t alloc_desc = {
932+ .stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC ,
933+ .pNext = & import_fd ,
934+ .flags = 0 ,
935+ .ordinal = 0 };
936+ ze_result = g_ze_ops .zeMemAllocDevice (ze_provider -> context , & alloc_desc ,
937+ ze_ipc_data -> size , 0 ,
938+ ze_provider -> device , ptr );
939+ if (ze_result != ZE_RESULT_SUCCESS ) {
940+ LOG_ERR ("zeMemAllocDevice() failed." );
941+ return ze2umf_result (ze_result );
942+ }
943+
944+ if (fd_local != -1 ) {
945+ (void )utils_close_fd (fd_local );
946+ }
845947 }
846948
847949 return UMF_RESULT_SUCCESS ;
@@ -1027,6 +1129,14 @@ umf_result_t umfLevelZeroMemoryProviderParamsSetFreePolicy(
10271129 return UMF_RESULT_ERROR_NOT_SUPPORTED ;
10281130}
10291131
1132+ umf_result_t umfLevelZeroMemoryProviderParamsSetMemoryExchangePolicy (
1133+ umf_level_zero_memory_provider_params_handle_t hParams ,
1134+ umf_level_zero_memory_provider_memory_exchange_policy_t policy ) {
1135+ (void )hParams ;
1136+ (void )policy ;
1137+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
1138+ }
1139+
10301140umf_result_t umfLevelZeroMemoryProviderParamsSetDeviceOrdinal (
10311141 umf_level_zero_memory_provider_params_handle_t hParams ,
10321142 uint32_t deviceOrdinal ) {
0 commit comments