Geometry inner loop: batched full-objective ratio optimiser (CMA-ES)
innerloop.py: optimise(root, programme_dir, x0=None, budget, method) ->
Result, optimising equal-offset free-branch ratios (midpoint projection of
legacy unequal cuts) against full oracle fitness. OracleEvaluator scores
each population in one batched perl call. Methods: cma (default) — multi-
start sigma ladder (0.05 local, 0.15 exploratory) with IPOP-style popsize
doubling and deterministic seeding (pycma treats seed 0 as clock!) — and
compass with Hooke-Jeeves pattern moves, kept for the d0s bake-off.
Acceptance (experiments/accept_innerloop.py, §4.5 bars vs unprojected
originals, within-noise tolerance 1%): x1.65 / x1.66 / x1.58 against bars
x1.24 / x1.67 / x1.59, no new failures, 46 oracle calls vs Nelder-Mead's
200. The two near-bar results are statistically indistinguishable from the
single-NM-draw bars (measured draw spread brackets them); decision approved
by Bruno 2026-06-12.
Also: tests/ scaffold (12 oracle-free unit tests, pytest pythonpath=src),
rebaseline_no_occlusion.py for homemaker-py-gp2, cma>=3.0 dependency
(installed via dnf), dead-variable cleanup in solver.py.
Closes homemaker-py-1p0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 09:42:24 +01:00
|
|
|
#!/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"
|
|
|
|
|
|
2026-06-12 10:31:38 +01:00
|
|
|
# name -> reference x-gain. Current bars are the occlusion-disabled re-baseline
|
|
|
|
|
# (homemaker-py-gp2): the deterministic-seed CMA run at budget 400 under
|
|
|
|
|
# URB_NO_OCCLUSION=1 — set that env var to reproduce. (The original §4.5
|
|
|
|
|
# Nelder-Mead bars, flag-off, were 1.24 / 1.67 / 1.59; the inner loop met them
|
|
|
|
|
# within noise, homemaker-py-1p0.)
|
Geometry inner loop: batched full-objective ratio optimiser (CMA-ES)
innerloop.py: optimise(root, programme_dir, x0=None, budget, method) ->
Result, optimising equal-offset free-branch ratios (midpoint projection of
legacy unequal cuts) against full oracle fitness. OracleEvaluator scores
each population in one batched perl call. Methods: cma (default) — multi-
start sigma ladder (0.05 local, 0.15 exploratory) with IPOP-style popsize
doubling and deterministic seeding (pycma treats seed 0 as clock!) — and
compass with Hooke-Jeeves pattern moves, kept for the d0s bake-off.
Acceptance (experiments/accept_innerloop.py, §4.5 bars vs unprojected
originals, within-noise tolerance 1%): x1.65 / x1.66 / x1.58 against bars
x1.24 / x1.67 / x1.59, no new failures, 46 oracle calls vs Nelder-Mead's
200. The two near-bar results are statistically indistinguishable from the
single-NM-draw bars (measured draw spread brackets them); decision approved
by Bruno 2026-06-12.
Also: tests/ scaffold (12 oracle-free unit tests, pytest pythonpath=src),
rebaseline_no_occlusion.py for homemaker-py-gp2, cma>=3.0 dependency
(installed via dnf), dead-variable cleanup in solver.py.
Closes homemaker-py-1p0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 09:42:24 +01:00
|
|
|
GATE = {
|
2026-06-12 10:31:38 +01:00
|
|
|
"2f45907abd9accac2a124d311732f749.dom": 1.63,
|
|
|
|
|
"candidate-002.dom": 1.70,
|
|
|
|
|
"c964435454c459f86c3ed9a5a7621132.dom": 1.68,
|
Geometry inner loop: batched full-objective ratio optimiser (CMA-ES)
innerloop.py: optimise(root, programme_dir, x0=None, budget, method) ->
Result, optimising equal-offset free-branch ratios (midpoint projection of
legacy unequal cuts) against full oracle fitness. OracleEvaluator scores
each population in one batched perl call. Methods: cma (default) — multi-
start sigma ladder (0.05 local, 0.15 exploratory) with IPOP-style popsize
doubling and deterministic seeding (pycma treats seed 0 as clock!) — and
compass with Hooke-Jeeves pattern moves, kept for the d0s bake-off.
Acceptance (experiments/accept_innerloop.py, §4.5 bars vs unprojected
originals, within-noise tolerance 1%): x1.65 / x1.66 / x1.58 against bars
x1.24 / x1.67 / x1.59, no new failures, 46 oracle calls vs Nelder-Mead's
200. The two near-bar results are statistically indistinguishable from the
single-NM-draw bars (measured draw spread brackets them); decision approved
by Bruno 2026-06-12.
Also: tests/ scaffold (12 oracle-free unit tests, pytest pythonpath=src),
rebaseline_no_occlusion.py for homemaker-py-gp2, cma>=3.0 dependency
(installed via dnf), dead-variable cleanup in solver.py.
Closes homemaker-py-1p0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 09:42:24 +01:00
|
|
|
}
|
|
|
|
|
|
2026-06-12 10:31:38 +01:00
|
|
|
# Bars are single optimiser draws and per-run variance brackets them
|
|
|
|
|
# (candidate-002 drew 0.0117-0.0160 against a 0.0123 flag-off bar).
|
|
|
|
|
# Reproduction within 1% counts as met — decision approved 2026-06-12
|
Geometry inner loop: batched full-objective ratio optimiser (CMA-ES)
innerloop.py: optimise(root, programme_dir, x0=None, budget, method) ->
Result, optimising equal-offset free-branch ratios (midpoint projection of
legacy unequal cuts) against full oracle fitness. OracleEvaluator scores
each population in one batched perl call. Methods: cma (default) — multi-
start sigma ladder (0.05 local, 0.15 exploratory) with IPOP-style popsize
doubling and deterministic seeding (pycma treats seed 0 as clock!) — and
compass with Hooke-Jeeves pattern moves, kept for the d0s bake-off.
Acceptance (experiments/accept_innerloop.py, §4.5 bars vs unprojected
originals, within-noise tolerance 1%): x1.65 / x1.66 / x1.58 against bars
x1.24 / x1.67 / x1.59, no new failures, 46 oracle calls vs Nelder-Mead's
200. The two near-bar results are statistically indistinguishable from the
single-NM-draw bars (measured draw spread brackets them); decision approved
by Bruno 2026-06-12.
Also: tests/ scaffold (12 oracle-free unit tests, pytest pythonpath=src),
rebaseline_no_occlusion.py for homemaker-py-gp2, cma>=3.0 dependency
(installed via dnf), dead-variable cleanup in solver.py.
Closes homemaker-py-1p0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 09:42:24 +01:00
|
|
|
# (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())
|