Files

85 lines
5.2 KiB
Python

"""Independent file-level exact gate; no reliance on a stored backend PASS."""
import argparse
import csv
import hashlib
import json
import numpy as np
from context import EXP,CFG,check,save,digest
def jsonl(path):
with path.open() as f: return [json.loads(line) for line in f if line.strip()]
def bit_equal(a,b):
return a.shape==b.shape and a.dtype==b.dtype and np.array_equal(np.ascontiguousarray(a).view(np.uint8),np.ascontiguousarray(b).view(np.uint8))
def evaluate(name):
spec=json.loads((EXP/'cases'/name/'spec.json').read_text());steps=spec['steps'];n=CFG['neurons']
cpu=EXP/'oracle'/name;gpu=EXP/'gpu'/name;checks={};details={}
arrays={key:np.load(cpu/filename,mmap_mode='r') for key,filename in (
('v','v-history.float64.npy'),('g','g-history.float64.npy'),('ref','ref-history.int32.npy'))}
expected={'v':np.dtype('float64'),'g':np.dtype('float64'),'ref':np.dtype('int32')}
checks['history_shapes_dtypes']=all(x.shape==(steps,n) and x.dtype==expected[k] for k,x in arrays.items())
assert checks['history_shapes_dtypes']
hashes=jsonl(gpu/'tick-state-hashes.jsonl')
checks['gpu_state_hash_coverage']=len(hashes)==steps and [x['tick'] for x in hashes]==list(range(steps))
assert checks['gpu_state_hash_coverage']
failures=[];finite=True
for tick,row in enumerate(hashes):
for key,value in arrays.items():
a=np.ascontiguousarray(value[tick]);sha=hashlib.sha256(a.tobytes()).hexdigest()
if sha!=row[key+'_sha256']:failures.append(dict(tick=tick,field=key))
if key!='ref' and not np.isfinite(a).all():finite=False
checks['all_tick_raw_state_hashes_exact']=not failures;checks['all_oracle_states_finite']=finite
details['first_hash_mismatches']=failures[:10]
with np.load(cpu/'state.npz',allow_pickle=False) as a,np.load(gpu/'state.npz',allow_pickle=False) as b:
for key in ('step','neuron_idx','counts','v','g','ref'):
checks['exact_'+key]=bit_equal(a[key],b[key])
checks['event_clock_range']=bool(np.all((a['step']>=0)&(a['step']<steps)))
checks['event_neuron_range']=bool(np.all((a['neuron_idx']>=0)&(a['neuron_idx']<n)))
checks['event_sort']=np.array_equal(np.lexsort((a['neuron_idx'],a['step'])),np.arange(len(a['step'])))
checks['event_unique']=len(np.unique(a['step'].astype(np.int64)*n+a['neuron_idx']))==len(a['step'])
checks['cpu_event_counts']=np.array_equal(np.bincount(a['neuron_idx'],minlength=n),a['counts'])
checks['gpu_event_counts']=np.array_equal(np.bincount(b['neuron_idx'],minlength=n),b['counts'])
for key in arrays:checks['cpu_final_'+key]=bit_equal(arrays[key][-1],a[key])
details.update(events=len(a['step']),active_neurons=int(np.count_nonzero(a['counts'])),
max_per_neuron_count=int(a['counts'].max()),
mean_rate_hz=float(len(a['step'])/(n*spec['duration_ms']/1000)),
first_event_step=None if not len(a['step']) else int(a['step'][0]))
ptr=np.load(EXP/'graph/ptr.npy',mmap_mode='r');degrees=np.diff(ptr)
expected_arrivals=np.zeros(steps,np.int64);due=a['step'].astype(np.int64)+18
valid=due<steps
np.add.at(expected_arrivals,due[valid],degrees[a['neuron_idx'][valid]])
cq,gq=jsonl(cpu/'queue.jsonl'),jsonl(gpu/'queue.jsonl')
checks['queue_coverage']=len(cq)==len(gq)==steps and [r['tick'] for r in cq]==list(range(steps))
checks['queue_original_order_exact']=cq==gq
checks['all_presynaptic_edges_due']=np.array_equal(expected_arrivals,np.asarray([r['count'] for r in cq],np.int64))
with (cpu/'requests.csv').open(newline='') as f:cr=list(csv.DictReader(f))
with (gpu/'requests.csv').open(newline='') as f:gr=list(csv.DictReader(f))
checks['request_rows_exact']=cr==gr
checks['request_count']=len(cr)==len(spec['seed_nodes'])
checks['actual_requests_match_protocol']=cr==[
dict(tick='0',neuron_idx=str(node),attempted='1',accepted='1',rejected='0')
for node in sorted(spec['seed_nodes'])]
details['request_rows']=cr
if cq:
details['queue_fields']=list(cq[0])
details['arrival_count']=sum(r['count'] for r in cq)
details['accepted_arrival_count']=sum(r['accepted_count'] for r in cq)
summary=json.loads((gpu/'summary.json').read_text())
checks['backend_summary_pass']=summary['pass_all'] is True
oracle_summary=json.loads((cpu/'summary.json').read_text())
checks['oracle_complete']=oracle_summary['complete'] is True and oracle_summary['steps']==steps and oracle_summary['nodes']==n and oracle_summary['edges']==CFG['edges']
checks={k:bool(v) for k,v in checks.items()}
files=[cpu/'state.npz',gpu/'state.npz',cpu/'queue.jsonl',gpu/'queue.jsonl',gpu/'tick-state-hashes.jsonl']
return dict(case=name,pass_all=all(checks.values()),checks=checks,details=details,
evidence_sha256={str(p.relative_to(EXP)):digest(p) for p in files})
def main():
ap=argparse.ArgumentParser();ap.add_argument('case');a=ap.parse_args();check()
assert a.case in [t['name'] for t in CFG['trials']]
result=evaluate(a.case);save(EXP/'audit'/('completed-'+a.case+'.json'),result)
print(json.dumps(result,ensure_ascii=False),flush=True)
if not result['pass_all']:raise SystemExit(1)
if __name__=='__main__':main()