1818 BaseDriver ,
1919 DriverError ,
2020 DriverNotSupported ,
21+ ExportableMemory ,
2122 LocalAllocation ,
23+ MappingPlacement ,
2224 PeerMapping ,
2325)
2426from iris .host .distributed .topology import InterconnectLevel
@@ -339,20 +341,15 @@ def _check_initialized(self) -> None:
339341 def allocate_exportable (
340342 self ,
341343 size : int ,
342- va : Optional [int ] = None ,
343- * ,
344- access_va : Optional [int ] = None ,
345- access_size : Optional [int ] = None ,
344+ placement : Optional [MappingPlacement ] = None ,
346345 ) -> LocalAllocation :
347346 self ._check_initialized ()
348- if (access_va is None ) != (access_size is None ):
349- raise CudaFabricError ("access_va and access_size must be provided together" )
350347 props = self ._make_alloc_props ()
351348 granularity = self ._get_granularity ()
352349 alloc_size = _round_up (size , granularity )
353350
354- reserved_va = va is None
355- mapped_va = int (va ) if va is not None else 0
351+ reserved_va = placement is None
352+ mapped_va = int (placement . va ) if placement is not None else 0
356353 handle = ctypes .c_uint64 ()
357354 mapped = False
358355
@@ -373,10 +370,10 @@ def allocate_exportable(
373370 "cuMemMap" ,
374371 )
375372 mapped = True
376- self ._mem_set_access (
377- int (access_va ) if access_va is not None else mapped_va ,
378- int (access_size ) if access_size is not None else alloc_size ,
373+ access_base , access_bytes = (
374+ placement .access_range (alloc_size ) if placement is not None else (mapped_va , alloc_size )
379375 )
376+ self ._mem_set_access (access_base , access_bytes )
380377 return LocalAllocation (
381378 va = mapped_va ,
382379 size = alloc_size ,
@@ -404,13 +401,16 @@ def allocate_exportable(
404401 pass
405402 raise
406403
407- def export_handle (self , allocation : LocalAllocation ) -> bytes :
404+ def export_handle (self , memory : ExportableMemory ) -> bytes :
408405 self ._check_initialized ()
406+ if memory .allocation is None :
407+ raise CudaFabricNotSupported ("NVIDIA fabric driver can only export driver-created VMM allocations" )
408+
409409 raw = (ctypes .c_ubyte * FABRIC_HANDLE_BYTES )()
410410 _cuda_try (
411411 _cuda_driver .cuMemExportToShareableHandle (
412412 ctypes .byref (raw ),
413- int (allocation .handle ),
413+ int (memory . allocation .handle ),
414414 _CU_MEM_HANDLE_TYPE_FABRIC ,
415415 0 ,
416416 ),
@@ -437,19 +437,14 @@ def import_and_map(
437437 peer_rank : int ,
438438 handle_bytes : bytes ,
439439 size : int ,
440- va : Optional [int ] = None ,
441- * ,
442- access_va : Optional [int ] = None ,
443- access_size : Optional [int ] = None ,
440+ placement : Optional [MappingPlacement ] = None ,
444441 ) -> PeerMapping :
445442 self ._check_initialized ()
446- if (access_va is None ) != (access_size is None ):
447- raise CudaFabricError ("access_va and access_size must be provided together" )
448443 imported_handle = self ._import_handle (handle_bytes )
449444
450445 granularity = self ._get_granularity ()
451- va_owned = va is None
452- mapped_va = int (va ) if va is not None else 0
446+ va_owned = placement is None
447+ mapped_va = int (placement . va ) if placement is not None else 0
453448 mapped = False
454449 try :
455450 if va_owned :
@@ -464,10 +459,8 @@ def import_and_map(
464459 "cuMemMap" ,
465460 )
466461 mapped = True
467- self ._mem_set_access (
468- int (access_va ) if access_va is not None else mapped_va ,
469- int (access_size ) if access_size is not None else size ,
470- )
462+ access_base , access_bytes = placement .access_range (size ) if placement is not None else (mapped_va , size )
463+ self ._mem_set_access (access_base , access_bytes )
471464 except Exception :
472465 if mapped :
473466 try :
@@ -497,7 +490,16 @@ def import_and_map(
497490 _driver_handle = (tag , imported_handle ),
498491 )
499492
500- def cleanup_import (self , mapping : PeerMapping ) -> None :
493+ def cleanup (self , target : LocalAllocation | PeerMapping ) -> None :
494+ if isinstance (target , LocalAllocation ):
495+ self ._cleanup_local (target )
496+ return
497+ if isinstance (target , PeerMapping ):
498+ self ._cleanup_import (target )
499+ return
500+ raise CudaFabricError (f"Unsupported cleanup target: { type (target ).__name__ } " )
501+
502+ def _cleanup_import (self , mapping : PeerMapping ) -> None :
501503 self ._check_initialized ()
502504 if isinstance (mapping ._driver_handle , tuple ) and len (mapping ._driver_handle ) == 2 :
503505 tag , imported_handle = mapping ._driver_handle
@@ -533,7 +535,7 @@ def cleanup_import(self, mapping: PeerMapping) -> None:
533535 )
534536 _run_cleanup_steps (* steps )
535537
536- def cleanup_local (self , allocation : LocalAllocation ) -> None :
538+ def _cleanup_local (self , allocation : LocalAllocation ) -> None :
537539 self ._check_initialized ()
538540 steps = [
539541 (
0 commit comments