Skip to content

Commit 07c6511

Browse files
committed
xbar5090 0.2.2 update: src/xbar5090/l2test.py
1 parent ef300e4 commit 07c6511

1 file changed

Lines changed: 43 additions & 4 deletions

File tree

‎src/xbar5090/l2test.py‎

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@ def _get_new_nvlddmkm(start_local_str: str) -> list[str]:
3737
return ["<event query failed: %s>" % e]
3838

3939

40-
def _run_round(mode: str, blocks: int, threads: int, stress_iters: int) -> dict:
40+
def _run_round(mode: str, blocks: int, threads: int, stress_iters: int, mb: int = 32) -> dict:
4141
exe = _checker_path()
4242
if not os.path.exists(exe):
4343
return {"error": f"L2 checker not found: {exe}"}
44-
cmd = [exe, "--blocks", str(blocks), "--threads", str(threads), "--rounds", "1", "--mode", mode]
44+
cmd = [exe, "--blocks", str(blocks), "--threads", str(threads), "--rounds", "1",
45+
"--mode", mode, "--mb", str(mb)]
4546
if mode == "load":
4647
cmd += ["--stress-iters", str(stress_iters)]
4748
try:
@@ -55,6 +56,31 @@ def _run_round(mode: str, blocks: int, threads: int, stress_iters: int) -> dict:
5556
return {"errors": int(m.group(1)), "elapsed_ms": float(m.group(2))}
5657

5758

59+
def _diagnose_cuda() -> None:
60+
"""Print CUDA/driver/memory diagnostics that help explain checker failures."""
61+
try:
62+
r = subprocess.run(
63+
["nvidia-smi", "--query-gpu=name,driver_version,memory.total,memory.used",
64+
"--format=csv,noheader,nounits"],
65+
capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=15,
66+
)
67+
if r.returncode == 0 and r.stdout.strip():
68+
print("nvidia-smi:", r.stdout.strip())
69+
else:
70+
print("nvidia-smi: unavailable", file=sys.stderr)
71+
except Exception as e:
72+
print(f"nvidia-smi: unavailable ({e})", file=sys.stderr)
73+
74+
75+
def _auto_select_mb(stress_iters: int) -> int | None:
76+
"""Find the largest checker buffer that can be allocated on this system."""
77+
for mb in (32, 16, 8, 4, 2):
78+
row = _run_round("idle", 1, 1, stress_iters, mb=mb)
79+
if "error" not in row:
80+
return mb
81+
return None
82+
83+
5884
def _gpu_blocks() -> int:
5985
"""Pick a heuristic block count for the detected RTX 50-series GPU.
6086
@@ -98,19 +124,30 @@ def _gpu_blocks() -> int:
98124

99125
def run_l2_test(blocks: int | None = None, threads: int = 256,
100126
stress_iters: int = 100000,
101-
idle_rounds: int = 3, load_rounds: int = 3) -> bool:
127+
idle_rounds: int = 3, load_rounds: int = 3,
128+
mb: int | None = None) -> bool:
102129
"""Run the L2 integrity test. Returns True only if all rounds pass."""
103130
if blocks is None:
104131
blocks = _gpu_blocks()
105132
print("=== XBAR L2 stability test ===")
106133
print("Using checker:", _checker_path())
107134
print(f"Using blocks={blocks} threads={threads} (auto-selected if not specified)")
135+
if mb is None:
136+
mb = _auto_select_mb(stress_iters)
137+
if mb is None:
138+
print("ERROR: could not allocate even a 2 MiB CUDA buffer.", file=sys.stderr)
139+
_diagnose_cuda()
140+
print("RESULT: FAIL")
141+
return False
142+
print(f"Auto-selected checker buffer: {mb} MiB")
143+
else:
144+
print(f"Using checker buffer: {mb} MiB")
108145
start_local = time.strftime("%Y-%m-%dT%H:%M:%S")
109146
all_ok = True
110147
errors_total = 0
111148
for mode, rounds in (("idle", idle_rounds), ("load", load_rounds)):
112149
for i in range(rounds):
113-
row = _run_round(mode, blocks, threads, stress_iters)
150+
row = _run_round(mode, blocks, threads, stress_iters, mb=mb)
114151
if "error" in row:
115152
print(f" round {i+1} {mode}: ERROR {row['error']}")
116153
all_ok = False
@@ -126,5 +163,7 @@ def run_l2_test(blocks: int | None = None, threads: int = 256,
126163
if new_events:
127164
all_ok = False
128165
print("Total L2 errors:", errors_total)
166+
if not all_ok:
167+
_diagnose_cuda()
129168
print("RESULT:", "PASS" if all_ok else "FAIL")
130169
return all_ok

0 commit comments

Comments
 (0)