84 ap = argparse.ArgumentParser(description=__doc__,
85 formatter_class=argparse.RawDescriptionHelpFormatter)
86 ap.add_argument(
"--top", type=int, default=8,
87 help=
"how many unverified rows to verify (default 8)")
88 ap.add_argument(
"--factor", type=int, default=4,
89 help=
"grid-extent multiplier (default 4)")
90 ap.add_argument(
"--run", action=
"store_true", help=
"launch, don't just print")
91 ap.add_argument(
"--workers", type=int, default=4)
92 ap.add_argument(
"--tag", default=
"AUTOVERIFY")
93 a = ap.parse_args(argv)
95 if not LEDGER.exists():
96 print(
"no ledger - run learn.py first", file=sys.stderr)
98 led = json.loads(LEDGER.read_text(encoding=
"utf-8"))
102 print(
"nothing to verify: every valid in-scope row already has an "
111 raw = res.get(c[
"row_id"])
112 if raw
is None or not c[
"design"]:
113 skipped.append((c[
"row_id"],
"no raw result or no design file"))
117 skipped.append((c[
"row_id"],
"cannot recover V (no occ_v)"))
119 key = (c[
"design"], V, raw.get(
"bin_V_bin"), raw.get(
"bin_I_bin"),
120 raw.get(
"bin_i_discrete"), raw.get(
"bin_v_discrete"),
121 raw.get(
"equations"))
122 groups.setdefault(key, []).append((c, raw))
124 print(f
"{len(cands)} unverified candidates -> {len(groups)} verification run(s)\n")
126 for gi, ((design, V, vbin, ibin, idisc, vdisc, eqs), items)
in \
127 enumerate(sorted(groups.items(), key=
lambda kv: str(kv[0]))):
130 skipped.append((design,
"design file missing"))
132 by_id = {r[
"row_id"]: r
for r
in csv.DictReader(src.open(encoding=
"utf-8"))}
133 hdr = list(next(iter(by_id.values())).keys())
138 vd = max(int(vdisc
or 5), 1)
140 r_bin = (V / vd) ** (1.0 / int(vbin))
141 newvbin = max(2, int(round(math.log(newV / vd) / math.log(r_bin))))
144 out_rows, picked = [], []
145 for off, (c, _raw)
in enumerate(items):
146 drow = by_id.get(c[
"row_id"])
148 skipped.append((c[
"row_id"], f
"row not in {design}"))
151 nid = str(900000 + gi * 100 + off)
153 if "cond_row_id" in nr:
154 nr[
"cond_row_id"] = nid
156 picked.append(f
"{c['row_id']}({c['label'] or '-'}, {c['n_in_range']}/6)")
159 name = f
"{a.tag}_g{gi}"
160 dpath = HERE /
"design" / f
"{name}.csv"
161 with dpath.open(
"w", newline=
"", encoding=
"utf-8")
as fh:
162 w = csv.DictWriter(fh, fieldnames=hdr)
164 w.writerows(out_rows)
165 cmd = [
"python",
"run_ensemble.py",
166 "--design", f
"design/{name}.csv",
167 "--conditions",
"conditions_S8.json",
"--spec",
"parameters_S4.json",
168 "--out", f
"results/{name}.jsonl",
169 "--machine",
"0",
"--of",
"1",
170 "--equations", str(eqs
or "bin_moment"),
171 "--i-discrete", str(idisc
or 100),
"--i-bin", str(ibin
or 36),
172 "--v-discrete", str(vd),
"--v-bin", str(newvbin),
173 "--allow-mixed",
"--I",
"80000",
"--V", str(newV),
174 "--dose",
"15.0",
"--lnl",
"1",
"--rtol",
"1e-5",
175 "--solver-mode",
"full_system",
"--timeout-s",
"43200",
176 "--workers", str(a.workers),
"--omp-threads",
"1"]
178 print(f
"[{name}] V {V} -> {newV} (v_bin {vbin} -> {newvbin}, ratio held)")
181 print(
" " +
" ".join(cmd) +
"\n")
185 for rid, why
in skipped:
186 print(f
" {rid}: {why}")
190 print(
"launching:",
" ".join(cmd[-6:]))
191 subprocess.Popen(cmd, cwd=HERE,
192 stdout=open(HERE /
"results" /
"verify.log",
"a"),
193 stderr=subprocess.STDOUT)
194 print(f
"\n{len(cmds)} run(s) launched. Re-run learn.py when they finish; "
195 "pairs form automatically.")
197 print(
"dry run - pass --run to launch.")