"""CPU-only read-only baseline and one predeclared conditional sensitivity.""" from concurrent.futures import ProcessPoolExecutor, as_completed from functools import lru_cache import time import traceback import numpy as np from context import (ROOT, EXP, AK, CORE, COEFF, CFG, PINS, read, save, digest, load_module, check, budget, bit_equal, write_npz) from credit import replay_credit from mbon_accounting import MBONAccounting @lru_cache(maxsize=1) def prepared(): core = load_module('sealed_ah_core_al', CORE, PINS[CORE.relative_to(ROOT).as_posix()]) with np.load(EXP / 'protocol/incoming.npz', allow_pickle=False) as f: data = {k: f[k].copy() for k in f.files} incoming = core.IncomingIndex(data['src_global'], data['dst_local'], data['edge_id'], data['weights'], len(data['targets'])) altered = data['weights'].copy() altered[data['is_candidate']] *= np.float64(1.0 - CFG['conditional_depression_fraction']) assert bit_equal(data['weights'][~data['is_candidate']], altered[~data['is_candidate']]) assert np.array_equal(np.sign(data['weights']), np.sign(altered)) depressed = core.IncomingIndex(data['src_global'], data['dst_local'], data['edge_id'], altered, len(data['targets'])) for array in data.values(): array.setflags(write=False) return core, data, incoming, depressed, read(COEFF) def compare_results(base, changed, base_history, changed_history): event_equal = all(bit_equal(base[k], changed[k]) for k in ('step', 'neuron_idx')) count_changes = base['counts'] != changed['counts'] latency_changes = base['first_spike'] != changed['first_spike'] return dict(event_sequence_changed=not event_equal, spike_count_L1=int(np.abs(base['counts'].astype(np.int64) - changed['counts']).sum()), neurons_with_count_change=int(count_changes.sum()), neurons_with_first_latency_change=int(latency_changes.sum()), baseline_spikes=int(base['counts'].sum()), depressed_spikes=int(changed['counts'].sum()), max_abs_V_difference_SI=float(np.max(np.abs(base_history['history_v'] - changed_history['history_v']))), max_abs_g_difference_SI=float(np.max(np.abs(base_history['history_g'] - changed_history['history_g']))), final_V_max_abs_difference_SI=float(np.max(np.abs(base['v'] - changed['v']))), final_g_max_abs_difference_SI=float(np.max(np.abs(base['g'] - changed['g']))), functional_count_or_first_latency_change=bool(count_changes.any() or latency_changes.any()), result_scope='Conditional clamped-upstream replay only; all target threshold/reset/ref recalculated; not whole-brain or learning') def audit_trial(row, stage): start = time.perf_counter() key = row['name'] + '-r' + str(row['repeat']) out = EXP / 'trials' / key assert stage in ('baseline', 'conditional25') if stage == 'baseline': out.mkdir(exist_ok=False) else: assert read(EXP / 'audit/baselines-complete.json')['pass_all'], 'All 144 baseline replays must pass first' assert out.is_dir() and not (out / 'summary.json').exists() case = AK / 'cases' / row['cohort'] / row['name'] trial = AK / 'gpu' / row['cohort'] / key spec = read(case / 'spec.json') assert spec['steps'] == CFG['steps'] and spec['dt_ms'] == CFG['dt_ms'] and spec['apl_delay_steps'] == 18 assert all(spec[k] == row[k] for k in ('name', 'seed', 'mode', 'odor_id')) assert read(trial / 'summary.json')['complete'] and read(trial / 'summary.json')['pass_all'] with np.load(trial / 'state.npz', allow_pickle=False) as f: state = {k: f[k].copy() for k in f.files} assert set(state) == {'step', 'neuron_idx', 'counts', 'v', 'g', 'ref'} with np.load(case / 'requests.npz', allow_pickle=False) as f: requests = {k: f[k].copy() for k in f.files} core, data, incoming, depressed, coeff = prepared() targets, steps = data['targets'], spec['steps'] assert not np.isin(requests['neuron_idx'], targets).any(), 'Unexpected MBON injection: do not reinterpret it' v0 = np.full(len(targets), spec['model']['resting_potential_mv'], np.float64) * np.float64(.001) g0 = np.zeros(len(targets), np.float64) events = dict(step=state['step'], neuron_idx=state['neuron_idx']) if stage == 'baseline': observer = MBONAccounting(incoming, data['groups'], tuple(CFG['groups']), coeff, steps) result = core.replay(v0, g0, coeff, steps, targets, requests, events, incoming, np.zeros((steps, len(targets)), np.float32), observer) selected = np.isin(state['neuron_idx'], targets) exact = {k: bit_equal(result[k], state[k][targets]) for k in ('counts', 'v', 'g', 'ref')} exact.update({k: bit_equal(result[k], state[k][selected]) for k in ('step', 'neuron_idx')}) assert all(exact.values()), 'Baseline MBON divergence: ' + str(exact) bt, be, bs = observer.finish() write_npz(out / 'baseline-replay.npz', **result) write_npz(out / 'baseline-target-accounting.npz', **bt) pending = np.zeros(len(incoming.edge_id), np.int64) for tick in range(steps - 18, steps): due = incoming.due(state['neuron_idx'][state['step'] == tick]) pending[due] += 1 be['pending_after_window_count'] = pending # Independent source-spike multiplicity covers due plus pending events. source_counts = np.bincount(state['neuron_idx'], minlength=CFG['neurons']) assert np.array_equal(be['due_count'] + pending, source_counts[incoming.src_global]) write_npz(out / 'baseline-edge-accounting.npz', **be) save(out / 'baseline-accounting.json', bs) trace = replay_credit(state['step'], state['neuron_idx'], data['kc_globals'], steps=steps, gate_tick=CFG['virtual_gate_tick'], dt_ms=CFG['dt_ms'], tau_ms=CFG['kc_trace_tau_ms'], cap=CFG['trace_cap']) arrays = {k: value for k, value in trace.items() if isinstance(value, np.ndarray)} write_npz(out / 'credit.npz', **arrays) save(out / 'credit.json', {k: value for k, value in trace.items() if not isinstance(value, np.ndarray)}) report = dict(**row, pass_all=True, baseline_exact=exact, due_plus_pending_source_events_exact=True, CPU_wall_seconds=time.perf_counter() - start) save(out / 'baseline-summary.json', report) return report with np.load(out / 'baseline-replay.npz', allow_pickle=False) as f: result = {k: f[k].copy() for k in f.files} with np.load(out / 'baseline-target-accounting.npz', allow_pickle=False) as f: bt = {k: f[k].copy() for k in f.files} baseline_report = read(out / 'baseline-summary.json') assert baseline_report['pass_all'] and all(baseline_report['baseline_exact'].values()) exact = baseline_report['baseline_exact'] d_observer = MBONAccounting(depressed, data['groups'], tuple(CFG['groups']), coeff, steps) changed = core.replay(v0, g0, coeff, steps, targets, requests, events, depressed, np.zeros((steps, len(targets)), np.float32), d_observer) dt, de, ds = d_observer.finish() write_npz(out / 'conditional25-replay.npz', **changed) write_npz(out / 'conditional25-target-accounting.npz', **dt) write_npz(out / 'conditional25-edge-accounting.npz', **de) save(out / 'conditional25-accounting.json', ds) sensitivity = compare_results(result, changed, bt, dt) save(out / 'sensitivity.json', sensitivity) report = dict(**row, pass_all=True, baseline_exact=exact, sensitivity=sensitivity, credit_gate='Virtual tick900 post-update; no DAN injection or plastic update', biological_duration_ms=spec['duration_ms'], CPU_wall_seconds=time.perf_counter() - start, baseline_CPU_wall_seconds=baseline_report['CPU_wall_seconds'], source_sha256={f: digest(trial / f) for f in ('state.npz', 'summary.json')}, conditional_weight_copy_only=True, training=False, candidate_generated=False) save(out / 'summary.json', report) save(out / 'output-hashes.json', [dict(path=p.name, bytes=p.stat().st_size, sha256=digest(p)) for p in sorted(out.iterdir()) if p.is_file()]) return report def main(): reg = check() assert not any((EXP / 'trials').iterdir()), 'No automatic resume/overwrite of diagnostic outputs' complete = [] try: for stage in ('baseline', 'conditional25'): complete = [] with ProcessPoolExecutor(max_workers=CFG['workers']) as pool: futures = {pool.submit(audit_trial, row, stage): row for row in reg['planned']} for task in as_completed(futures): result = task.result() complete.append(dict(name=result['name'], repeat=result['repeat'], pass_all=True)) budget() print(stage, len(complete), result['name'], result['repeat'], round(result['CPU_wall_seconds'], 3), 'CPU s', flush=True) assert len(complete) == 144 if stage == 'baseline': save(EXP / 'audit/baselines-complete.json', dict(pass_all=True, trials=complete, primary=120, repeats=24)) except Exception as error: save(EXP / 'audit/failure.json', dict(error=type(error).__name__, message=str(error), traceback=traceback.format_exc(), stage=stage, completed=complete)) raise assert len(complete) == 144 save(EXP / 'audit/replays-complete.json', dict(pass_all=True, trials=complete, primary=120, repeats=24, meaning='All exact conditional baseline reconstructions; not an overall biological or learning PASS')) if __name__ == '__main__': main()