@@ -210,14 +210,17 @@ def reservations_for(device) -> list[Reservation]:
210210class ReservationReport :
211211 """What the early reservations cost, for the terminal."""
212212
213- def __init__ (self , device_name , device_memory , before , after , reservations , measured , seconds = 0.0 ):
213+ def __init__ (
214+ self , device_name , device_memory , before , after , reservations , measured , seconds = 0.0 , unsupported = False
215+ ):
214216 self .device_name = device_name
215217 self .device_memory = device_memory
216218 self .before = before
217219 self .after = after
218220 self .reservations = reservations
219221 self .measured = measured
220222 self .seconds = seconds
223+ self .unsupported = unsupported
221224
222225 @property
223226 def failed (self ) -> list [Reservation ]:
@@ -231,6 +234,9 @@ def pool_reservation_bytes(self) -> int | None:
231234
232235 def lines (self ) -> list [str ]:
233236 out = [f"device 0: { self .device_name } ({ format_bytes (self .device_memory )} device memory)" ]
237+ if self .unsupported :
238+ out .append ("device does not support memory pools; nothing to reserve" )
239+ return out
234240 if self .measured :
235241 out .append (f"largest reservable range before: { format_bytes (self .before )} " )
236242 else :
@@ -278,32 +284,25 @@ def build_failure_message(report: ReservationReport) -> str:
278284 ]
279285 for item in report .failed :
280286 lines .append (f" { item .name } ({ item .detail } ): { item .error } " )
281- lines += [
282- "" ,
283- "The driver keeps two pools per device -- the default memory pool and the graph" ,
284- "memory pool -- and reserves roughly twice the installed device memory of address" ,
285- "space for each one the first time it is used. Neither reservation can be capped," ,
286- "and neither is released before the process exits. On a large-memory GPU with a" ,
287- "bounded per-process address space the two together can exceed the budget, and no" ,
288- "amount of freeing device memory helps: the exhausted resource is address space," ,
289- "not memory. Expect cuMemGetInfo to report plenty free while this fails." ,
290- "" ,
291- "Options: run on a device with less memory, run the graph tests in a separate" ,
292- "process from the rest of the suite so the two reservations never coexist, or on" ,
293- "Windows check whether the driver model (WDDM/MCDM/TCC) bounds the address space" ,
294- "more tightly than expected. See issue #2381." ,
295- "" ,
296- ]
287+
297288 return "\n " .join (lines )
298289
299290
300291def reserve_driver_pools (device , measure : bool = True ) -> ReservationReport :
301- """Materialize both driver-managed pools, measuring address space around them."""
292+ """Materialize both driver-managed pools, measuring address space around them.
293+
294+ Both pools require mempool support, so on a device without it there is
295+ nothing to reserve and nothing to pre-empt. Skip rather than fail: the tests
296+ that need pools skip themselves on such a device, and the rest still run.
297+ """
302298 device_memory = None
303299 err , _free , total = driver .cuMemGetInfo ()
304300 if err == driver .CUresult .CUDA_SUCCESS :
305301 device_memory = int (total )
306302
303+ if not device .properties .memory_pools_supported :
304+ return ReservationReport (device .name , device_memory , None , None , [], measured = False , unsupported = True )
305+
307306 measured = measure and vmm_supported (device .device_id )
308307 started = time .perf_counter ()
309308 before = largest_reservable () if measured else None
0 commit comments