78 lines
3 KiB
Python
78 lines
3 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Acceptance run for the geometry inner loop (homemaker-py-1p0).
|
||
|
|
|
||
|
|
Gate (DESIGN.md §4.5, issue acceptance criteria): reproduce or exceed the
|
||
|
|
Nelder-Mead diagnostic gains — x1.24 / x1.67 / x1.59, no new failures — on
|
||
|
|
2f45907, candidate-002 and c964435, using the batched compass search.
|
||
|
|
|
||
|
|
Usage: accept_innerloop.py [budget] [method] (default: 200 oracle evals, cma)
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import shutil
|
||
|
|
import sys
|
||
|
|
import tempfile
|
||
|
|
import time
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
||
|
|
from homemaker import dom, innerloop, oracle # noqa: E402
|
||
|
|
|
||
|
|
URB = Path("/home/bruno/src/urb")
|
||
|
|
EX = URB / "examples" / "programme-house"
|
||
|
|
|
||
|
|
# name -> the x-gain the §4.5 Nelder-Mead diagnostic achieved (the bar)
|
||
|
|
GATE = {
|
||
|
|
"2f45907abd9accac2a124d311732f749.dom": 1.24,
|
||
|
|
"candidate-002.dom": 1.67,
|
||
|
|
"c964435454c459f86c3ed9a5a7621132.dom": 1.59,
|
||
|
|
}
|
||
|
|
|
||
|
|
# The §4.5 bars are single Nelder-Mead draws and the inner loop's per-run
|
||
|
|
# variance brackets them (candidate-002 drew 0.0117-0.0160 against a 0.0123
|
||
|
|
# bar). Reproduction within 1% counts as met — decision approved 2026-06-12
|
||
|
|
# (homemaker-py-1p0); chasing the last fraction with seed rolls would be
|
||
|
|
# cherry-picking.
|
||
|
|
NOISE_TOL = 0.99
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> int:
|
||
|
|
budget = int(sys.argv[1]) if len(sys.argv) > 1 else 200
|
||
|
|
method = sys.argv[2] if len(sys.argv) > 2 else "cma"
|
||
|
|
print(f"method={method} budget={budget}")
|
||
|
|
all_ok = True
|
||
|
|
with tempfile.TemporaryDirectory(prefix="accept_innerloop_") as tmp:
|
||
|
|
scratch = Path(tmp)
|
||
|
|
shutil.copy(EX / "patterns.config", scratch)
|
||
|
|
for name, bar in GATE.items():
|
||
|
|
# Baseline = the UNMODIFIED original file, exactly as §4.5 measured
|
||
|
|
# it. The inner loop's own x0 score is the equal-offset *projection*
|
||
|
|
# of the original (a==b forced, clipped), which is lower for legacy
|
||
|
|
# designs with unequal cuts — gains must not be measured from there.
|
||
|
|
s_orig = oracle.score(shutil.copy(EX / name, scratch), URB)
|
||
|
|
|
||
|
|
root = dom.load(str(EX / name))
|
||
|
|
t0 = time.perf_counter()
|
||
|
|
r = innerloop.optimise(root, EX, budget=budget, method=method, urb_root=URB)
|
||
|
|
dt = time.perf_counter() - t0
|
||
|
|
gain = r.fitness / s_orig.fitness if s_orig.fitness else float("inf")
|
||
|
|
ok = gain >= bar * NOISE_TOL and r.n_fails <= s_orig.n_fails
|
||
|
|
all_ok &= ok
|
||
|
|
print(
|
||
|
|
f"{name:42s} dof={len(r.x):2d} "
|
||
|
|
f"orig={s_orig.fitness:.6g}(fails {s_orig.n_fails}) "
|
||
|
|
f"projected x0={r.x0_fitness:.6g}(fails {r.x0_n_fails}) "
|
||
|
|
f"opt={r.fitness:.6g}(fails {r.n_fails}) "
|
||
|
|
f"x{gain:.2f} (bar x{bar:.2f}) "
|
||
|
|
f"{r.n_evals} evals / {r.n_oracle_calls} oracle calls / {dt:.0f}s "
|
||
|
|
f"{'PASS' if ok else 'FAIL'}",
|
||
|
|
flush=True,
|
||
|
|
)
|
||
|
|
print("\nGATE " + ("PASSED" if all_ok else "FAILED"))
|
||
|
|
return 0 if all_ok else 1
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
sys.exit(main())
|