Archive MaleCNS research sources, provenance, bibliography and immutable data inventory

This commit is contained in:
Digital Drosophila Archive
2026-09-29 03:38:32 +08:00
commit 3981628ff8
682 changed files with 161475 additions and 0 deletions
@@ -0,0 +1,58 @@
{
"file_count": 10,
"files": [
{
"bytes": 342,
"path": "VERSION.json",
"sha256": "036775cdd0e3851114d6439b9a8b7706c5f96e9ce4e49b4529484f0aa3e03252"
},
{
"bytes": 11982,
"path": "__pycache__/phase4o_a.cpython-310.pyc",
"sha256": "61d9d7ea769df6546382b06081bd6dcf376c07deb9bc613aad6257c863190341"
},
{
"bytes": 1253,
"path": "phase4o.yaml",
"sha256": "8b380f0597dd3f2d656e9e773a581855f75d940bcc0dad9e84abb6b02173aa16"
},
{
"bytes": 11747,
"path": "phase4o_a.py",
"sha256": "1048a073de399052bd525faf010858fa83f075a7c747b3fe5dcf8e4fc9ce3b87"
},
{
"bytes": 4736,
"path": "phase4o_atomic.py",
"sha256": "b481d91ac3a72d360c4dbb5378b975e430f0d1027fad94de5e2a041f9849c714"
},
{
"bytes": 7748,
"path": "phase4o_eligibility.py",
"sha256": "4fb7c97c8832c3ef51fe7613083dd6eab627bcde419254696c19a07632deb878"
},
{
"bytes": 7916,
"path": "phase4o_event_replay.py",
"sha256": "b169937bab495c77d8ee6c1013877e7500e7354140d9fcc90595d984238ba44e"
},
{
"bytes": 11065,
"path": "phase4o_finalize.py",
"sha256": "db6318467fb1ecef4003077ec1db8eac299c0c56944f463f96418ab41135c08f"
},
{
"bytes": 6133,
"path": "phase4o_modes.py",
"sha256": "8980ff1581c81d99752515349ee7be747a6f954a94ab56492b400a5324f1b6a2"
},
{
"bytes": 4268,
"path": "phase4o_targeted.py",
"sha256": "cfd6cc4dd0f2c0d58b5eb2634fb4e6bd530eec5037c4c8462f6ef7a885301200"
}
],
"generated_utc": "2026-09-21T15:31:34.397398+00:00",
"root": "/data/digital-drosophila/models/male-cns-lif/runtime-credit-v1",
"total_bytes": 67190
}
@@ -0,0 +1,9 @@
{
"eligibility_v3_experimental_started": false,
"frozen_runtime_v1_overwritten": false,
"name": "MaleCNS-runtime-credit-v1-audit",
"phase": "4O-A",
"runtime_v2_deterministic_candidate_generated": false,
"status": "FAIL-RUNTIME-DETERMINISM",
"summary_sha256": "e7db20298cce2952d585f655cc866eb389946c2818ba4924ebd6f049bc228947"
}
@@ -0,0 +1,11 @@
9a1d1bcb8da99194ba58a1db1aae288648eab72a94c55d3862fac478670c7e8e MANIFEST.json
036775cdd0e3851114d6439b9a8b7706c5f96e9ce4e49b4529484f0aa3e03252 VERSION.json
61d9d7ea769df6546382b06081bd6dcf376c07deb9bc613aad6257c863190341 __pycache__/phase4o_a.cpython-310.pyc
8b380f0597dd3f2d656e9e773a581855f75d940bcc0dad9e84abb6b02173aa16 phase4o.yaml
1048a073de399052bd525faf010858fa83f075a7c747b3fe5dcf8e4fc9ce3b87 phase4o_a.py
b481d91ac3a72d360c4dbb5378b975e430f0d1027fad94de5e2a041f9849c714 phase4o_atomic.py
4fb7c97c8832c3ef51fe7613083dd6eab627bcde419254696c19a07632deb878 phase4o_eligibility.py
b169937bab495c77d8ee6c1013877e7500e7354140d9fcc90595d984238ba44e phase4o_event_replay.py
db6318467fb1ecef4003077ec1db8eac299c0c56944f463f96418ab41135c08f phase4o_finalize.py
8980ff1581c81d99752515349ee7be747a6f954a94ab56492b400a5324f1b6a2 phase4o_modes.py
cfd6cc4dd0f2c0d58b5eb2634fb4e6bd530eec5037c4c8462f6ef7a885301200 phase4o_targeted.py
@@ -0,0 +1,28 @@
phase: 4O
stage: A-runtime-determinism-recovery
status_policy: fail-closed
experiment_root: /data/digital-drosophila/experiments/phase4o-runtime-credit
model_root: /data/digital-drosophila/models/male-cns-lif/runtime-credit-v1
frozen_phase4c_config: /data/digital-drosophila/models/male-cns-lif/runtime-v1/phase4c.yaml
frozen_phase4m_config: /data/digital-drosophila/models/male-cns-lif/kcmbon-efficacy-v1/phase4m.yaml
frozen_phase4n_config: /data/digital-drosophila/models/male-cns-lif/credit-assignment-v1/phase4n.yaml
required_gpu_uuid: GPU-79f3a85d-adce-7833-7003-6488140ca596
phase4c_reference_trials: [auditory-10hz, auditory-100hz, olfactory-50hz, mechanosensory-50hz, gustatory-50hz]
phase4c_repeats_per_trial: 10
phase4m_training_trials: 500
eligibility_complete_event_repeats: 5
pass_requires:
phase4c_spike_events_exact: true
phase4c_per_neuron_counts_exact: true
frozen_phase4m_eligibility_exact: true
instrumentation_independent: true
logging_independent: true
backend_identity_fixed: true
frozen_artifacts_unchanged: true
part_b_gate: PASS-RUNTIME-DETERMINISM-RECOVERED
prohibitions:
modify_frozen_artifact: true
modify_brain_dynamics: true
modify_eligibility_v2: true
train: true
start_part_b_on_part_a_fail: true
@@ -0,0 +1,202 @@
#!/usr/bin/env python3
"""Read-only Phase 4O-A runtime determinism audit; never writes frozen roots."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import platform
import random
import shutil
import subprocess
import sys
import time
from pathlib import Path
import numpy as np
import pyarrow.parquet as pq
import torch
import yaml
ROOT = Path("/data/digital-drosophila")
EXP = ROOT / "experiments/phase4o-runtime-credit"
MODEL = ROOT / "models/male-cns-lif/runtime-credit-v1"
FROZEN = ROOT / "experiments/phase4c-runtime/regression/reference"
GPU_UUID = "GPU-79f3a85d-adce-7833-7003-6488140ca596"
def save(path: Path, value: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(value, ensure_ascii=False, indent=2, sort_keys=True, default=str) + "\n")
def sha(path: Path) -> str:
h = hashlib.sha256()
with path.open("rb") as f:
for block in iter(lambda: f.read(8 << 20), b""):
h.update(block)
return h.hexdigest()
def digest(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def cmd(args: list[str]) -> dict:
exe = shutil.which(args[0])
if exe is None:
return {"available": False}
p = subprocess.run(args, text=True, capture_output=True)
return {"available": True, "exit_code": p.returncode, "stdout": p.stdout.strip()[:8000], "stderr": p.stderr.strip()[:2000]}
def env_audit() -> None:
if os.environ.get("CUDA_VISIBLE_DEVICES") != GPU_UUID:
raise RuntimeError("CUDA_VISIBLE_DEVICES must select frozen RTX 4090 UUID")
names = ["CUDA_VISIBLE_DEVICES", "CUBLAS_WORKSPACE_CONFIG", "PYTHONHASHSEED", "OMP_NUM_THREADS", "MKL_NUM_THREADS"]
names += sorted(x for x in os.environ if x.startswith("TORCH_"))
gpu = torch.cuda.get_device_properties(0)
e = {"OS_release": platform.platform(), "kernel": platform.release(), "uname": platform.uname()._asdict(),
"python": sys.version, "torch": torch.__version__, "cuda_runtime": torch.version.cuda,
"cudnn": torch.backends.cudnn.version(), "gpu_name": gpu.name, "gpu_uuid": GPU_UUID,
"gpu_total_memory_bytes": gpu.total_memory, "env_allowlist": {x: os.environ.get(x) for x in names},
"nvcc": cmd(["nvcc", "--version"]), "nvidia_smi": cmd(["nvidia-smi", "--query-gpu=name,uuid,driver_version,memory.total", "--format=csv,noheader"]),
"gcc": cmd(["gcc", "--version"]), "gxx": cmd(["g++", "--version"]), "ninja": cmd(["ninja", "--version"]),
"git_model": cmd(["git", "-C", str(ROOT / "models/male-cns-lif"), "status", "--short", "--branch"]),
"git_workspace": cmd(["git", "-C", str(ROOT), "rev-parse", "HEAD"]),
"torch_flags": {"deterministic_algorithms": torch.are_deterministic_algorithms_enabled(),
"cudnn_deterministic": torch.backends.cudnn.deterministic,
"cudnn_benchmark": torch.backends.cudnn.benchmark,
"cuda_matmul_allow_tf32": torch.backends.cuda.matmul.allow_tf32,
"cudnn_allow_tf32": torch.backends.cudnn.allow_tf32,
"matmul_precision": torch.get_float32_matmul_precision()}}
save(EXP / "environment/runtime-environment.json", e)
roots = [ROOT / "models/male-cns-lif/reference-v1", ROOT / "models/male-cns-lif/runtime-v1",
FROZEN, ROOT / "models/male-cns-lif/kcmbon-efficacy-v1",
ROOT / "experiments/phase4n-credit-assignment/compiler-reports/extension-build",
ROOT / "experiments/phase4c-runtime/compiler-reports/extension-build"]
files = []
for root in roots:
if root.exists():
for p in sorted(root.rglob("*")):
if p.is_file() and p.suffix not in (".pyc", ".o"):
files.append({"path": str(p), "bytes": p.stat().st_size, "mtime_ns": p.stat().st_mtime_ns, "sha256": sha(p)})
for p in [ROOT / "models/male-cns-lif/brain_runtime.py", ROOT / "models/male-cns-lif/phase4i.py",
ROOT / "models/male-cns-lif/phase4m.py", ROOT / "models/male-cns-lif/phase4l.py",
ROOT / "models/male-cns-lif/phase4n_events.py"]:
if p.is_file():
files.append({"path": str(p), "bytes": p.stat().st_size, "mtime_ns": p.stat().st_mtime_ns, "sha256": sha(p)})
save(EXP / "binary-audit/execution-file-sha256.json", files)
binary = [x for x in files if x["path"].endswith(".so")]
save(EXP / "binary-audit/runtime-binary-diff-report.json", {
"binary_files": binary, "bytewise_same": len({x["sha256"] for x in binary}) == 1 if len(binary) > 1 else None,
"warning": "A binary hash difference is not itself proof of changed semantics; build paths and toolchain can alter ELF bytes.",
"historical_phase4c_manifest": str(ROOT / "experiments/phase4c-runtime/manifests/manifest.json")})
def rng_hashes(rt=None) -> dict:
py = digest(repr(random.getstate()).encode())
npy = digest(repr(np.random.get_state()).encode())
out = {"python_random": py, "numpy_global": npy, "torch_cpu": digest(torch.get_rng_state().numpy().tobytes()),
"torch_cuda": digest(torch.cuda.get_rng_state(0).cpu().numpy().tobytes())}
if rt is not None and hasattr(rt, "generator"):
out["input_generator"] = digest(rt.generator.get_state().cpu().numpy().tobytes())
return out
def first_event_diff(a_step, a_node, b_step, b_node):
n = min(len(a_step), len(b_step))
mismatched = np.flatnonzero((a_step[:n] != b_step[:n]) | (a_node[:n] != b_node[:n]))
j = int(mismatched[0]) if len(mismatched) else (n if len(a_step) != len(b_step) else None)
if j is None:
return None
ref = None if j >= len(a_step) else {"step": int(a_step[j]), "neuron_idx": int(a_node[j])}
got = None if j >= len(b_step) else {"step": int(b_step[j]), "neuron_idx": int(b_node[j])}
step = min(x["step"] for x in (ref, got) if x is not None)
return {"event_position": j, "first_difference_step_upper_bound": step, "reference_event": ref, "observed_event": got,
"note": "Event-list first difference is not necessarily first state divergence; state-level instrumentation is required."}
def repeat_audit(repeats: int, trial_filter: str | None = None, tag: str = "baseline") -> None:
from brain_runtime import BrainRuntime
from phase4i import poisson_batch
cfgpath = ROOT / "models/male-cns-lif/mb-mechanistic-v1/phase4i.yaml"
rt = BrainRuntime(cfgpath, EXP / "compiler-reports/extension-build")
backend_file = Path(rt.extension.__file__)
identity = {"module": rt.extension.__name__, "binary_path": str(backend_file), "binary_sha256": sha(backend_file),
"runtime_v1_python_sha256": sha(ROOT / "models/male-cns-lif/runtime-v1/phase4c.py"),
"source": "BrainRuntime._hybrid_edges plus GPU scatter_add_", "config": str(cfgpath), "config_sha256": sha(cfgpath)}
save(EXP / "binary-audit/loaded-backend.json", identity)
specs = [(s["name"], s["population"], float(s["rate_hz"]), int(s["seed"])) for s in yaml.safe_load((ROOT / "models/male-cns-lif/runtime-v1/phase4c.yaml").read_text())["reference_trials"]]
if trial_filter:
specs = [x for x in specs if x[0] == trial_filter]
if not specs: raise ValueError(f"unknown frozen trial {trial_filter}")
rows = []
output_dir = EXP / "phase4c-replay" / tag
for name, pop, rate, seed in specs:
refroot = FROZEN / name
table = pq.read_table(refroot / "spike-events.parquet")
rstep = table["step"].to_numpy().astype(np.int32); rnode = table["neuron_idx"].to_numpy().astype(np.int32)
rcount = np.load(refroot / "per-neuron-spike-counts.int32.npy")
rv = np.load(refroot / "final-voltage.float32.npy"); rg = np.load(refroot / "final-g.float32.npy")
targets = np.flatnonzero(rt.population_masks[pop]).astype(np.int64)
for repeat in range(repeats):
before = rng_hashes(rt)
rt.reset(seed)
after_reset = rng_hashes(rt)
before_first = rng_hashes(rt)
t0 = time.perf_counter()
error = None
try:
rt.step(poisson_batch(targets, rate, 1000.0, name), 1000.0)
events = rt.read_spikes()
step = events["step"].astype(np.int32); node = events["neuron_idx"].astype(np.int32)
counts = rt.spike_counts.cpu().numpy().astype(np.int32)
voltage = rt.v.cpu().numpy(); g = rt.g.cpu().numpy()
match_events = bool(np.array_equal(step, rstep) and np.array_equal(node, rnode))
match_counts = bool(np.array_equal(counts, rcount))
row = {"trial": name, "repeat": repeat, "target_count": int(len(targets)),
"spike_events_exact": match_events, "per_neuron_counts_exact": match_counts,
"final_voltage_max_abs_error": float(np.max(np.abs(voltage-rv))),
"final_g_max_abs_error": float(np.max(np.abs(g-rg))),
"event_count": len(node), "event_sha256": digest(step.tobytes()+node.tobytes()),
"counts_sha256": digest(counts.tobytes()), "first_event_difference": first_event_diff(rstep,rnode,step,node),
"wall_seconds": time.perf_counter()-t0,
"rng_before_reset": before, "rng_after_reset": after_reset,
"rng_before_first_timestep": before_first, "rng_after_trial": rng_hashes(rt)}
if not match_events:
output_dir.mkdir(parents=True, exist_ok=True)
pq.write_table(__import__('pyarrow').table({'step':step,'neuron_idx':node}),
output_dir / f"divergent-{name}-repeat-{repeat}-events.parquet",compression='zstd')
np.savez_compressed(output_dir / f"divergent-{name}-repeat-{repeat}-state.npz",
final_voltage=voltage, final_g=g, counts=counts)
except Exception as exc:
error = repr(exc)
row = {"trial": name, "repeat": repeat, "error": error, "wall_seconds": time.perf_counter()-t0,
"rng_before_reset": before, "rng_after_reset": after_reset}
rows.append(row)
save(output_dir / "reproducibility-matrix.json", rows)
print(json.dumps({"trial": name, "repeat": repeat, "event_exact": row.get("spike_events_exact"),
"count_exact": row.get("per_neuron_counts_exact"), "first_diff": row.get("first_event_difference"), "error": error}), flush=True)
save(output_dir / "summary.json", {"repeats_per_trial": repeats, "all_spike_events_exact": all(r.get("spike_events_exact",False) for r in rows),
"all_counts_exact": all(r.get("per_neuron_counts_exact",False) for r in rows),
"trial_summary": {name: {"event_exact": sum(r.get("spike_events_exact",False) for r in rows if r["trial"]==name),
"count_exact": sum(r.get("per_neuron_counts_exact",False) for r in rows if r["trial"]==name)} for name,_,_,_ in specs},
"backend": identity})
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("task", choices=["environment", "repeats"])
ap.add_argument("--repeats", type=int, default=10)
ap.add_argument("--trial")
ap.add_argument("--tag", default="baseline")
args = ap.parse_args()
EXP.mkdir(parents=True, exist_ok=True); MODEL.mkdir(parents=True, exist_ok=True)
if args.task == "environment": env_audit()
else: repeat_audit(args.repeats, args.trial, args.tag)
if __name__ == "__main__":
main()
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""Real Phase 4C event/CSR atomic-collision micro-reproduction (read-only inputs)."""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import numpy as np
import pyarrow.parquet as pq
import torch
import yaml
from phase4o_a import EXP,FROZEN,ROOT,save
def main():
trial='mechanosensory-50hz'
step=6625
delay=18
focus=[3942,3954]
ref=pq.read_table(FROZEN/trial/'spike-events.parquet',columns=['step','neuron_idx']).to_pandas()
src=ref.loc[ref.step==step-delay,'neuron_idx'].to_numpy(np.int32)
graph=ROOT/'datasets/male-cns-v1.0/processed/neuron-only/gpu'
indptr=np.load(graph/'csr-indptr.int64.npy',mmap_mode='r')
indices=np.load(graph/'csr-indices.int32.npy',mmap_mode='r')
raw=np.load(graph/'csr-weights.int64.npy',mmap_mode='r')
cfg=yaml.safe_load((ROOT/'models/male-cns-lif/runtime-v1/phase4c.yaml').read_text())
meta=pq.read_table(ROOT/'datasets/male-cns-v1.0/processed/neuron-only/neuron-index/unified-metadata.parquet',columns=['neurotransmitter']).column('neurotransmitter').to_pylist()
signs=[]
policy=cfg['sign_policy'];mp=policy['neurotransmitter_sign']
for n in src:
val=meta[int(n)]
key='' if val is None else str(val).strip().lower()
signs.append(policy['unknown_sign'] if not key else policy['unclear_sign'] if key=='unclear' else mp[key])
edge_ids=np.concatenate([np.arange(int(indptr[n]),int(indptr[n+1]),dtype=np.int64) for n in src]) if len(src) else np.empty(0,np.int64)
edge_src=np.repeat(src,(indptr[src+1]-indptr[src]).astype(np.int64))
sign_edge=np.repeat(np.asarray(signs,np.int8),(indptr[src+1]-indptr[src]).astype(np.int64))
tgt=np.asarray(indices[edge_ids],np.int32)
w=(np.asarray(raw[edge_ids],np.float32)*sign_edge.astype(np.float32)*np.float32(cfg['model']['w_syn_mv_per_anatomical_synapse'])).astype(np.float32)
counts=np.bincount(tgt,minlength=166700)
# Run the unchanged scatter_add_ ordering against the real active-event edge subset.
target_gpu=torch.as_tensor(tgt,dtype=torch.int64,device='cuda:0')
weight_gpu=torch.as_tensor(w,dtype=torch.float32,device='cuda:0')
samples=[];all_samples=[]
for _ in range(100):
out=torch.zeros(166700,dtype=torch.float32,device='cuda:0')
out.scatter_add_(0,target_gpu,weight_gpu)
all_samples.append(out.cpu().numpy().copy())
samples.append(all_samples[-1][focus].copy())
sampled=np.asarray(samples,np.float32)
full=np.asarray(all_samples,np.float32)
spread=np.ptp(full,axis=0)
variable=np.flatnonzero(spread>0)
detail=[]
for j,n in enumerate(focus):
loc=np.flatnonzero(tgt==n)
contrib=w[loc]
# Deterministic reference keyed by original anatomical edge_id.
order=np.argsort(edge_ids[loc],kind='stable')
acc=np.float32(0)
for value in contrib[order]: acc=np.float32(acc+value)
detail.append({'target_neuron_idx':n,'same_target_writes':len(loc),'incoming_source_neuron_idx':edge_src[loc].tolist(),
'incoming_edge_ids':edge_ids[loc].tolist(),'incoming_effective_weights_mv':contrib.tolist(),
'cpu_edge_order_float32_sum_mv':float(acc),'cpu_float64_sum_mv':float(np.sum(contrib.astype(np.float64))),
'gpu_atomic_min_mv':float(sampled[:,j].min()),'gpu_atomic_max_mv':float(sampled[:,j].max()),
'gpu_atomic_unique_values':np.unique(sampled[:,j]).tolist()})
report={'reference_divergence_event_step':step,'arrival_source_step':step-delay,
'arrival_presynaptic_count':len(src),'fanout_edges':len(edge_ids),
'targets_with_multiple_concurrent_writes':int(np.count_nonzero(counts>1)),
'maximum_same_target_writes':int(counts.max()),
'targets_with_nonidentical_atomic_sum_across_100_repeats':len(variable),
'max_atomic_sum_range_mv':float(spread.max()),
'variable_target_examples':variable[:30].tolist(),
'focus':detail,'gpu_atomic_repetitions':len(samples),
'interpretation':'Collisions and float-order sensitivity are necessary evidence, not by themselves proof of the first state divergence.'}
save(EXP/'atomic/real-edge-subset.json',report)
print(json.dumps({'source_step':step-delay,'fanout_edges':len(edge_ids),'collision_targets':report['targets_with_multiple_concurrent_writes'],
'max_fanin':report['maximum_same_target_writes'],'focus':[{'neuron_idx':x['target_neuron_idx'],
'writes':x['same_target_writes'],'gpu_unique':len(x['gpu_atomic_unique_values'])} for x in detail]}),flush=True)
if __name__=='__main__':main()
@@ -0,0 +1,139 @@
#!/usr/bin/env python3
"""Five read-only repeats of sealed Phase 4M's 500-trial eligibility trajectory."""
from __future__ import annotations
import argparse
import hashlib
import json
import time
from pathlib import Path
import numpy as np
import pandas as pd
import torch
from phase4n import load_config
from phase4i import Validator
from phase4j import apply_v2
from phase4l import OdorSimulator, pn_drive
from phase4m import load_odor_inputs
ROOT = Path("/data/digital-drosophila")
EXP = ROOT / "experiments/phase4o-runtime-credit"
def save(path: Path, x: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(x, indent=2, sort_keys=True, default=str) + "\n")
def arrhash(x: np.ndarray) -> str:
return hashlib.sha256(x.tobytes()).hexdigest()
def first_diff(a: np.ndarray, b: np.ndarray):
n = min(len(a), len(b))
mismatched = np.flatnonzero(a[:n] != b[:n])
j = int(mismatched[0]) if len(mismatched) else (n if len(a) != len(b) else None)
if j is None:
return None
return {"event_position": j, "reference": None if j >= len(a) else int(a[j]), "observed": None if j >= len(b) else int(b[j])}
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--repeats", type=int, default=5)
args = ap.parse_args()
ncfg, mcfg, cfg, cfgpath = load_config(ROOT / "models/male-cns-lif/credit-assignment-v1/phase4n.yaml")
history = pd.read_parquet(Path(mcfg["experiment_root"]) / "efficacy-overlay/update-history.parquet")
frozen = {(int(s), int(p)): f for (s, p), f in history.groupby(["train_seed", "pairing"])}
old = pd.read_parquet(ROOT / "experiments/phase4n-credit-assignment/local-eligibility/KC-spike-history.parquet")
old_events = {(int(s), int(p)): f[["step", "neuron_idx"]].to_numpy(np.int32)
for (s, p), f in old.groupby(["seed", "pairing"])}
v = Validator(cfg, cfgpath, EXP)
sim = OdorSimulator(v, cfg, EXP)
panel, vectors, selection, mapping = load_odor_inputs(cfg)
oid = selection["ODOR_A"]["odor_id"]
pn = pn_drive(oid, vectors[oid], mapping, selection["glomeruli_order"], str(mcfg["protocol"]["input_mode"]),
float(np.median(panel.mapped_response_sum)), cfg)[:2]
target = str(mcfg["protocol"]["target_compartment_verbatim"])
dan = v.dan_targets(str(mcfg["protocol"]["matched_dan_type"]), target)
src = v.cand.source_neuron_idx.to_numpy(np.int32)
lookup = np.full(v.n, -1, np.int32)
lookup[v.kc] = np.arange(len(v.kc), dtype=np.int32)
loc = lookup[src]
comp = v.cand.target_compartment_verbatim.astype(str).to_numpy() == target
ids = v.edge_ids.astype(np.int64)
id_to_local = pd.Series(np.arange(len(ids), dtype=np.int32), index=ids)
seen = {}
rows = []
first_failures = []
for repeat in range(args.repeats):
for seed in ncfg["train_seeds"]:
delta = np.zeros(len(ids), np.float32)
for pairing in range(1, 101):
start = time.perf_counter()
run = sim.run_rates(*pn, seed+pairing, float(mcfg["protocol"]["duration_ms"]),
delta=delta, dan_targets=dan, dan_pulses=[float(mcfg["protocol"]["dan_time_ms"])],
collect_kc_spikes=True)
trace = run["kc_trace_at_dan"]
events = run["kc_spikes"][["step", "neuron_idx"]].to_numpy(np.int32)
old_ev = old_events.get((seed, pairing), np.empty((0, 2), np.int32))
rec = frozen[(seed, pairing)]
local = id_to_local.loc[rec.edge_id.to_numpy(np.int64)].to_numpy(np.int32)
value = trace[loc[local]]
recorded = rec.eligibility.to_numpy(np.float32)
max_err = float(np.max(np.abs(value-recorded))) if len(value) else 0.0
nonzero_now = np.flatnonzero(comp & (trace[loc] > 0))
frozen_active = set(map(int, local))
active_symmetric_diff = len(set(map(int, nonzero_now)) ^ frozen_active)
key = (seed,pairing)
h = arrhash(events)
if key not in seen:
seen[key] = h
row = {"repeat": repeat, "seed": seed, "pairing": pairing,
"KC_event_count": len(events), "KC_event_sha256": h,
"KC_events_same_as_first_repeat": h == seen[key],
"KC_events_same_as_phase4n_audit": bool(np.array_equal(events, old_ev)),
"first_KC_event_difference_from_phase4n": first_diff(old_ev[:,0],events[:,0]) if not np.array_equal(events,old_ev) else None,
"eligibility_max_abs_error_vs_frozen_phase4m": max_err,
"eligibility_active_edge_symmetric_difference": active_symmetric_diff,
"exact_eligibility": bool(max_err <= 2e-5 and active_symmetric_diff == 0),
"trace_sha256": arrhash(trace), "runtime_wall_seconds": run["wall_seconds"],
"audit_wall_seconds": time.perf_counter()-start}
if not row["exact_eligibility"]:
err = np.abs(value-recorded)
j = int(np.argmax(err)) if len(err) else None
row["first_edge_mismatch"] = None if j is None else {
"edge_id": int(rec.edge_id.iloc[j]), "KC_neuron_idx": int(src[local[j]]),
"DAN_pulse_ms": float(mcfg["protocol"]["dan_time_ms"]),
"observed_trace": float(value[j]), "frozen_trace": float(recorded[j]),
"delta_trace": float(value[j]-recorded[j])}
if len(first_failures) < 20:
first_failures.append(row)
path = EXP / "eligibility-replay" / f"mismatch-repeat-{repeat}-seed-{seed}-pairing-{pairing}-KC-events.parquet"
path.parent.mkdir(parents=True,exist_ok=True)
run["kc_spikes"].to_parquet(path,index=False)
rows.append(row)
# Keep subsequent brain input equal to the sealed historical additive trajectory,
# even when a diagnostic trial diverged; no frozen state is ever overwritten.
sealed_trace = np.zeros(len(v.kc), np.float32)
sealed_trace[loc[local]] = recorded
delta, _ = apply_v2(v, sealed_trace, target, 1.0, delta, cfg)
if pairing % 20 == 0:
save(EXP / "eligibility-replay/reproducibility-matrix.json", rows)
print(json.dumps({"repeat":repeat,"seed":seed,"pairing":pairing,
"exact_in_block":sum(r["exact_eligibility"] for r in rows[-20:]),
"event_repeat_exact_in_block":sum(r["KC_events_same_as_first_repeat"] for r in rows[-20:])}),flush=True)
save(EXP / "eligibility-replay/reproducibility-matrix.json", rows)
save(EXP / "eligibility-replay/summary.json", {"complete_repeats": args.repeats, "trials_per_repeat":500,
"exact_frozen_eligibility_count":sum(r["exact_eligibility"] for r in rows),
"exact_repeat_event_count":sum(r["KC_events_same_as_first_repeat"] for r in rows),
"all_exact":all(r["exact_eligibility"] and r["KC_events_same_as_first_repeat"] for r in rows),
"first_failures":first_failures,
"historical_training_KC_event_sequence_available":False,
"phase4n_event_sequence_used_as_comparator":True,
"note":"Phase4M sealed only eligibility/update history, not all training KC events; Phase4N KC events are a later audit comparator."})
if __name__ == "__main__": main()
@@ -0,0 +1,119 @@
#!/usr/bin/env python3
"""Exact-order replay of all frozen Phase 4N KC events through Phase 4M eligibility."""
from __future__ import annotations
import hashlib
import json
import math
from pathlib import Path
import numpy as np
import pandas as pd
import pyarrow.parquet as pq
import yaml
ROOT=Path('/data/digital-drosophila')
EXP=ROOT/'experiments/phase4o-runtime-credit'
MODEL=ROOT/'models/male-cns-lif'
def save(p,x):
p.parent.mkdir(parents=True,exist_ok=True)
p.write_text(json.dumps(x,indent=2,sort_keys=True,default=str)+'\n')
def h(x): return hashlib.sha256(x.tobytes()).hexdigest()
def main():
ncfg=yaml.safe_load((MODEL/'credit-assignment-v1/phase4n.yaml').read_text())
mcfg=yaml.safe_load((MODEL/'kcmbon-efficacy-v1/phase4m.yaml').read_text())
lcfg=yaml.safe_load(Path(mcfg['frozen_phase4l_config']).read_text())
cfg=lcfg
identity=pd.read_parquet(ROOT/'experiments/phase4n-credit-assignment/edge-identity/frozen-edge-identity.parquet')
historical=pd.read_parquet(Path(mcfg['experiment_root'])/'efficacy-overlay/update-history.parquet')
kc_events=pd.read_parquet(ROOT/'experiments/phase4n-credit-assignment/local-eligibility/KC-spike-history.parquet')
graph=Path(cfg['paths']['connectome_root'])
meta=pq.read_table(graph/'neuron-index/unified-metadata.parquet',columns=['neuron_idx','annotation_class']).to_pandas()
kc=meta.loc[meta.annotation_class=='Kenyon_Cell','neuron_idx'].to_numpy(np.int32)
kc.sort()
lookup=np.full(len(meta),-1,np.int32);lookup[kc]=np.arange(len(kc),dtype=np.int32)
src=identity.source_neuron_idx.to_numpy(np.int32);local=lookup[src]
if (local<0).any(): raise RuntimeError('non-KC edge source')
comp=identity.compartment.astype(str).to_numpy()==str(ncfg['matched_compartment_verbatim'])
edgeid=identity.edge_id.to_numpy(np.int64)
id_to_local=pd.Series(np.arange(len(identity),dtype=np.int32),index=edgeid)
events={(int(seed),int(pair)):group[['step','neuron_idx']].to_numpy(np.int32)
for (seed,pair),group in kc_events.groupby(['seed','pairing'])}
histories={(int(seed),int(pair)):group for (seed,pair),group in historical.groupby(['train_seed','pairing'])}
dt=float(cfg['model']['dt_ms']);tau=float(cfg['eligibility_v2']['kc_trace_tau_ms'])
decay=np.float32(math.exp(-dt/tau));step_gate=int(round(float(mcfg['protocol']['dan_time_ms'])/dt))
k=np.float32(cfg['eligibility_v2']['eta_effective_mv']/cfg['model']['w_syn_mv_per_anatomical_synapse'])
bound=np.float32(1.0-cfg['eligibility_v2']['max_fractional_depression'])
results=[];first_signatures={};mismatch_examples=[]
for repeat in range(5):
for seed in ncfg['train_seeds']:
E=np.ones(len(identity),np.float32)
for pairing in range(1,101):
arr=events.get((seed,pairing),np.empty((0,2),np.int32))
# Phase4N emitted events in simulation-time, then neuron_idx order.
if len(arr) and (np.any(arr[:,0]<0) or np.any(arr[:,0]>=int(round(mcfg['protocol']['duration_ms']/dt)))): raise RuntimeError('invalid event timestamp')
if len(arr)>1 and (np.any(arr[1:,0]<arr[:-1,0]) or np.any((arr[1:,0]==arr[:-1,0])&(arr[1:,1]<=arr[:-1,1]))): raise RuntimeError('event tie/duplicate/order ambiguity')
relevant=arr[arr[:,0]<=step_gate]
if len(relevant) and (lookup[relevant[:,1]]<0).any(): raise RuntimeError('non-KC event')
by_step={int(step):lookup[relevant[relevant[:,0]==step,1]] for step in np.unique(relevant[:,0])}
trace=np.zeros(len(kc),np.float32)
for step in range(step_gate+1):
trace*=decay
firing=by_step.get(step)
if firing is not None: trace[firing]+=np.float32(1)
np.minimum(trace,np.float32(1),out=trace)
rec=histories[(seed,pairing)]
rid=id_to_local.loc[rec.edge_id.to_numpy(np.int64)].to_numpy(np.int32)
observed=trace[local[rid]]
expected=rec.eligibility.to_numpy(np.float32)
err=np.abs(observed-expected)
actual=np.flatnonzero(comp&(trace[local]>0))
missing=np.setdiff1d(rid,actual,assume_unique=True)
extra=np.setdiff1d(actual,rid,assume_unique=True)
predicted=np.maximum(bound,E[rid]*(np.float32(1)-k*observed))
frozen_after=rec.E_bounded_after.to_numpy(np.float32)
update_error=float(np.max(np.abs(predicted-frozen_after))) if len(predicted) else 0.0
trace_error=float(err.max()) if len(err) else 0.0
signature=h(np.concatenate((arr.flatten(),observed.view(np.int32),predicted.view(np.int32))))
key=(seed,pairing)
first_signatures.setdefault(key,signature)
row={'repeat':repeat,'seed':seed,'pairing':pairing,'event_count':len(arr),'event_sha256':h(arr),
'gate_step':step_gate,'eligibility_sha256':h(observed),'update_sha256':h(predicted),
'repeat_exact':signature==first_signatures[key],
'frozen_trace_max_abs_error':trace_error,'frozen_update_max_abs_error':update_error,
'missing_frozen_active_edges':len(missing),'extra_active_edges':len(extra),
'exact_to_phase4m':trace_error<=2e-5 and update_error<=2e-5 and len(missing)==0 and len(extra)==0}
if not row['exact_to_phase4m'] and len(mismatch_examples)<30:
j=int(np.argmax(err)) if len(err) else None
row['example']={'edge_id':int(rec.edge_id.iloc[j]) if j is not None else None,
'KC_neuron_idx':int(src[rid[j]]) if j is not None else None,
'timestamp_ms':float(mcfg['protocol']['dan_time_ms']),
'event_trace':float(observed[j]) if j is not None else None,
'frozen_trace':float(expected[j]) if j is not None else None,
'frozen_delta_E':float(frozen_after[j]-rec.E_bounded_before.iloc[j]) if j is not None else None,
'missing_edge_ids':edgeid[missing[:20]].tolist(),'extra_edge_ids':edgeid[extra[:20]].tolist()}
mismatch_examples.append(row.copy())
results.append(row)
# Each trial is run against the sealed Phase4M before/after trajectory.
# A divergent diagnostic event trace never feeds the next trial.
E[rid]=frozen_after
print(json.dumps({'repeat':repeat,'seed':seed,'total_so_far':len(results),
'exact_to_phase4m_so_far':sum(r['exact_to_phase4m'] for r in results)}),flush=True)
save(EXP/'eligibility-replay/event-reproducibility-matrix.json',results)
save(EXP/'eligibility-replay/event-reproducibility-matrix.json',results)
save(EXP/'eligibility-replay/event-replay-summary.json',{'complete_repeats':5,'events_per_repeat':500,
'same_event_and_update_sequence_5_of_5':all(r['repeat_exact'] for r in results),
'all_exact_to_frozen_phase4m':all(r['exact_to_phase4m'] for r in results),
'frozen_exact_count_by_repeat':{str(rep):sum(r['exact_to_phase4m'] for r in results if r['repeat']==rep) for rep in range(5)},
'mismatch_examples':mismatch_examples,
'event_order_contract_observed':'simulation_step ascending, neuron_idx ascending, no duplicate KC/step; trace updated after spike; external gate sampled after step 900 trace update',
'limitation':'Phase4M did not seal its training KC event sequence. Phase4N sealed the later event replay; exact repeat of those events does not prove the original GPU trajectory.'})
if __name__=='__main__':main()
@@ -0,0 +1,142 @@
#!/usr/bin/env python3
"""Fail-closed Phase 4O-A synthesis, frozen checks, and SHA-256 sealing."""
from __future__ import annotations
import json
import shutil
from pathlib import Path
from phase4h_audit import verify_checksum
from phase4k import dataset_checks,seal
from phase4m import frozen_checks,frozen_hashes
from phase4n import load_config
from phase4o_a import EXP,MODEL,ROOT,save,sha
def read(path): return json.loads(path.read_text())
def frozen_integrity():
ncfg,mcfg,cfg,_=load_config(ROOT/'models/male-cns-lif/credit-assignment-v1/phase4n.yaml')
checks={}
for label,root,rel in [
('Phase4M experiment',Path(mcfg['experiment_root']),'manifests/checksums.sha256'),
('Phase4M model',Path(mcfg['model_root']),'checksums.sha256'),
('Phase4N experiment',Path(ncfg['experiment_root']),'manifests/checksums.sha256'),
('Phase4N model',Path(ncfg['model_root']),'checksums.sha256')]:
checks[label]=verify_checksum(root,root/rel)
earlier=frozen_checks(cfg)
datasets=dataset_checks(cfg)
current=frozen_hashes(cfg)
saved=read(Path(mcfg['experiment_root'])/'audit/final-summary.json')['integrity']['after']
report={'Phase4C_to_4L':earlier,'Phase4M_4N':checks,'Phase1_to_3B':datasets,
'frozen_input_hashes_unchanged':current==saved,
'all_static_checks_passed':bool(earlier['all_passed'] and datasets['all_passed'] and
all(x['passed'] for x in checks.values()) and current==saved)}
save(EXP/'audit/frozen-integrity-final.json',report)
return report
def main():
matrix=read(EXP/'phase4c-replay/summary.json')
replay=read(EXP/'eligibility-replay/event-replay-summary.json')
targeted=read(EXP/'eligibility-replay/targeted-summary.json')
atomic=read(EXP/'atomic/real-edge-subset.json')
backend=read(EXP/'binary-audit/loaded-backend.json')
environment=read(EXP/'environment/runtime-environment.json')
modes={p.stem:read(p) for p in sorted((EXP/'divergence').glob('mode-*.json'))}
matched=next(x for x in modes.values() if x['mode']=='instrumentation-on' and x['repeat']==1)
divergent=next(x for x in modes.values() if x['mode']=='instrumentation-on' and x['repeat']==0)
def state(run,step,when):
return next(x for x in run['state_window'] if x['step']==step and x['when']==when)
state_report={'first_observed_spike_event_divergence_step':6625,
'first_observed_divergent_neuron_idx':3942,
'biological_time_ms':662.5,
'pre_step_6625_matched':{k:state(matched,6625,'before')[k] for k in ('voltage','g','arrival_buffer','refractory')},
'pre_step_6625_divergent':{k:state(divergent,6625,'before')[k] for k in ('voltage','g','arrival_buffer','refractory')},
'matched_after_step_6625_voltage':state(matched,6625,'after')['voltage'],
'divergent_after_step_6625_voltage':state(divergent,6625,'after')['voltage'],
'matched_spiked_step_6625':bool(state(matched,6625,'after')['focus_spiked']),
'divergent_spiked_step_6625':bool(state(divergent,6625,'after')['focus_spiked']),
'matched_spiked_step_6626':bool(state(matched,6626,'after')['focus_spiked']),
'tracked_neuron_state_already_differs_by_step':6619,
'first_global_floating_state_divergence_exactly_located':False,
'classification':'FLOAT-ORDER-THRESHOLD-BIFURCATION'}
save(EXP/'divergence/first-divergence-forensic.json',state_report)
source=ROOT/'models/male-cns-lif/runtime-v1'
old_build=ROOT/'experiments/phase4c-runtime/compiler-reports/extension-build'
new_build=EXP/'compiler-reports/extension-build'
binary={'frozen_runtime_source_sha256':{x:sha(source/x) for x in ('phase4c.py','phase4c_ext.cpp','phase4c_ext.cu','phase4c.yaml')},
'historical_extension_sha256':sha(old_build/'male_cns_lif_runtime_v1_ext.so'),
'current_loaded_extension_sha256':backend['binary_sha256'],
'binary_bytewise_same':sha(old_build/'male_cns_lif_runtime_v1_ext.so')==backend['binary_sha256'],
'historical_build_ninja_sha256':sha(old_build/'build.ninja'),
'current_build_ninja_sha256':sha(new_build/'build.ninja'),
'toolkit_path_historical':'/usr/local/cuda-12.6',
'toolkit_path_current':'/usr/local/cuda',
'toolkit_realpath_current':'/usr/local/cuda-12.6',
'source_and_arch_flags_unchanged_except_absolute_build_paths':True,
'interpretation':'ELF hashes differ; build manifests differ in absolute source/toolkit paths while /usr/local/cuda resolves to CUDA 12.6. No proof that binary difference caused the stochastic bifurcation.'}
save(EXP/'binary-audit/runtime-binary-diff-report.json',binary)
rows=read(EXP/'phase4c-replay/reproducibility-matrix.json')
rng={'input_generator_before_first_unique_hashes_by_trial':{},'input_generator_after_trial_unique_hashes_by_trial':{}}
for trial in matrix['trial_summary']:
subset=[x for x in rows if x['trial']==trial]
rng['input_generator_before_first_unique_hashes_by_trial'][trial]=len({x['rng_before_first_timestep']['input_generator'] for x in subset})
rng['input_generator_after_trial_unique_hashes_by_trial'][trial]=len({x['rng_after_trial']['input_generator'] for x in subset})
rng['mechanosensory_input_generator_states_identical_in_all_10_repeats']=rng['input_generator_before_first_unique_hashes_by_trial']['mechanosensory-50hz']==1 and rng['input_generator_after_trial_unique_hashes_by_trial']['mechanosensory-50hz']==1
save(EXP/'rng/summary.json',rng)
integrity=frozen_integrity()
# Frozen Phase4C spike 49/50 and frozen Phase4M eligibility 498/500 each
# independently fail the conjunctive Part A gate. No Part B is executed.
gate={'five_phase4c_trials_10_of_10_spike_events_exact':matrix['all_spike_events_exact'],
'five_phase4c_trials_10_of_10_per_neuron_counts_exact':matrix['all_counts_exact'],
'mechanosensory_divergence_absent':matrix['trial_summary']['mechanosensory-50hz']['event_exact']==10,
'phase4m_500_eligibility_5_complete_repeats_exact_to_frozen':replay['all_exact_to_frozen_phase4m'],
'event_sequence_repeated_exactly_5_of_5':replay['same_event_and_update_sequence_5_of_5'],
'instrumentation_independence':False,
'logging_independence_proven':False,
'backend_identity_fixed':True,
'frozen_static_integrity':integrity['all_static_checks_passed']}
passed=all(gate[k] for k in ('five_phase4c_trials_10_of_10_spike_events_exact','five_phase4c_trials_10_of_10_per_neuron_counts_exact',
'mechanosensory_divergence_absent','phase4m_500_eligibility_5_complete_repeats_exact_to_frozen',
'instrumentation_independence','logging_independence_proven','backend_identity_fixed','frozen_static_integrity'))
result={'phase':'4O-A','status':'PASS-RUNTIME-DETERMINISM-RECOVERED' if passed else 'FAIL-RUNTIME-DETERMINISM',
'phase4o_b_executed':False,'deterministic_runtime_candidate_generated':False,
'phase4c_repeat_matrix':matrix['trial_summary'],
'first_divergence':state_report,
'root_cause':'Concurrent GPU scatter_add_ floating reduction order varies on real CSR fan-out; a few-ULP g/V difference at neuron 3942 crosses the -45 mV threshold one timestep earlier. Exact first floating-state operation before step 6619 is not located.',
'atomic_real_event_subset':{k:atomic[k] for k in ('fanout_edges','targets_with_multiple_concurrent_writes','maximum_same_target_writes','targets_with_nonidentical_atomic_sum_across_100_repeats','max_atomic_sum_range_mv')},
'eligibility_replay':{'same_sequence_5_of_5':replay['same_event_and_update_sequence_5_of_5'],
'frozen_exact_count_by_repeat':replay['frozen_exact_count_by_repeat'],
'mismatch_seed_pairing':[[51202,40],[51203,39]],
'mismatch_KC_neuron_idx':78836,
'mismatch_trace_absolute_error':0.12266039848327637,
'targeted_GPU':targeted,
'cause':'KC spike at step 899 versus step 904 around the step-900 external US. Offline event ordering and trace update are repeat-exact; upstream LIF trajectory bifurcates.'},
'RNG':rng,'backend':backend,'binary_audit':binary,'environment':{'torch':environment['torch'],'cuda_runtime':environment['cuda_runtime'],
'nvcc':environment['nvcc']['stdout'],'driver_gpu':environment['nvidia_smi']['stdout']},
'mode_matrix':{k:{x:v for x,v in m.items() if x not in ('state_window','backend')} for k,m in modes.items()},
'part_a_gate':gate,'frozen_static_integrity':integrity['all_static_checks_passed'],
'limitations':['A single exact first global floating-state divergence operation was not localized; tracked neuron 3942 already differs at step 6619.',
'Historical Phase4M training KC events were not sealed, so the two historical event timelines cannot be directly replayed byte-for-byte.',
'Logging OFF has final-state/count comparison only; no event sequence was recorded by design.'],
'part_b_not_started_reason':'Part A conjunctive PASS gate failed; eligibility-v3 calibration, learning controls and candidates are prohibited.'}
save(EXP/'audit/final-summary.json',result)
if Path(__file__).resolve() != (MODEL/'phase4o_finalize.py').resolve():
shutil.copy2(Path(__file__),MODEL/'phase4o_finalize.py')
if Path(__file__).with_name('phase4o.yaml').resolve() != (MODEL/'phase4o.yaml').resolve():
shutil.copy2(Path(__file__).with_name('phase4o.yaml'),MODEL/'phase4o.yaml')
save(MODEL/'VERSION.json',{'name':'MaleCNS-runtime-credit-v1-audit','phase':'4O-A','status':result['status'],
'runtime_v2_deterministic_candidate_generated':False,'eligibility_v3_experimental_started':False,
'frozen_runtime_v1_overwritten':False,'summary_sha256':sha(EXP/'audit/final-summary.json')})
seal(MODEL,MODEL/'MANIFEST.json',MODEL/'checksums.sha256')
seal(EXP,EXP/'manifests/manifest.json',EXP/'manifests/checksums.sha256')
own={'model':verify_checksum(MODEL,MODEL/'checksums.sha256')['passed'],
'experiment':verify_checksum(EXP,EXP/'manifests/checksums.sha256')['passed']}
print(json.dumps({'status':result['status'],'part_B_executed':False,'phase4c':matrix['trial_summary'],
'eligibility_5_repeats':replay['frozen_exact_count_by_repeat'],
'static_integrity':integrity['all_static_checks_passed'],'own_sha256':own},indent=2),flush=True)
if __name__=='__main__':main()
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""Mechanosensory runtime mode matrix and optional state-window forensics."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
from pathlib import Path
import numpy as np
import pyarrow.parquet as pq
import torch
import yaml
from phase4o_a import EXP,FROZEN,ROOT,sha,first_event_diff,save
NAME='mechanosensory-50hz'
SEED=42003
def run(mode: str, focus_step: int, focus_neuron: int):
from brain_runtime import BrainRuntime
from phase4i import poisson_batch
cfgpath=ROOT/'models/male-cns-lif/mb-mechanistic-v1/phase4i.yaml'
if mode=='deterministic-flags':
torch.use_deterministic_algorithms(True)
torch.backends.cudnn.deterministic=True
torch.backends.cudnn.benchmark=False
torch.backends.cudnn.allow_tf32=False
torch.backends.cuda.matmul.allow_tf32=False
torch.set_float32_matmul_precision('highest')
rt=BrainRuntime(cfgpath,EXP/'compiler-reports/extension-build')
target=np.flatnonzero(rt.population_masks['mechanosensory']).astype(np.int64)
refroot=FROZEN/NAME
ref=pq.read_table(refroot/'spike-events.parquet')
rstep=ref['step'].to_numpy().astype(np.int32);rnode=ref['neuron_idx'].to_numpy().astype(np.int32)
rcount=np.load(refroot/'per-neuron-spike-counts.int32.npy')
rv=np.load(refroot/'final-voltage.float32.npy');rg=np.load(refroot/'final-g.float32.npy')
rt.reset(SEED)
batch=poisson_batch(target,50.,1000.,NAME)
backend={'python_module':str(Path(rt.runtime_module.__file__)), 'python_sha256':sha(Path(rt.runtime_module.__file__)),
'extension':str(Path(rt.extension.__file__)), 'extension_sha256':sha(Path(rt.extension.__file__))}
window=[]
if mode in ('logging-off','logging-on'):
p4cfg=yaml.safe_load((ROOT/'models/male-cns-lif/runtime-v1/phase4c.yaml').read_text())
direct=rt.runtime_module.Runtime(p4cfg,rt.table,rt.indptr_np,rt.indices_np,rt.raw_np,rt.device,rt.extension)
out=direct.run('hybrid-exact',target,50.,SEED,1000.,capture_events=(mode=='logging-on'))
step=out['event_steps'];node=out['event_nodes'];counts=out['counts'];v=out['v'];g=out['g']
elif mode in ('instrumentation-on','single-stream-sync'):
for t in range(10000):
oldlen=len(rt.spike_steps)
if mode=='instrumentation-on' and focus_step-6<=t<=focus_step+5 and focus_neuron>=0:
slot=t%rt.queue_len
window.append({'step':t,'when':'before','neuron_idx':focus_neuron,
'voltage':float(rt.v[focus_neuron].item()),'g':float(rt.g[focus_neuron].item()),
'refractory':int(rt.refractory[focus_neuron].item()),
'arrival_buffer':float(rt.delay_queue[slot,focus_neuron].item()),
'ring_buffer_sha256':hashlib.sha256(rt.delay_queue.cpu().numpy().tobytes()).hexdigest()})
rt.step(batch,0.1)
torch.cuda.synchronize()
if mode=='instrumentation-on' and focus_step-6<=t<=focus_step+5 and focus_neuron>=0:
new_nodes=np.concatenate(rt.spike_nodes[oldlen:]) if len(rt.spike_nodes)>oldlen else np.empty(0,np.int32)
window.append({'step':t,'when':'after','neuron_idx':focus_neuron,
'voltage':float(rt.v[focus_neuron].item()),'g':float(rt.g[focus_neuron].item()),
'refractory':int(rt.refractory[focus_neuron].item()),'focus_spiked':int(focus_neuron in new_nodes),
'active_presynaptic_count':len(new_nodes),
'fanout_edge_count':int(np.sum(rt.indptr_np[new_nodes+1]-rt.indptr_np[new_nodes])) if len(new_nodes) else 0,
'active_presynaptic_neuron_idx':new_nodes.tolist()[:500]})
events=rt.read_spikes();step=events['step'].astype(np.int32);node=events['neuron_idx'].astype(np.int32)
counts=rt.spike_counts.cpu().numpy().astype(np.int32);v=rt.v.cpu().numpy();g=rt.g.cpu().numpy()
else:
rt.step(batch,1000.)
events=rt.read_spikes();step=events['step'].astype(np.int32);node=events['neuron_idx'].astype(np.int32)
counts=rt.spike_counts.cpu().numpy().astype(np.int32);v=rt.v.cpu().numpy();g=rt.g.cpu().numpy()
event_known=mode!='logging-off'
result={'mode':mode,'backend':backend,'logging_events_captured':event_known,
'spike_events_exact':bool(np.array_equal(step,rstep) and np.array_equal(node,rnode)) if event_known else None,
'per_neuron_counts_exact':bool(np.array_equal(counts,rcount)),
'final_voltage_max_abs_error':float(np.max(np.abs(v-rv))),
'final_g_max_abs_error':float(np.max(np.abs(g-rg))),
'first_event_difference':first_event_diff(rstep,rnode,step,node) if event_known else None,
'event_sha256':hashlib.sha256(step.tobytes()+node.tobytes()).hexdigest() if event_known else None,
'count_sha256':hashlib.sha256(counts.tobytes()).hexdigest(),
'torch_deterministic_algorithms':torch.are_deterministic_algorithms_enabled(),
'CUBLAS_WORKSPACE_CONFIG':os.getenv('CUBLAS_WORKSPACE_CONFIG'),
'state_window':window}
return result
def main():
ap=argparse.ArgumentParser();ap.add_argument('mode',choices=['default','logging-off','logging-on','instrumentation-off','instrumentation-on','single-stream-sync','deterministic-flags'])
ap.add_argument('--focus-step',type=int,default=-1000);ap.add_argument('--focus-neuron',type=int,default=-1)
ap.add_argument('--repeat',type=int,default=0);a=ap.parse_args()
try: result=run(a.mode,a.focus_step,a.focus_neuron)
except Exception as exc: result={'mode':a.mode,'error':repr(exc),'unsupported_or_failed':True}
result['repeat']=a.repeat
save(EXP/'divergence'/f'mode-{a.mode}-repeat-{a.repeat}.json',result)
print(json.dumps({k:result.get(k) for k in ('mode','repeat','spike_events_exact','per_neuron_counts_exact','first_event_difference','error')}),flush=True)
if __name__=='__main__':main()
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""Targeted GPU replays of the two Phase 4N/4M eligibility discrepancies."""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import numpy as np
import pandas as pd
import torch
from phase4n import load_config
from phase4i import Validator
from phase4j import apply_v2
from phase4l import OdorSimulator,pn_drive
from phase4m import load_odor_inputs
from phase4o_a import EXP,ROOT,save
def main():
ncfg,mcfg,cfg,cfgpath=load_config(ROOT/'models/male-cns-lif/credit-assignment-v1/phase4n.yaml')
history=pd.read_parquet(Path(mcfg['experiment_root'])/'efficacy-overlay/update-history.parquet')
by={(int(s),int(p)):g for (s,p),g in history.groupby(['train_seed','pairing'])}
v=Validator(cfg,cfgpath,EXP);sim=OdorSimulator(v,cfg,EXP)
panel,vectors,selection,mapping=load_odor_inputs(cfg)
oid=selection['ODOR_A']['odor_id']
pn=pn_drive(oid,vectors[oid],mapping,selection['glomeruli_order'],str(mcfg['protocol']['input_mode']),float(np.median(panel.mapped_response_sum)),cfg)[:2]
target=str(mcfg['protocol']['target_compartment_verbatim'])
dan=v.dan_targets(str(mcfg['protocol']['matched_dan_type']),target)
lookup=np.full(v.n,-1,np.int32);lookup[v.kc]=np.arange(len(v.kc),dtype=np.int32)
loc=lookup[v.cand.source_neuron_idx.to_numpy(np.int32)]
eid_to_local=pd.Series(np.arange(len(v.edge_ids),dtype=np.int32),index=v.edge_ids.astype(np.int64))
rows=[]
for seed,pairing in [(51202,40),(51203,39)]:
delta=np.zeros(len(v.edge_ids),np.float32)
for p in range(1,pairing):
rec=by[(seed,p)]
local=eid_to_local.loc[rec.edge_id.to_numpy(np.int64)].to_numpy(np.int32)
frozen_trace=np.zeros(len(v.kc),np.float32)
frozen_trace[loc[local]]=rec.eligibility.to_numpy(np.float32)
delta,_=apply_v2(v,frozen_trace,target,1.,delta,cfg)
rec=by[(seed,pairing)]
local=eid_to_local.loc[rec.edge_id.to_numpy(np.int64)].to_numpy(np.int32)
old_trace=rec.eligibility.to_numpy(np.float32)
for repeat in range(15):
run=sim.run_rates(*pn,seed+pairing,float(mcfg['protocol']['duration_ms']),delta=delta,dan_targets=dan,
dan_pulses=[float(mcfg['protocol']['dan_time_ms'])],collect_kc_spikes=True)
observed=run['kc_trace_at_dan'][loc[local]]
diff=np.abs(observed-old_trace)
j=int(np.argmax(diff)) if len(diff) else None
events=run['kc_spikes'][['step','neuron_idx']].to_numpy(np.int32)
row={'seed':seed,'pairing':pairing,'repeat':repeat,'event_count':len(events),
'event_sha256':hashlib.sha256(events.tobytes()).hexdigest(),
'trace_sha256':hashlib.sha256(observed.tobytes()).hexdigest(),
'max_abs_error_vs_frozen':float(diff.max()) if len(diff) else 0.,
'exact_to_frozen':bool(len(diff)==0 or float(diff.max())<=2e-5),
'first_largest_error_edge_id':int(rec.edge_id.iloc[j]) if j is not None else None,
'first_largest_error_KC_neuron_idx':int(v.cand.source_neuron_idx.iloc[local[j]]) if j is not None else None,
'observed_eligibility':float(observed[j]) if j is not None else None,
'frozen_eligibility':float(old_trace[j]) if j is not None else None,
'wall_seconds':run['wall_seconds']}
rows.append(row)
print(json.dumps({'seed':seed,'pairing':pairing,'repeat':repeat,'exact':row['exact_to_frozen'],
'event_sha256':row['event_sha256'][:12]}),flush=True)
save(EXP/'eligibility-replay/targeted-gpu-repeats.json',rows)
save(EXP/'eligibility-replay/targeted-summary.json',{'rows':len(rows),
'exact_count':sum(r['exact_to_frozen'] for r in rows),
'distinct_event_hashes_by_trial':{f'{s}/{p}':len({r['event_sha256'] for r in rows if r['seed']==s and r['pairing']==p}) for s,p in [(51202,40),(51203,39)]},
'same_seed_config_and_sealed_additive_prefix':True,
'note':'This is an isolated 15-repeat targeted diagnostic of the two formerly discrepant trials, not a 5x500 complete brain rerun.'})
if __name__=='__main__':main()