@@ -3117,32 +3117,98 @@ def test_vmm_options_handle_type_win32_raises():
31173117
31183118
31193119@pytest .mark .agent_authored (model = "claude-fable-5-1" )
3120- @pytest .mark .parametrize ("location_type" , ["host" , "host_numa" , "host_numa_current" ])
3120+ @pytest .mark .parametrize ("location_type" , ["host" , "host_numa" ])
31213121def test_vmm_host_location_types_report_host_accessible (init_cuda , location_type ):
31223122 """Every host-backed location type reports is_host_accessible; only "host" needs handle_type=None.
31233123
3124- __init__ classifies "host", "host_numa" and "host_numa_current " alike when
3124+ __init__ classifies "host" and "host_numa " alike when
31253125 deciding the resource is not bound to a device, so is_host_accessible must
31263126 agree; otherwise a NUMA-located resource claims to be neither host- nor
31273127 device-accessible. The driver rejects an exportable handle type for HOST
31283128 memory only, so the default handle type is rejected at construction for
3129- "host" and accepted for the NUMA location types .
3129+ "host" and accepted for "host_numa" .
31303130 """
31313131 device = Device ()
31323132 device .set_current ()
3133+ numa = {"numa_id" : 0 } if location_type == "host_numa" else {}
31333134 if location_type == "host" :
31343135 with pytest .raises (ValueError , match = "handle_type=None" ):
31353136 VirtualMemoryResource (device , config = VirtualMemoryResourceOptions (location_type = location_type ))
31363137 else :
3137- VirtualMemoryResource (device , config = VirtualMemoryResourceOptions (location_type = location_type ))
3138+ VirtualMemoryResource (device , config = VirtualMemoryResourceOptions (location_type = location_type , ** numa ))
31383139 mr = VirtualMemoryResource (
3139- device , config = VirtualMemoryResourceOptions (location_type = location_type , handle_type = None )
3140+ device , config = VirtualMemoryResourceOptions (location_type = location_type , handle_type = None , ** numa )
31403141 )
31413142 assert mr .device is None
31423143 assert mr .is_host_accessible is True
31433144 assert mr .device_id == - 1
31443145
31453146
3147+ @pytest .mark .thread_unsafe (reason = "records process-global warnings" )
3148+ @pytest .mark .agent_authored (model = "claude-opus-5-5" )
3149+ def test_vmm_host_numa_allocates_and_copies (init_cuda ):
3150+ """A "host_numa" resource allocates on its NUMA node, and the host can use the memory.
3151+
3152+ The driver rejects CU_MEM_LOCATION_TYPE_HOST_NUMA with location id -1, so
3153+ the allocation works only if numa_id reaches the allocation properties
3154+ (#2694). The resource grants access to its own location only, so the data
3155+ goes through the host. A per-call config cannot move the buffer to another
3156+ node.
3157+ """
3158+ device = Device ()
3159+ device .set_current ()
3160+ props = device .properties
3161+ if not props .host_numa_virtual_memory_management_supported :
3162+ pytest .skip ("Host NUMA virtual memory management is not supported on this device" )
3163+ if props .host_numa_id < 0 :
3164+ pytest .skip ("The system reports no host NUMA node" )
3165+ mr = VirtualMemoryResource (
3166+ device ,
3167+ config = VirtualMemoryResourceOptions (location_type = "host_numa" , numa_id = props .host_numa_id , handle_type = None ),
3168+ )
3169+ with assert_no_cuda_warning ():
3170+ buf = mr .allocate (4096 )
3171+ try :
3172+ assert buf .is_host_accessible
3173+ ctypes .memset (int (buf .handle ), 0xAB , buf .size )
3174+ assert ctypes .string_at (int (buf .handle ), buf .size ) == b"\xab " * buf .size
3175+ other_node = VirtualMemoryResourceOptions (
3176+ location_type = "host_numa" , numa_id = props .host_numa_id + 1 , handle_type = None
3177+ )
3178+ with pytest .raises (ValueError , match = "config.numa_id" ):
3179+ mr .modify_allocation (buf , 2 * buf .size , other_node )
3180+ finally :
3181+ buf .close ()
3182+
3183+
3184+ @pytest .mark .agent_authored (model = "claude-opus-5-5" )
3185+ def test_vmm_host_numa_current_rejected (init_cuda ):
3186+ """The driver does not accept "host_numa_current" for physical allocations, so construction rejects it."""
3187+ device = Device ()
3188+ device .set_current ()
3189+ with pytest .raises (ValueError , match = "does not accept it for physical allocations" ):
3190+ VirtualMemoryResource (
3191+ device , config = VirtualMemoryResourceOptions (location_type = "host_numa_current" , handle_type = None )
3192+ )
3193+
3194+
3195+ @pytest .mark .agent_authored (model = "claude-opus-5-5" )
3196+ @pytest .mark .parametrize (
3197+ ("options" , "match" ),
3198+ [
3199+ pytest .param ({"location_type" : "host_numa" }, "requires numa_id" , id = "host_numa-missing" ),
3200+ pytest .param ({"location_type" : "host_numa" , "numa_id" : - 1 }, "numa_id must be >= 0" , id = "host_numa-negative" ),
3201+ pytest .param ({"location_type" : "host" , "numa_id" : 0 }, "only valid with" , id = "host-misplaced" ),
3202+ pytest .param ({"location_type" : "device" , "numa_id" : 0 }, "only valid with" , id = "device-misplaced" ),
3203+ ],
3204+ )
3205+ def test_vmm_numa_id_validation (init_cuda , options , match ):
3206+ """numa_id is required for "host_numa", must be non-negative, and is rejected for other location types."""
3207+ device = _vmm_device_or_skip ()
3208+ with pytest .raises (ValueError , match = match ):
3209+ VirtualMemoryResource (device , config = VirtualMemoryResourceOptions (handle_type = None , ** options ))
3210+
3211+
31463212def test_device_memory_resource_peer_accessible_by_non_owned (mempool_device ):
31473213 """peer_accessible_by on a non-owned (default) DMR queries the driver live."""
31483214 dev = mempool_device
0 commit comments