summaryrefslogtreecommitdiff
path: root/external/dualprop_patches/0016-experiment-lock-P2-source-and-cell-registry.patch
diff options
context:
space:
mode:
Diffstat (limited to 'external/dualprop_patches/0016-experiment-lock-P2-source-and-cell-registry.patch')
-rw-r--r--external/dualprop_patches/0016-experiment-lock-P2-source-and-cell-registry.patch70
1 files changed, 70 insertions, 0 deletions
diff --git a/external/dualprop_patches/0016-experiment-lock-P2-source-and-cell-registry.patch b/external/dualprop_patches/0016-experiment-lock-P2-source-and-cell-registry.patch
new file mode 100644
index 0000000..47fd5b6
--- /dev/null
+++ b/external/dualprop_patches/0016-experiment-lock-P2-source-and-cell-registry.patch
@@ -0,0 +1,70 @@
+From 18b17f442b045686bee420b81b3e889cb80fd71e Mon Sep 17 00:00:00 2001
+From: YurenHao0426 <Blackhao0426@gmail.com>
+Date: Mon, 27 Jul 2026 13:51:07 -0500
+Subject: [PATCH 16/19] experiment: lock P2 source and cell registry
+
+---
+ crossover_grid.py | 40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/crossover_grid.py b/crossover_grid.py
+index cbd9b98..4523250 100644
+--- a/crossover_grid.py
++++ b/crossover_grid.py
+@@ -180,6 +180,43 @@ def p2_jobs():
+ ]
+
+
++def p2_registry_sha256(jobs):
++ encoded = json.dumps(
++ jobs, sort_keys=True, separators=(",", ":")).encode("utf-8")
++ return hashlib.sha256(encoded).hexdigest()
++
++
++def ensure_p2_launch(source, jobs):
++ path = os.path.join(ROOT, "runs", "plain-p2-launch.json")
++ immutable = {
++ "stage": "p2",
++ "source": source,
++ "selector_path": SELECTOR,
++ "selector_sha256": SELECTOR_SHA256,
++ "num_registered_cells": len(jobs),
++ "registry_sha256": p2_registry_sha256(jobs),
++ "jobs": jobs,
++ }
++ if os.path.exists(path):
++ with open(path, encoding="utf-8") as handle:
++ existing = json.load(handle)
++ for key, value in immutable.items():
++ if existing.get(key) != value:
++ raise RuntimeError(f"P2 launch lock drift in {key}")
++ return path
++ record = {**immutable, "created_unix_time": time.time()}
++ os.makedirs(os.path.dirname(path), exist_ok=True)
++ try:
++ descriptor = os.open(
++ path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
++ except FileExistsError:
++ return ensure_p2_launch(source, jobs)
++ with os.fdopen(descriptor, "w", encoding="utf-8") as handle:
++ json.dump(record, handle, indent=2, sort_keys=True)
++ handle.write("\n")
++ return path
++
++
+ def p2_command(method, architecture, rate):
+ cli_method = {
+ "bp": "backprop",
+@@ -673,6 +710,9 @@ def main():
+ raise ValueError("invalid shard")
+ source = source_report()
+ jobs = p1_jobs() if args.stage == "p1" else p2_jobs()
++ if args.stage == "p2" and not args.dry_run:
++ launch = ensure_p2_launch(source, jobs)
++ print(f"P2 launch lock: {launch}", flush=True)
+ if args.method:
+ jobs = [job for job in jobs if job["method"] == args.method]
+ jobs = [
+--
+2.54.0
+