3030from __future__ import annotations
3131
3232import os
33- import sys
3433import time
3534
3635from cuda .bindings import driver
3736
38- if sys .platform == "win32" :
39- from helpers import win_address_space
40- else :
41- # No Linux counterpart on purpose; see helpers/win_address_space.py.
42- win_address_space = None
43-
44- # Holes smaller than this are noise in the layout dump.
45- LAYOUT_MIN_HOLE = 1024 * 1024 * 1024
46- LAYOUT_MAX_HOLES = 6
47-
4837MIB = 1024 * 1024
4938GIB = 1024 * MIB
5039
@@ -141,44 +130,6 @@ def format_bytes(value: int | None) -> str:
141130 return f"{ value / GIB :.2f} GiB"
142131
143132
144- def free_holes () -> list [tuple [int , int ]] | None :
145- """Unallocated holes as ``(size, base)``, largest first. None off Windows."""
146- if win_address_space is None :
147- return None
148- return win_address_space .free_regions (LAYOUT_MIN_HOLE )
149-
150-
151- def pool_capacity (holes , pool_bytes ) -> int | None :
152- """How many driver pools the free holes could hold between them.
153-
154- This is the number that decides the outcome, and it is neither the largest
155- hole nor the count of holes that clear one pool. A reservation has to fit
156- within a single hole, but a hole twice the size takes two -- the driver
157- packs them from its low end, so a lone 800 GiB hole hosts both pools just
158- as well as two 400 GiB ones. Summing each hole's capacity covers both.
159- """
160- if holes is None or not pool_bytes :
161- return None
162- return sum (size // pool_bytes for size , _base in holes )
163-
164-
165- def layout_lines (holes , pool_bytes , label , detail : bool = True ) -> list [str ]:
166- """Render the hole structure. Base addresses show whether it is randomized."""
167- if holes is None :
168- return []
169- capacity = pool_capacity (holes , pool_bytes )
170- headline = f"free holes { label } : { len (holes )} >= { format_bytes (LAYOUT_MIN_HOLE )} "
171- if capacity is not None :
172- headline += f", room for { capacity } pool(s) of { format_bytes (pool_bytes )} "
173- out = [headline ]
174- if detail :
175- for size , base in holes [:LAYOUT_MAX_HOLES ]:
176- out .append (f" { format_bytes (size ):>14} @ { base :#018x} " )
177- if len (holes ) > LAYOUT_MAX_HOLES :
178- out .append (f" ... and { len (holes ) - LAYOUT_MAX_HOLES } smaller" )
179- return out
180-
181-
182133class Reservation :
183134 """One driver-managed pool that has to be materialized."""
184135
@@ -260,16 +211,7 @@ class ReservationReport:
260211 """What the early reservations cost, for the terminal."""
261212
262213 def __init__ (
263- self ,
264- device_name ,
265- device_memory ,
266- before ,
267- after ,
268- reservations ,
269- measured ,
270- seconds = 0.0 ,
271- unsupported = False ,
272- holes_before = None ,
214+ self , device_name , device_memory , before , after , reservations , measured , seconds = 0.0 , unsupported = False
273215 ):
274216 self .device_name = device_name
275217 self .device_memory = device_memory
@@ -279,7 +221,6 @@ def __init__(
279221 self .measured = measured
280222 self .seconds = seconds
281223 self .unsupported = unsupported
282- self .holes_before = holes_before
283224
284225 @property
285226 def failed (self ) -> list [Reservation ]:
@@ -310,24 +251,13 @@ def lines(self) -> list[str]:
310251 # carve its reservations out of a region other than the largest
311252 # hole, in which case the largest hole does not move at all.
312253 change = None if self .before is None or self .after is None else self .before - self .after
313- if change is None :
314- note = ""
315- elif change > 0 :
316- note = f" (largest hole shrank by { format_bytes (change )} )"
317- else :
318- note = " (largest hole unchanged)"
319- out .append (f"largest reservable range after: { format_bytes (self .after )} { note } " )
254+ out .append (f"largest reservable range after: { format_bytes (self .after )} " )
320255 pool_bytes = self .pool_reservation_bytes
321256 if pool_bytes and self .after is not None :
322257 out .append (
323258 f"remaining headroom: { self .after // pool_bytes } more pool-sized "
324259 f"({ format_bytes (pool_bytes )} ) reservations [{ self .seconds :.1f} s measuring]"
325260 )
326- # Just the counts here. They are what makes a successful session
327- # comparable with a failed one, since the hole count is what decides the
328- # outcome. The addresses behind them are only worth printing when a
329- # reservation is actually refused; see build_failure_message.
330- out += layout_lines (self .holes_before , self .pool_reservation_bytes , "at session start" , detail = False )
331261 return out
332262
333263
@@ -349,14 +279,6 @@ def build_failure_message(report: ReservationReport) -> str:
349279 for item in report .failed :
350280 lines .append (f" { item .name } ({ item .detail } ): { item .error } " )
351281
352- # Each pool needs a hole of its own, so the hole structure -- not the total
353- # free -- is what decides this. Included here because it is the first thing
354- # anyone diagnosing a refusal will want.
355- layout = layout_lines (report .holes_before , pool_bytes , "at session start" )
356- if layout :
357- lines .append ("" )
358- lines += [f" { line } " for line in layout ]
359-
360282 return "\n " .join (lines )
361283
362284
@@ -379,7 +301,6 @@ def reserve_driver_pools(device, measure: bool = True) -> ReservationReport:
379301 started = time .perf_counter ()
380302 before = largest_reservable () if measured else None
381303 elapsed = time .perf_counter () - started
382- holes_before = free_holes ()
383304
384305 reservations = reservations_for (device )
385306 for item in reservations :
@@ -388,13 +309,4 @@ def reserve_driver_pools(device, measure: bool = True) -> ReservationReport:
388309 started = time .perf_counter ()
389310 after = largest_reservable () if measured else None
390311 elapsed += time .perf_counter () - started
391- return ReservationReport (
392- device .name ,
393- device_memory ,
394- before ,
395- after ,
396- reservations ,
397- measured ,
398- elapsed ,
399- holes_before = holes_before ,
400- )
312+ return ReservationReport (device .name , device_memory , before , after , reservations , measured , elapsed )
0 commit comments