Files
digital-drosophila/models/male-cns-lif/apl-timing-lab-v1/calibration.py
T
2026-09-30 12:08:25 +08:00

369 lines
22 KiB
Python

"""Read-only two-arm CAL aggregation using the sealed, full original 4L gate.
No trajectory is generated here. Representation failure never selects an arm
or suppresses the other arm. Timing checks use direct slices, not either
runtime's queue, and old scientific outputs are never modified.
"""
from __future__ import annotations
import csv
import hashlib
import importlib.util
import json
from pathlib import Path
import sys
import numpy as np
LEGACY_SHA256 = "edb9cb2d890471fd07afd88c959ef3540b0cd40af490fac3f26396b5e7f5bf9c"
STATE_DTYPES = {"step": np.int32, "neuron_idx": np.int32, "counts": np.int32,
"v": np.float64, "g": np.float64, "ref": np.int32}
APL_FILES = {"apl-drive.float32.npy": 2, "apl-state.float32.npy": 2,
"apl-inhibition.float32.npy": 4064}
REQUEST_FIELDS = ("tick", "neuron_idx", "attempted", "accepted", "rejected")
_DEFAULT_OUTPUT = object()
def require(ok, message):
if not ok:
raise ValueError(message)
def read_json(path):
return json.loads(Path(path).read_text(encoding="utf-8"))
def file_hash(path):
value = hashlib.sha256()
with Path(path).open("rb") as stream:
for block in iter(lambda: stream.read(8 << 20), b""):
value.update(block)
return value.hexdigest()
def raw_hash(value):
return hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()
def bit_equal(a, b):
return bool(a.dtype == b.dtype and a.shape == b.shape and
np.array_equal(np.ascontiguousarray(a).view(np.uint8),
np.ascontiguousarray(b).view(np.uint8)))
def load_legacy(path=None):
"""Load the sealed pure functions, without rebinding any old global/path."""
if path is None:
from context import AG_MODEL
path = AG_MODEL / "calibration.py"
path = Path(path)
require(file_hash(path) == LEGACY_SHA256, "Sealed AG calibration source changed")
spec = importlib.util.spec_from_file_location("sealed_ag_calibration_for_aj", path)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
return module
def _jsonl(path):
with Path(path).open(encoding="utf-8") as stream:
return [json.loads(line) for line in stream if line.strip()]
def _request_rows(path):
with Path(path).open(encoding="utf-8", newline="") as stream:
reader = csv.DictReader(stream)
require(tuple(reader.fieldnames or ()) == REQUEST_FIELDS, "Request schema mismatch")
return [{key: int(row[key]) for key in REQUEST_FIELDS} for row in reader]
def _component(directory):
gpu, oracle = directory / "apl-component.json", directory / "apl-worker-handshake.json"
require(gpu.is_file() != oracle.is_file(), "Exactly one backend APL provenance file is required")
return read_json(gpu) if gpu.is_file() else read_json(oracle)["handshake"]
def control_identity(newdir, olddir, case):
"""Compare delay0 scientific evidence with sealed AG, for fixtures or CAL.
case is the NEW case directory. Summary paths, budgets, build/wall times and
new adapter metadata are deliberately not compared. Missing evidence raises;
numerical differences return pass_all=False with each failed check retained.
"""
newdir, olddir, case = Path(newdir), Path(olddir), Path(case)
spec = read_json(case / "spec.json")
require(type(spec.get("apl_delay_steps")) is int and spec["apl_delay_steps"] == 0,
"Control identity is defined only for explicit delay0")
fresh, old = read_json(newdir / "summary.json"), read_json(olddir / "summary.json")
require(all(row.get("complete") is True and row.get("pass_all") is True for row in (fresh, old)),
"Cannot compare incomplete/failed control evidence")
require(all(row.get("steps") == spec["steps"] and row.get("completed_ticks") == spec["steps"] and
row.get("case", row.get("name")) == spec["name"] for row in (fresh, old)),
"Control case identity/completion changed")
checks = {}
with np.load(newdir / "state.npz", allow_pickle=False) as aa, np.load(olddir / "state.npz", allow_pickle=False) as bb:
require(set(aa.files) == set(bb.files) == set(STATE_DTYPES), "Control state schema mismatch")
for name, dtype in STATE_DTYPES.items():
first, second = aa[name], bb[name]
require(first.dtype == second.dtype == dtype and first.ndim == second.ndim == 1 and
np.isfinite(first).all() and np.isfinite(second).all(), "Invalid control state: " + name)
checks["state/" + name] = bit_equal(first, second)
for name, width in APL_FILES.items():
first, second = (np.load(folder / name, mmap_mode="r", allow_pickle=False) for folder in (newdir, olddir))
require(first.dtype == second.dtype == np.float32 and first.shape == second.shape == (spec["steps"], width)
and np.isfinite(first).all() and np.isfinite(second).all(), "Invalid control APL trace: " + name)
checks[name] = bit_equal(first, second)
for name in ("tick-state-hashes.jsonl", "queue.jsonl"):
first, second = _jsonl(newdir / name), _jsonl(olddir / name)
require(len(first) == len(second) == spec["steps"] and all(
[row.get("tick") for row in rows] == list(range(spec["steps"])) for rows in (first, second)),
"Incomplete control tick record: " + name)
checks[name] = first == second
checks["requests.csv"] = _request_rows(newdir / "requests.csv") == _request_rows(olddir / "requests.csv")
checks["APL_component"] = _component(newdir) == _component(olddir)
require(isinstance(old.get("effective_weights_raw_sha256"), str) and
len(old["effective_weights_raw_sha256"]) == 64, "Missing old effective-weight evidence")
checks["effective_weights_raw_sha256"] = fresh.get("effective_weights_raw_sha256") == old["effective_weights_raw_sha256"]
for key in ("nodes", "edges", "precision", "apl_fast_edges_zeroed", "kc_targets_present"):
require(key in fresh and key in old, "Missing control summary scientific field: " + key)
checks["summary/" + key] = fresh[key] == old[key]
if spec["record_history"]:
for prefix in ("", "preAPL-"):
for field, dtype in (("v", "float64"), ("g", "float64"), ("ref", "int32")):
name = f"{prefix}{field}-history.{dtype}.npy" if not prefix else f"{prefix}{field}.{dtype}.npy"
first, second = (np.load(folder / name, mmap_mode="r", allow_pickle=False) for folder in (newdir, olddir))
checks[name] = bit_equal(first, second)
# CPU oracle also saves actual effective Brian weights. GPU has only the
# raw effective-weight digest, already compared above.
if (newdir / "weights.npy").exists() or (olddir / "weights.npy").exists():
require((newdir / "weights.npy").is_file() and (olddir / "weights.npy").is_file(),
"Control backend weight-file presence differs")
checks["weights.npy"] = bit_equal(np.load(newdir / "weights.npy", mmap_mode="r"),
np.load(olddir / "weights.npy", mmap_mode="r"))
return {"pass_all": bool(all(checks.values())), "case": spec["name"], "checks": checks,
"scope": "Six state arrays, all tick hashes/queues/requests, generated APL, component, effective weights and fixture pre/post histories",
"adapter_paths_budgets_and_runtime_metadata_compared": False}
def validate_timing(output, spec, trial):
"""Independently verify raw timing files and recorded audit, without a queue."""
output = Path(output)
steps, delay = spec["steps"], spec["apl_delay_steps"]
require(type(delay) is int and delay in (0, 18), "Invalid timing arm")
generated = trial["apl"]["apl-inhibition.float32.npy"]
applied = np.load(output / "apl-applied.float32.npy", mmap_mode="r", allow_pickle=False)
pending = np.load(output / "apl-pending-tail.float32.npy", mmap_mode="r", allow_pickle=False)
for name, value, shape in (("generated", generated, (steps, 4064)),
("applied", applied, (steps, 4064)), ("pending", pending, (delay, 4064))):
require(value.dtype == np.float32 and value.shape == shape and np.isfinite(value).all() and
np.all(value >= 0), "Invalid timing array " + name)
warmup, consumed, prefix = min(steps, delay), max(steps - delay, 0), max(delay - steps, 0)
require(np.all(applied[:warmup].view(np.uint32) == 0) and np.all(pending[:prefix].view(np.uint32) == 0),
"Timing initial padding must be positive zero")
require(bit_equal(applied[warmup:], generated[:consumed]) and bit_equal(pending[prefix:], generated[consumed:]),
"Timing transport is not an exact finite generated-sequence partition")
audit = read_json(output / "apl-timing-audit.json")
summary = read_json(output / "summary.json")
expected = {"pass_all": True, "apl_delay_steps": delay, "steps": steps,
"pending_generated_count": min(steps, delay), "pending_initial_zero_prefix": prefix,
"pending_application_tick_start": steps, "pending_application_tick_stop_exclusive": steps + delay,
"pending_generated_tick_start": consumed, "pending_generated_tick_stop_exclusive": steps,
"initial_padding_positive_zero": True, "sample_bits_preserved": True, "brain_tail_advanced": False,
"generated_trace": "apl-inhibition.float32.npy", "applied_trace": "apl-applied.float32.npy",
"pending_trace": "apl-pending-tail.float32.npy", "pending_raw_sha256": raw_hash(pending),
"pending_queue_drained": delay == 0, "finite_generated_sequence_only": True,
"future_apl_decay_or_feedback_generated": False, "closed_loop_branch_integrals_claimed_equal": False,
"biological_delay_measurement_claimed": False}
final_state = trial["apl"]["apl-state.float32.npy"][-1]
expected.update(final_apl_state_float32=final_state.tolist(),
final_apl_state_u32_bits=final_state.view(np.uint32).tolist(),
final_apl_state_nonzero=bool(np.any(final_state != 0)))
for key, value in expected.items():
require(key in audit and audit[key] == value and type(audit[key]) is type(value),
"Timing audit disagrees with independent data: " + key)
require(summary.get("apl_delay_steps") == delay and summary.get("apl_timing") == audit,
"Timing audit differs from GPU summary")
return {"applied": applied, "pending": pending, "audit": audit,
"report": {"pass_all": True, "apl_delay_steps": delay, "steps": steps,
"generated_applied_pending_bits_exact": True, "pending_generated_count": min(steps, delay),
"pending_initial_zero_prefix": prefix, "brain_tail_advanced": False}}
def timing_repeat(first, repeat, legacy):
result = legacy.exact_repeat(first, repeat)
result["checks"].update(apl_applied=bit_equal(first["timing"]["applied"], repeat["timing"]["applied"]),
apl_pending=bit_equal(first["timing"]["pending"], repeat["timing"]["pending"]),
timing_audit=first["timing"]["audit"] == repeat["timing"]["audit"])
result["pass_all"] = bool(all(result["checks"].values()))
result["scope"] += "; plus delayed applied h, finite pending tail and timing audit"
return result
def _case_spec(case, old_case, row, delay):
spec = read_json(case / "spec.json")
old = read_json(old_case / "spec.json")
require(type(spec.get("apl_delay_steps")) is int and spec["apl_delay_steps"] == delay,
"Case arm/delay mismatch")
require(set(spec) == set(old) | {"apl_delay_steps"}, "Unexpected case fields")
require(all(spec[key] == value for key, value in old.items() if key not in ("budget_root", "output_budget_bytes")),
"A scientific case field changed in addition to APL output delay")
require(spec["name"] == row["name"] and spec["kind"] == "calibration" and spec["steps"] == 1000 and
spec["duration_ms"] == 100.0 and spec["dt_ms"] == .1 and spec["training"] is False and
all(spec[key] == row[key] for key in ("mode", "odor_id", "odor_index", "seed")), "Invalid fixed CAL case")
for name in ("requests.npz", "pn-drive.npz"):
require(file_hash(case / name) == file_hash(old_case / name), "Frozen CAL input bytes changed: " + name)
return spec
def _read_new(legacy, output, case, spec, kc_globals, cfg):
trial = legacy.read_trial(output, case, spec, kc_globals, cfg["neurons"], cfg["edges"])
trial["timing"] = validate_timing(output, spec, trial)
return trial
def _provenance(output, name, repeat):
return {"case": name, "repeat": repeat, "sha256": {fname: file_hash(output / fname) for fname in
("state.npz", "summary.json", "tick-state-hashes.jsonl", "queue.jsonl", "requests.csv", "apl-component.json",
*APL_FILES, "apl-applied.float32.npy", "apl-pending-tail.float32.npy", "apl-timing-audit.json")}}
def collect_arm(arm, delay, records, odors, legacy, cfg, exp, ag, kc_globals):
failures, runs, rows, repeats, controls, provenance, timings, modes = [], {}, [], [], [], [], [], {}
for row in records:
name, first, spec = row["name"], None, None
case = exp / "cases" / arm / name
try:
spec = _case_spec(case, ag / "cases" / name, row, delay)
except Exception as error:
failures.append(dict(stage="case_spec", case=name, type=type(error).__name__, message=str(error)))
for repeat_index in ([0, 1] if row["seed"] == legacy.ORIGINAL_SEEDS[0] else [0]):
output = exp / "gpu" / arm / (name + "-r" + str(repeat_index))
try:
require(spec is not None, "Case spec unavailable")
trial = _read_new(legacy, output, case, spec, kc_globals, cfg)
require(trial["record"]["requested"] == row["requests"], "Inventory request count changed")
timings.append(dict(case=name, repeat=repeat_index, **trial["timing"]["report"]))
provenance.append(_provenance(output, name, repeat_index))
if repeat_index == 0:
first = trial
runs[(row["mode"], row["odor_id"], row["seed"])] = {key: first[key] for key in
("kc_counts", "expected_external_events", "external_events")}
rows.append(first["record"])
else:
require(first is not None, "Baseline unavailable for exact repeat")
report = dict(case=name, **timing_repeat(first, trial, legacy))
repeats.append(report)
require(report["pass_all"], "Exact repetition differs: " + ", ".join(
key for key, value in report["checks"].items() if not value))
if delay == 0:
control = control_identity(output, ag / "gpu" / (name + "-r" + str(repeat_index)), case)
controls.append(dict(repeat=repeat_index, **control))
require(control["pass_all"], "Delay0 differs from sealed AG: " + ", ".join(
key for key, value in control["checks"].items() if not value))
except Exception as error:
failures.append(dict(stage="raw_trial" if repeat_index == 0 else "repeat_trial", case=name,
repeat=repeat_index, type=type(error).__name__, message=str(error)))
# Each complete mode is still described even if the other mode/arm failed.
for mode in legacy.ORIGINAL_MODES:
needed = {(mode, odor, seed) for odor in odors for seed in legacy.ORIGINAL_SEEDS}
if needed.issubset(runs):
try:
modes[mode] = legacy.summarize_mode(mode, odors, legacy.ORIGINAL_SEEDS, runs, cfg["gates"])
except Exception as error:
failures.append(dict(stage="representation_calculation", mode=mode, type=type(error).__name__, message=str(error)))
numerical = bool(len(runs) == 60 and len(timings) == 72 and not any(
row["stage"] != "representation_calculation" for row in failures))
repeat_pass = bool(len(repeats) == 12 and all(row["pass_all"] for row in repeats))
control_pass = bool(delay != 0 or (len(controls) == 72 and all(row["pass_all"] for row in controls)))
representation = bool(len(modes) == 2 and all(row["gate"] for row in modes.values()))
execution = bool(numerical and repeat_pass and control_pass)
return {"arm": arm, "apl_delay_steps": delay, "pass_all": bool(execution and representation),
"execution_gate_pass": execution, "numerical_integrity_pass": numerical, "exact_repeat_pass": repeat_pass,
"control_identity_applicable": delay == 0, "delay0_control_identity_pass": control_pass if delay == 0 else None,
"original_representation_gate_pass": representation, "expected_base_trials": 60, "valid_base_trials": len(runs),
"expected_repeats": 12, "checked_repeats": len(repeats), "checked_timing_trials": len(timings),
"modes": modes, "runs": rows, "repeats": repeats, "timing_checks": timings,
"control_checks": controls, "failures": failures, "input_output_provenance": provenance}
def summarize(out_json=_DEFAULT_OUTPUT):
"""Default writes new evidence exclusively; out_json=None is pure recomputation."""
from context import EXP, AG, ROOT, CFG, check
target = EXP / "calibration/summary.json" if out_json is _DEFAULT_OUTPUT else (
None if out_json is None else Path(out_json))
require(target is None or not target.exists(), "Refusing existing calibration summary")
arms, failures, odors, encoder = {}, [], [], None
try:
check()
legacy = load_legacy()
require(CFG["delays_steps"] == [0, 18], "Fixed timing arms changed")
records = read_json(EXP / "protocol/calibration-cases.json")
require(file_hash(EXP / "protocol/calibration-cases.json") == file_hash(AG / "protocol/calibration-cases.json"),
"Original CAL inventory bytes changed")
odors = legacy.validate_inventory(records, CFG)
encoder = read_json(EXP / "protocol/encoder-audit.json")
require(file_hash(EXP / "protocol/encoder-audit.json") == file_hash(AG / "protocol/encoder-audit.json"),
"Frozen encoder audit changed")
require(encoder["panel_count"] == 12 and encoder["cal_count"] == 6 and
encoder["seeds"] == list(legacy.ORIGINAL_SEEDS) and encoder["requested_before_any_dynamics"] is True and
encoder["formal_AB_run"] is False and encoder["heldout_run"] is False, "Invalid frozen encoder scope")
import pandas as pd
panel = pd.read_parquet(ROOT / "experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet")
require(len(panel) == 12 and set(panel[panel.split == "calibration"].odor_id) == legacy.ORIGINAL_CAL_IDS and
float(np.median(panel.mapped_response_sum)) == encoder["median_mapped_response_sum"],
"Static original 12-panel median/identities changed; no heldout trajectories are read")
kc = np.load(AG / "apl-bundle/kc_globals.npy", allow_pickle=False)
require(kc.dtype == np.int32 and kc.shape == (4064,) and np.all(np.diff(kc) > 0) and
np.all((kc >= 0) & (kc < CFG["neurons"])), "Invalid frozen KC identity")
for delay in (0, 18):
arm = "delay" + str(delay)
try:
arms[arm] = collect_arm(arm, delay, records, odors, legacy, CFG, EXP, AG, kc)
except Exception as error:
failures.append(dict(stage="arm", arm=arm, type=type(error).__name__, message=str(error)))
except Exception as error:
failures.append(dict(stage="prerequisites", type=type(error).__name__, message=str(error)))
for arm, data in arms.items():
failures.extend(dict(arm=arm, **row) for row in data["failures"])
complete = set(arms) == {"delay0", "delay18"}
numerical = bool(complete and all(row["numerical_integrity_pass"] for row in arms.values()) and not failures)
repeated = bool(complete and all(row["exact_repeat_pass"] for row in arms.values()))
control = bool("delay0" in arms and arms["delay0"]["delay0_control_identity_pass"])
represented = bool(complete and all(row["original_representation_gate_pass"] for row in arms.values()))
execution = bool(numerical and repeated and control)
result = {"phase": "4AJ", "pass_all": bool(execution and represented), "execution_gate_pass": execution,
"numerical_integrity_pass": numerical, "exact_repeat_pass": repeated, "delay0_control_identity_pass": control,
"original_representation_gate_pass": represented,
"original_representation_gate_pass_by_arm": {arm: row["original_representation_gate_pass"] for arm, row in arms.items()},
"expected_base_trials_per_arm": 60, "expected_repeats_per_arm": 12,
"expected_delay0_AG_comparisons": 72, "arms": arms, "failures": failures, "odor_ids": odors,
"encoder_audit": encoder, "legacy_calibration_sha256": LEGACY_SHA256,
"scope": "Both fixed timing arms, full original 4L CAL gate; no heldout or learning claim",
"representation_failure_is_not_numerical_failure": True,
"selection_or_tuning_performed": False, "both_arms_retained_regardless_of_representation": True,
"closed_loop_generated_h_integrals_forced_equal": False,
"pending_is_finite_generated_sequence_not_complete_future_decay": True,
"candidate_generated": False, "training": False, "heldout_dynamic_access": False,
"shared_apl_component_oracle_limit": True, "independent_oracle_equivalence_claim": False}
if target is not None:
outputs = {target: result}
for arm, data in arms.items():
directory = target.parent / arm
outputs[directory / "summary.json"] = data
for mode, metrics in data["modes"].items():
outputs[directory / (mode + ".json")] = metrics
require(all(not path.exists() for path in outputs), "Refusing existing arm/mode summary")
for path, value in outputs.items():
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
json.dump(value, stream, ensure_ascii=False, indent=2, allow_nan=False)
stream.write("\n")
return result
if __name__ == "__main__":
result = summarize()
print(json.dumps({key: result[key] for key in ("pass_all", "execution_gate_pass",
"delay0_control_identity_pass", "original_representation_gate_pass_by_arm")}), flush=True)