"""Validate the cmd 0x0d accept/reject timing separation. Interleaved A/B so clock drift and USB jitter hit both arms equally. """ import ctypes, time, statistics from tinygrad import Device from tinygrad.runtime.autogen.am import am d = Device["AMD"]; adev = d.iface.dev_impl; psp = adev.psp SZ = ctypes.sizeof(am.struct_psp_gfx_cmd_resp); C = 28 def timed(cid, words): adev.vram.view(psp.cmd_paddr, SZ)[:] = b"\x00" * SZ c = am.struct_psp_gfx_cmd_resp(cmd_id=cid) buf = bytearray(memoryview(c).cast('B')) for i, v in words.items(): buf[C+i*4:C+4+i*4] = int(v & 0xFFFFFFFF).to_bytes(4, 'little') cmd = am.struct_psp_gfx_cmd_resp.from_buffer_copy(bytes(buf)) t0 = time.perf_counter() try: psp._ring_submit(cmd) except Exception: pass return (time.perf_counter() - t0) * 1e3 N = 120 A, B = [], [] for _ in range(6): timed(0x7e, {}) for i in range(N): A.append(timed(0x0d, {0: 3, 1: 0, 2: 1})) # ACCEPT B.append(timed(0x0d, {0: 0xF})) # REJECT def stats(x): return statistics.median(x), statistics.mean(x), statistics.pstdev(x) ma, aa, sa = stats(A); mb, ab, sb = stats(B) print(f" ACCEPT (idx=3): median={ma:.3f} mean={aa:.3f} sd={sa:.3f} n={N}") print(f" REJECT (idx=0xF): median={mb:.3f} mean={ab:.3f} sd={sb:.3f} n={N}") print(f" median separation: {ma-mb:+.3f} ms") # Mann-Whitney U via rank sum (no scipy) comb = sorted([(v,0) for v in A] + [(v,1) for v in B]) ranks = {} i = 0 rsum = 0.0 while i < len(comb): j = i while j+1 < len(comb) and comb[j+1][0] == comb[i][0]: j += 1 r = (i+j)/2.0 + 1 for k in range(i, j+1): if comb[k][1] == 0: rsum += r i = j+1 n1 = n2 = N U = rsum - n1*(n1+1)/2 mu = n1*n2/2 sd = (n1*n2*(n1+n2+1)/12) ** 0.5 z = (U-mu)/sd print(f" Mann-Whitney U={U:.0f} z={z:+.2f} (|z|>3 => clearly separable)") # how well does a single sample classify? thr = (ma+mb)/2 acc = (sum(1 for v in A if v > thr) + sum(1 for v in B if v <= thr)) / (2*N) print(f" single-sample classification accuracy at threshold {thr:.3f} ms: {100*acc:.1f}%") print("\nsOS alive:", psp.is_sos_alive())