369 lines
22 KiB
Python
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)
|