Files
2026-09-30 09:59:18 +08:00

206 lines
12 KiB
Python

"""Reconstruct existing KC targets; never launch a brain simulation or CUDA."""
from functools import lru_cache
import time
import traceback
import numpy as np
import pandas as pd
from context import ROOT, EXP, AG, META, COEFF, read, save, digest, check
from replay_core import IncomingIndex, replay
from accounting import DriveAccounting, bit_equal
from populations import GROUPS
@lru_cache(maxsize=2)
def graph_view(graph_name):
folder = AG / 'graphs' / graph_name
nodes = np.load(folder / 'nodes.npy', mmap_mode='r')
all_kc = np.load(AG / 'apl-bundle/kc_globals.npy', mmap_mode='r')
apl = np.load(AG / 'apl-bundle/apl_globals.npy', mmap_mode='r')
targets, node_positions, apl_columns = np.intersect1d(nodes, all_kc, assume_unique=True, return_indices=True)
lookup = np.full(len(nodes), -1, np.int32)
lookup[node_positions] = np.arange(len(targets), dtype=np.int32)
destination = np.load(folder / 'dst.npy', mmap_mode='r')
selected = np.flatnonzero(lookup[destination] >= 0)
src_local = np.load(folder / 'src.npy', mmap_mode='r')[selected]
src = nodes[src_local]
dst = lookup[destination[selected]]
ids = np.load(folder / 'edge_id.npy', mmap_mode='r')[selected]
weights = np.load(folder / 'weights.npy', mmap_mode='r')[selected].copy()
weights[np.isin(src, apl)] = 0.0
original = np.load(ROOT / 'datasets/male-cns-v1.0/processed/neuron-only/gpu/csr-weights.int64.npy', mmap_mode='r')
raw = original[ids]
assert raw.dtype == np.int64 and np.all(raw > 0)
incoming = IncomingIndex(src, dst, ids, weights, len(targets))
group_frame = pd.read_parquet(EXP / 'protocol/neuron-source-groups.parquet')
labels = group_frame.audit_source_group.to_numpy()
group_codes = np.array([GROUPS.index(x) for x in labels], np.int32)[src]
audit = dict(graph_name=graph_name, graph_nodes=len(nodes), graph_edges=len(destination),
KC_targets=len(targets), incoming_edges=len(ids), incoming_contacts=int(raw.sum()),
zeroed_APL_incoming_edges=int(np.isin(src, apl).sum()),
groups={name: dict(edges=int(np.count_nonzero(group_codes == gi)),
contacts=int(raw[group_codes == gi].sum())) for gi, name in enumerate(GROUPS)},
source_graph=str(folder), conditional_target_filter_only=True, source_graph_modified=False)
return incoming, raw, group_codes, targets, node_positions, apl_columns, audit
def input_audit(case, source, spec, state, population):
with np.load(case / 'requests.npz', allow_pickle=False) as data:
req = {k: data[k].copy() for k in data.files}
table = pd.read_csv(source / 'requests.csv')
assert len(table) == len(req['tick'])
assert np.array_equal(table.tick.to_numpy(), req['tick'])
assert np.array_equal(table.neuron_idx.to_numpy(), req['neuron_idx'])
assert (table.attempted == 1).all() and table.accepted.isin([0, 1]).all()
assert np.array_equal(table.rejected.to_numpy(), 1 - table.accepted.to_numpy())
request_keys = req['tick'].astype(np.int64) * 166700 + req['neuron_idx']
event_keys = state['step'].astype(np.int64) * 166700 + state['neuron_idx']
accepted = np.isin(request_keys, event_keys)
assert np.array_equal(accepted, table.accepted.to_numpy().astype(bool))
labels = population.audit_source_group.to_numpy()
all_pn = np.flatnonzero(labels == 'ALPN').astype(np.int32)
observed_count = np.bincount(state['neuron_idx'], minlength=166700)
requested_count = np.bincount(req['neuron_idx'], minlength=166700)
accepted_count = np.bincount(req['neuron_idx'][accepted], minlength=166700)
targets = np.empty(0, np.int32)
rates = np.empty(0, np.float32)
if spec['kind'] == 'calibration':
with np.load(case / 'pn-drive.npz', allow_pickle=False) as data:
targets, rates = data['targets'].copy(), data['rates_hz'].copy()
assert targets.dtype == np.int32 and rates.dtype == np.float32
assert targets.shape == rates.shape == (spec['target_count'],)
assert len(np.unique(targets)) == len(targets) and np.isfinite(rates).all() and (rates > 0).all()
assert np.isin(targets, all_pn).all() and np.isin(req['neuron_idx'], targets).all()
rate_map = dict(zip(targets.tolist(), rates.tolist()))
pn_table = population.iloc[all_pn][['neuron_idx', 'body_id', 'annotation_type']].copy()
pn_table['design_target'] = np.isin(all_pn, targets)
pn_table['design_rate_hz'] = [rate_map.get(int(i), 0.0) for i in all_pn]
pn_table['requests'] = requested_count[all_pn]
pn_table['accepted_requests'] = accepted_count[all_pn]
pn_table['rejected_requests'] = requested_count[all_pn] - accepted_count[all_pn]
pn_table['actual_spikes'] = observed_count[all_pn]
pn_table['spikes_not_coincident_with_accepted_request'] = observed_count[all_pn] - accepted_count[all_pn]
assert (pn_table.spikes_not_coincident_with_accepted_request >= 0).all()
info = dict(requests=len(request_keys), accepted=int(accepted.sum()), rejected=int((~accepted).sum()),
actual_spikes_by_source_group={name: int(observed_count[labels == name].sum()) for name in GROUPS},
all_ALPN=len(all_pn), odor_design_target_count=len(targets), PN_ever_requested=int(np.count_nonzero(requested_count[all_pn])),
PN_ever_accepted_request=int(np.count_nonzero(accepted_count[all_pn])),
PN_actual_active=int(np.count_nonzero(observed_count[all_pn])),
design_target_PN_spikes=int(observed_count[targets].sum()),
non_design_ALPN_spikes=int(observed_count[np.setdiff1d(all_pn, targets)].sum()),
accepted_request_is_not_proof_spike_was_caused_exclusively_by_request=True,
actual_requested_events_not_forced_to_equal_across_odors=True)
return req, info, pn_table
def audit_trial(row, population):
start = time.perf_counter()
name = row['case'] + '-r' + str(row['repeat'])
out = EXP / 'trials' / name
out.mkdir(exist_ok=False)
source = ROOT / row['source']
case = AG / 'cases' / row['case']
spec = read(case / 'spec.json')
graph_name = 'fixtures' if row['kind'] == 'fixture' else 'full'
incoming, raw, groups, targets, positions, apl_columns, graph_audit = graph_view(graph_name)
with np.load(source / 'state.npz', allow_pickle=False) as data:
state = {k: data[k].copy() for k in data.files}
assert set(state) == {'step', 'neuron_idx', 'counts', 'v', 'g', 'ref'}
assert all(np.isfinite(v).all() for v in state.values())
req, input_report, pn_table = input_audit(case, source, spec, state, population)
event_mask = np.isin(state['neuron_idx'], targets)
expected = {key: state[key][event_mask] for key in ('step', 'neuron_idx')}
initial_v = np.full(len(targets), spec['model']['resting_potential_mv'], np.float64) * np.float64(.001)
initial_g = np.zeros(len(targets), np.float64)
if (case / 'arrays.npz').exists():
with np.load(case / 'arrays.npz', allow_pickle=False) as data:
initial_v = data['initial_v_mv'][positions] * np.float64(.001)
initial_g = data['initial_g_mv'][positions] * np.float64(.001)
histories = {}
if row['kind'] == 'fixture':
for key, suffix in (('v', 'float64'), ('g', 'float64'), ('ref', 'int32')):
histories[key] = np.load(source / f'{key}-history.{suffix}.npy', mmap_mode='r')[:, positions]
histories['pre_' + key] = np.load(source / f'preAPL-{key}.{suffix}.npy', mmap_mode='r')[:, positions]
h = np.load(source / 'apl-inhibition.float32.npy', mmap_mode='r')
assert h.shape == (spec['steps'], 4064)
if not np.array_equal(apl_columns, np.arange(4064)):
h = h[:, apl_columns]
coeff = read(COEFF)
accounting = DriveAccounting(targets, incoming, raw, groups, GROUPS, expected,
coeff, state['counts'][positions], histories)
result = replay(initial_v, initial_g, coeff, spec['steps'], targets, req,
dict(step=state['step'], neuron_idx=state['neuron_idx']), incoming, h, accounting)
exact = {key: bit_equal(result[key], state[key][positions]) for key in ('v', 'g', 'ref', 'counts')}
exact.update({key: bit_equal(result[key], expected[key]) for key in ('step', 'neuron_idx')})
assert all(exact.values()), 'Reconstruction diverged: ' + str(exact)
assert accounting.callback_count == spec['steps']
data, report = accounting.finish(result['g'])
assert bit_equal(data['first_spike_tick'], result['first_spike'])
per_kc = pd.DataFrame(data)
per_kc.insert(1, 'body_id', population.iloc[targets].body_id.to_numpy())
per_kc.to_parquet(out / 'per-kc.parquet', index=False)
pn_table.to_parquet(out / 'per-pn.parquet', index=False)
pd.DataFrame(accounting.tick_rows).to_parquet(out / 'per-tick.parquet', index=False)
with (out / 'replay-final.npz').open('xb') as f:
np.savez_compressed(f, **result)
late_counts = np.bincount(state['neuron_idx'][state['step'] >= spec['steps'] - 18], minlength=166700)
pending = late_counts[incoming.src_global]
report.update(case=row['case'], repeat=row['repeat'], kind=row['kind'], pass_all=True,
exact=exact, full_KC_sparse_events_and_final_state_exact=True,
every_tick_fixture_pre_post_state_exact=bool(histories),
graph=graph_audit, input=input_report, steps=spec['steps'], duration_ms=spec['duration_ms'],
KC_active=int(np.count_nonzero(result['counts'])), KC_spikes=int(result['counts'].sum()),
pending_after_record_window=dict(edge_events=int(pending.sum()), contacts=int(np.dot(pending, raw)),
nominal_abs_SI=float(np.dot(pending, np.abs(incoming.weights)))),
mode=spec.get('mode'), odor_id=spec.get('odor_id'), seed=spec.get('seed'),
CPU_audit_wall_seconds=time.perf_counter() - start,
original_brain_time_and_wall_not_rebenchmarked=True, training=False, new_brain_simulation=False,
candidate_generated=False, input_sha256={filename: digest(source / filename)
for filename in ('state.npz', 'apl-inhibition.float32.npy', 'requests.csv', 'summary.json')})
save(out / 'summary.json', report)
return report
def main():
check()
prepared = read(EXP / 'protocol/prepared-hashes.json')
for row in prepared:
assert digest(EXP / row['path']) == row['sha256']
population = pd.read_parquet(EXP / 'protocol/neuron-source-groups.parquet')
inventory = read(EXP / 'protocol/inventory.json')
reports = []
for row in inventory:
try:
report = audit_trial(row, population)
reports.append(dict(case=row['case'], repeat=row['repeat'], pass_all=report['pass_all']))
assert sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file()) < 2 * 1024 ** 3
print(row['case'], row['repeat'], 'EXACT', report['KC_active'],
'KC active; CPU audit seconds', round(report['CPU_audit_wall_seconds'], 3), flush=True)
except Exception as error:
save(EXP / 'audit/failure.json', dict(case=row, error=type(error).__name__, message=str(error),
traceback=traceback.format_exc(), completed=reports, new_brain_simulation=False))
raise
repeat_checks = []
for row in inventory:
if row['repeat'] != 1:
continue
first = EXP / 'trials' / (row['case'] + '-r0')
repeat = EXP / 'trials' / (row['case'] + '-r1')
checks = {}
for filename in ('per-kc.parquet', 'per-pn.parquet', 'per-tick.parquet'):
a, b = pd.read_parquet(first / filename), pd.read_parquet(repeat / filename)
checks[filename] = a.equals(b)
with np.load(first / 'replay-final.npz') as a, np.load(repeat / 'replay-final.npz') as b:
checks['replay-final'] = set(a.files) == set(b.files) and all(bit_equal(a[k], b[k]) for k in a.files)
assert all(checks.values()), 'Repeat accounting differs'
repeat_checks.append(dict(case=row['case'], pass_all=True, checks=checks))
assert len(reports) == 80 and len(repeat_checks) == 12
save(EXP / 'audit/completed.json', dict(pass_all=True, trials=reports, repeat_checks=repeat_checks,
meaning='Exact conditional KC reconstruction and reproducible accounting only', candidate_generated=False))
print('PASS 80/80 conditional reconstructions; 12/12 accounting repeats', flush=True)
if __name__ == '__main__':
main()