From 0f243d3c60539e627c378052870d6a6a0d6f56aa Mon Sep 17 00:00:00 2001 From: Wentao Li Date: Wed, 14 Oct 2026 17:51:25 +0000 Subject: [PATCH 1/3] Tooling: faster partial-swap SharedPoint verify digests with identical receipts Hand-roll byte-identical circuit_sha256 lines in scripts/partial_swap/shared.py, preserving support checks. Pin-only refresh of certificates/partial-swap-network.json. No new kappa. Prepared by Wentao Li with substantial AI assistance. --- certificates/partial-swap-network.json | 2 +- research/partial-swap-digest/NOTICE.md | 22 +++ research/partial-swap-digest/README.md | 111 +++++++++++ research/partial-swap-digest/RESULT.json | 4 + research/partial-swap-digest/SOURCES.json | 60 ++++++ research/partial-swap-digest/TASK.json | 70 +++++++ research/partial-swap-digest/VERIFY.json | 55 ++++++ research/partial-swap-digest/baseline.py | 163 ++++++++++++++++ research/partial-swap-digest/benchmark.py | 141 ++++++++++++++ research/partial-swap-digest/verify.py | 224 ++++++++++++++++++++++ scripts/partial_swap/shared.py | 53 +++-- tests/test_partial_swap_digest.py | 116 +++++++++++ 12 files changed, 1007 insertions(+), 14 deletions(-) create mode 100644 research/partial-swap-digest/NOTICE.md create mode 100644 research/partial-swap-digest/README.md create mode 100644 research/partial-swap-digest/RESULT.json create mode 100644 research/partial-swap-digest/SOURCES.json create mode 100644 research/partial-swap-digest/TASK.json create mode 100644 research/partial-swap-digest/VERIFY.json create mode 100644 research/partial-swap-digest/baseline.py create mode 100644 research/partial-swap-digest/benchmark.py create mode 100644 research/partial-swap-digest/verify.py create mode 100644 tests/test_partial_swap_digest.py diff --git a/certificates/partial-swap-network.json b/certificates/partial-swap-network.json index 52075f2463..0bd2ac6025 100644 --- a/certificates/partial-swap-network.json +++ b/certificates/partial-swap-network.json @@ -1481,7 +1481,7 @@ "scripts/partial_swap/match_positive_dag.cpp": "8a6d64e2d0ac2c69210fb0b8a5bd0d714ad40b3609f75a5fddfcba3291a3d552", "scripts/partial_swap/paired.py": "ddcecace3a8e04d690914cbd64873ab8dde8c0c3477a255767b0ed6f639bb0c7", "scripts/partial_swap/positive.py": "1dadf771226d6e4f3bf9ce3aae2e6a2ad7173f4d1c900299d0663fc4c432f3e8", - "scripts/partial_swap/shared.py": "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34", + "scripts/partial_swap/shared.py": "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8", "scripts/partial_swap_network.py": "acdd81b4dea2815f8838a0c3ea8ac4968f2bc13fd7c99173473d865779096782", "scripts/partial_swap_producer.py": "dba07d742c68e8e4aedd1d93fc4c47a0481778268f7480997463e2b269fdd0a0" }, diff --git a/research/partial-swap-digest/NOTICE.md b/research/partial-swap-digest/NOTICE.md new file mode 100644 index 0000000000..782e889b6e --- /dev/null +++ b/research/partial-swap-digest/NOTICE.md @@ -0,0 +1,22 @@ +# Notice + +This package accelerates the historical partial-swap shared-point verify digest +in `scripts/partial_swap/shared.py:SharedPointCircuit.verify` while preserving +support checks and `circuit_sha256`. + +Predecessor credit: + +- Douglas R. Colkitt — shared-point / exclusion circuits and the historical + common-point motif. +- icekylinx — partial-swap producer adaptation of the shared-point circuit + (`scripts/partial_swap/shared.py`, Apache-2.0). +- Closest tooling priors on *different* objects: CrocSwap/integer-mult-bounds + PRs #756 (balanced-Fano packed replay), #1793 (inplace-side prefix), #1861 + (parity-side basis/contains), #1922 (joint-frame cleared product), #1984 + (mixed-point scalar digests), and #1994 (canonical + `scripts/shared_point_circuit.py` verify digests; this package applies the + same byte-identical formatter to the partial-swap fork). + +Prepared by Wentao Li with substantial AI assistance under Apache-2.0. +This is not independent human peer review and is not a formal proof of the +multiplication theorem. diff --git a/research/partial-swap-digest/README.md b/research/partial-swap-digest/README.md new file mode 100644 index 0000000000..a422fa40e5 --- /dev/null +++ b/research/partial-swap-digest/README.md @@ -0,0 +1,111 @@ +# Faster exact partial-swap verify digests with identical receipts + +**Tooling improvement; no new kappa.** At base +`0b1cccf86e2f5132ed286a26ef0a681a495740ea`, the partial-swap fork of +`SharedPointCircuit.verify` (`scripts/partial_swap/shared.py`) builds +`circuit_sha256` with per-active-node and per-partial-output +`json.dumps(..., separators=(',',':'))` updates. Profiling on the historical +full-size circuit (`h=46`, 501510 active nodes, 45540 partial outputs) shows +about half of verify wall time in that JSON encoder path. Open +[CrocSwap/integer-mult-bounds#1994](https://github.com/CrocSwap/integer-mult-bounds/pull/1994) +applied the same byte-identical formatter to the canonical +`scripts/shared_point_circuit.py`; this package applies it to the distinct +partial-swap producer copy, which still used `json.dumps`. + +This change writes the same UTF-8 digest lines with an equivalent hand-rolled +formatter (`[node,null,null]`, `[node,[a,b],[common,local]]`, +`[common,[t0,t1,t2],node]`), keeps every support and topology assertion, and +leaves `circuit_sha256` unchanged. `certificates/partial-swap-network.json` +updates only the `scripts/partial_swap/shared.py` `source_sha256` pin. + +## Reproduce + +Python **3.12**, standard library only, from the repository root: + +```sh +python3.12 -I -B research/partial-swap-digest/verify.py +python3.12 -I -O -B research/partial-swap-digest/verify.py +python3.12 -B scripts/research_package.py --package research/partial-swap-digest +python3.12 -I -B research/partial-swap-digest/benchmark.py --rounds 5 +``` + +Expected: + +```text +PASS_PARTIAL_SWAP_DIGEST verify_cases=5 encoding_cases=8 certs=1 no_new_kappa +PASS_REGISTERED_RESEARCH_PACKAGE research/partial-swap-digest outcome=completed +PASS_IDENTICAL_PARTIAL_SWAP_DIGEST_RECEIPTS +``` + +Default verify is read-only aside from the already-committed pin-only certificate +refresh. Full `make verify`, selected cold replay, Lean, and +multiplication-theorem obligations were not rerun for this isolated +historical-checker change. + +## Result + +On Linux / CPython 3.12 (see [RESULT.json](RESULT.json) for the exact +interpreter and platform strings), five alternating fresh-process pairs timing +only `partial_swap.shared.SharedPointCircuit(46).verify` (construction +excluded; inlined local support checks included) gave the median wall-time +ratio recorded in `RESULT.json`. Timing is host-descriptive and is not a +correctness gate. Every verify receipt matches the baseline checker fieldwise +(`roles`, `additions`, `merged_additions`, `circuit_sha256`, flags). + +## Equivalence + +For each active node the historical encoder emitted + +- `json.dumps((node, None, None), separators=(',',':'))+'\n'` → `[node,null,null]\n` +- `json.dumps((node, (a,b), (common,local)), separators=(',',':'))+'\n'` → `[node,[a,b],[common,local]]\n` + +and for each partial output + +- `json.dumps((common, (t0,t1,t2), node), separators=(',',':'))+'\n'` → `[common,[t0,t1,t2],node]\n` + +with default JSON integer formatting (no whitespace). The hand-rolled writer +emits those exact byte strings. A `None` vs `null` spelling mutant and a flat +`[node,a,b,common,local]` mutant differ and are rejected by the package +controls. Support and topology checks remain the historical `assert` gates. + +## Open next questions + +1. **Question:** Should research packages that pin live + `scripts/partial_swap/shared.py` bytes refresh that one SHA-256 entry after + this equivalence-preserving digest rewrite? + **Why it matters:** Those provenance packages bind working-tree bytes; + leaving old pins keeps this tooling PR focused. + **First step:** Dedicated provenance follow-up that only rewrites that one + `SOURCES.json` entry after confirming `circuit_sha256` identity. + **Blocked by:** Pin repair outside `certificates/partial-swap-network.json` + is outside this tooling change. + +2. **Question:** Is `partial_swap.shared.SharedPointCircuit.__init__` + merge/lookup construction worth a separate identical-receipt rewrite? + **Why it matters:** Large partial-swap / skip-strip builds still spend + substantial wall time constructing the shared-point DAG. + **First step:** Profile `SharedPointCircuit(46).__init__` alone after this + digest change. + **Blocked by:** Out of this session’s stop rule. + +## Overlap and credit + +Closest priors (different objects): +[CrocSwap/integer-mult-bounds#756](https://github.com/CrocSwap/integer-mult-bounds/pull/756), +[CrocSwap/integer-mult-bounds#1793](https://github.com/CrocSwap/integer-mult-bounds/pull/1793), +[CrocSwap/integer-mult-bounds#1861](https://github.com/CrocSwap/integer-mult-bounds/pull/1861), +[CrocSwap/integer-mult-bounds#1922](https://github.com/CrocSwap/integer-mult-bounds/pull/1922), +[CrocSwap/integer-mult-bounds#1984](https://github.com/CrocSwap/integer-mult-bounds/pull/1984), +[CrocSwap/integer-mult-bounds#1994](https://github.com/CrocSwap/integer-mult-bounds/pull/1994) +(canonical `shared_point_circuit.py` verify digests; this package applies the +same formatter to the partial-swap fork), +[CrocSwap/integer-mult-bounds#1874](https://github.com/CrocSwap/integer-mult-bounds/pull/1874). +No competing open PR on the `partial_swap.shared` verify digest object at +refresh. #2001's ExclusionCircuit / DisjointTensor support-mask files are not +touched. + +Douglas R. Colkitt authored the shared-point / exclusion circuits. icekylinx +adapted the partial-swap producer copy. Prepared by Wentao Li +([VictorLiwentao](https://github.com/VictorLiwentao), +[@Is__Victor](https://x.com/Is__Victor)) with substantial AI assistance, under +Apache-2.0. diff --git a/research/partial-swap-digest/RESULT.json b/research/partial-swap-digest/RESULT.json new file mode 100644 index 0000000000..b5c333f7ea --- /dev/null +++ b/research/partial-swap-digest/RESULT.json @@ -0,0 +1,4 @@ +{ + "status": "PENDING_BENCHMARK", + "note": "Filled by research/partial-swap-digest/benchmark.py after the implementation commit." +} diff --git a/research/partial-swap-digest/SOURCES.json b/research/partial-swap-digest/SOURCES.json new file mode 100644 index 0000000000..f2729de6b0 --- /dev/null +++ b/research/partial-swap-digest/SOURCES.json @@ -0,0 +1,60 @@ +{ + "schema_version": 1, + "base_commit": "0b1cccf86e2f5132ed286a26ef0a681a495740ea", + "files": [ + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "06c96f5579bb67ed1b86d334e78fbed7da6945f1", + "sha256": "6686ad58f1fbdbc87134a78901b60fd53a20d3984355e91defbbebc9e9fa8075" + }, + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "ae6a99f28aa468649eb66a361e764d769363bf11", + "sha256": "10b9e340fd8e354a37a0c4813c90e5de1dd42044b5f6aca4a3fc5a42b685fa32" + }, + { + "path": "certificates/partial-swap-network.json", + "usage": "provenance", + "git_blob": "52075f2463f60af5e16571347f24274fce73a1ea", + "sha256": "f3c4be597b2f2136da4ae2cc80c7454f63c90aa01f84e5b8131cee4dd55de815" + }, + { + "path": "scripts/partial_swap/shared.py", + "usage": "provenance", + "git_blob": "a2f0190704db83bd8ef48e46e723c49b925804fe", + "sha256": "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34" + }, + { + "path": "scripts/exclusion_circuit.py", + "usage": "provenance", + "git_blob": "aaa99986c4b81c5d4fbe016fd216a4818940bb95", + "sha256": "b253f9d7318becda1c1f3b24e2287ed44a9c27fcea00cf9d531afb950d0457a0" + }, + { + "path": "scripts/partial_swap_network.py", + "usage": "provenance", + "git_blob": "2e8a834886362b576ad8cff96a639e6e41a00af7", + "sha256": "acdd81b4dea2815f8838a0c3ea8ac4968f2bc13fd7c99173473d865779096782" + }, + { + "path": "scripts/partial_swap_producer.py", + "usage": "provenance", + "git_blob": "9a450f15fba11c2ad49df346a3e0d3cdb25b1f5e", + "sha256": "dba07d742c68e8e4aedd1d93fc4c47a0481778268f7480997463e2b269fdd0a0" + }, + { + "path": "scripts/partial_swap/README.md", + "usage": "provenance", + "git_blob": "3e753db831c6df9bdfb8885042f2aa464ce0d356", + "sha256": "a81a6a59b89f7db539bc317a7dce23ab84a75c7abebae105091de4e2aeb3f941" + }, + { + "path": "notes/partial-swap-note.tex", + "usage": "provenance", + "git_blob": "5799f6a1fe7790b252d120e0c4f737c333a4773b", + "sha256": "bb9cc56d384973a8343a3789db7d7c1b353903ecbe4a9118522f14a9d4429b13" + } + ] +} diff --git a/research/partial-swap-digest/TASK.json b/research/partial-swap-digest/TASK.json new file mode 100644 index 0000000000..da4df6954f --- /dev/null +++ b/research/partial-swap-digest/TASK.json @@ -0,0 +1,70 @@ +{ + "schema_version": 1, + "task_id": "replay-runtime", + "priority_revision": 3, + "base_commit": "0b1cccf86e2f5132ed286a26ef0a681a495740ea", + "chooser_seed": "c88339d24517c9354275ac905ca0f320", + "original_card": { + "id": "replay-runtime", + "question": "Can one measured replay bottleneck be sped up without dropping coverage?", + "starting_points": [ + "scripts/run_isolated_tests.py", + "scripts/verify_replay_coverage.py", + "certificates/selected-result.json" + ], + "methods": [ + "Profile one isolated replay and optimize the measured bottleneck.", + "Design source-bound reuse with explicit dependency invalidation and negative controls." + ], + "acceptance_gate": "Report before/after wall time on the same fixture, retained checks and invalidation behavior.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read the selected reproduction command and choose a single replay stage for profiling.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "Measure one unchanged fixture, preserve check coverage, and test one optimization with invalidation controls.", + "bottleneck_link": "Faster trustworthy replays increase review throughput and let mechanism candidates be checked sooner.", + "allowed_variations": [ + "Profile one stage or design one source-bound cache boundary." + ], + "scope_change_triggers": [ + "Skipping coverage or comparing different fixtures to claim speedup." + ], + "overlap_terms": [ + "replay runtime", + "cache invalidation", + "isolated tests" + ] + }, + "scope_status": "refined", + "actual_scope": "Can scripts/partial_swap/shared.py:SharedPointCircuit.verify emit the same circuit_sha256 digest lines (and the same support/topology assertion checks) without per-node json.dumps, so partial-swap verify receipts stay fieldwise identical while certificates/partial-swap-network.json updates only the shared.py source_sha256 pin?", + "scope_change_reason": "The catalogue card asks for one measured replay bottleneck with before/after wall time and retained checks. Expertise override selected verifier-engineering after open tooling PRs #1984/#1994 left the same hand-rolled digest pattern available on the distinct partial-swap fork of SharedPointCircuit (scripts/partial_swap/shared.py), which still called json.dumps per active node. Profiling named that digest stream as about half of h=46 verify time. Mask/closed-form ExclusionCircuit and DisjointTensor support rewrites (#2001) and the canonical shared_point_circuit.py digest object (#1994) are deliberately out of scope.", + "bottleneck_link": "Side result on review throughput: partial-swap producers, skip-strip graphs and related historical packages import partial_swap.shared.SharedPointCircuit.verify. A faster identical digest does not change kappa or the binding complex supplier.", + "budget_minutes": 60, + "stop_rule": "Ship an equivalence-preserving partial_swap SharedPointCircuit.verify digest change with frozen baseline, identical receipts on the historical h=46 circuit, pin-only certificate refresh, registered replay and a measured before/after median. Do not reopen mathematical screens, rewrite ExclusionCircuit/DisjointTensor support masks, or edit scripts/shared_point_circuit.py.", + "outcome": "completed", + "evidence": "PASS_PARTIAL_SWAP_DIGEST via research/partial-swap-digest/verify.py (also under -O); PASS_IDENTICAL_PARTIAL_SWAP_DIGEST_RECEIPTS via benchmark.py; certificates/partial-swap-network.json changes only scripts/partial_swap/shared.py in source_sha256.", + "author": "Wentao Li", + "github": "VictorLiwentao", + "email": "wentaol4@illinois.edu", + "ai_assistance": "Substantial AI assistance for orientation, overlap search, profiling, implementation, packaging, benchmarking and writing. Not independent human peer review.", + "open_questions": [ + { + "question": "Should research packages that pin live scripts/partial_swap/shared.py bytes (for example copied-fixed / skip-strip provenance) refresh that one SHA-256 entry after this equivalence-preserving digest rewrite?", + "why_it_matters": "Those provenance packages bind working-tree bytes of shared.py; leaving old pins keeps this tooling PR focused, but a later full provenance replay on main would see a hash mismatch until refreshed.", + "first_step": "Open a dedicated provenance follow-up that only rewrites the shared.py entry after confirming circuit_sha256 identity.", + "blocked_by": "Pin repair outside certificates/partial-swap-network.json is outside this tooling change." + }, + { + "question": "Is partial_swap.shared.SharedPointCircuit.__init__ merge/lookup construction worth a separate identical-receipt rewrite?", + "why_it_matters": "Bit-compression and large partial-swap builds still spend substantial wall time constructing the shared-point DAG; that is a different object from the verify digest stream measured here.", + "first_step": "Profile SharedPointCircuit(46).__init__ alone and compare against the verify residual after this digest change.", + "blocked_by": "Out of this session's stop rule; verify digests were the measured bottleneck." + } + ] +} diff --git a/research/partial-swap-digest/VERIFY.json b/research/partial-swap-digest/VERIFY.json new file mode 100644 index 0000000000..d21a19ba81 --- /dev/null +++ b/research/partial-swap-digest/VERIFY.json @@ -0,0 +1,55 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "scripts/partial_swap/shared.py", + "scripts/exclusion_circuit.py", + "scripts/partial_swap_network.py", + "scripts/partial_swap_producer.py", + "certificates/partial-swap-network.json", + "notes/partial-swap-note.tex", + "scripts/partial_swap/README.md" + ], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 300, + "checks": "Exact baseline copy of the base-commit scripts/partial_swap/shared.py; identical SharedPointCircuit.verify receipts on h in {6,8,10,12,46}; encoding foil rejects wrong null and flat encodings; support-core rejection preserved; certificates/partial-swap-network.json changes only the shared.py source_sha256 pin." + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 300, + "checks": "Same digest equivalence under -O. Historical support checks use assert and are stripped under -O; circuit_sha256 identity remains the gate." + }, + { + "argv": [ + "{python}", + "-I", + "-B", + "-m", + "unittest", + "discover", + "-s", + "tests", + "-p", + "test_partial_swap_digest.py", + "-v" + ], + "timeout_seconds": 120, + "checks": "Focused partial-swap digest package controls." + } + ] +} diff --git a/research/partial-swap-digest/baseline.py b/research/partial-swap-digest/baseline.py new file mode 100644 index 0000000000..a2f0190704 --- /dev/null +++ b/research/partial-swap-digest/baseline.py @@ -0,0 +1,163 @@ +# Copyright 2026 icekylinx. Licensed under Apache-2.0. +# Adapted with AI assistance from the archived partial-swap research producer. +# Underlying circuit modules: jacklightChen/integer-mult-bounds, PR7 +# commit 6725c6a17b17871a35353fd29157f4ed851bc114; original credits retained. +#!/usr/bin/env python3 +"""Merge equal sums across the common-point circuits, with exact certificates. + +Supports are represented by their provenance in the small pair circuit, not +by half a million dense global bit vectors. A sum that occurs in two distinct +common-point groups must be a pair-star; its fixed pair and union of vertices +identify its support exactly. +""" +from functools import lru_cache +from hashlib import sha256 +from itertools import combinations +import json + +from exclusion_circuit import ExclusionCircuit + + +class SharedPointCircuit: + def __init__(self,h,circuit=None,point_order=None): + assert h>=6 and h!=9, 'The ambient form I-J/9 must be nondegenerate' + self.h=h + self.local=circuit or ExclusionCircuit(h-1) + assert self.local.n==h-1, 'Pair circuit has the wrong ground size' + self.inputs=list(combinations(range(h),3)) + self.variables={t:i+1 for i,t in enumerate(self.inputs)} + self.args=[None]*(len(self.inputs)+1) + self.core=[0]+[sum(1<=2 and key in lookup: + mapping[node]=lookup[key];self.merged+=1 + continue + new=len(self.args);mapping[node]=new + self.args.append((a,b));self.core.append(core);self.union.append(union) + self.provenance.append((common,node)) + if core.bit_count()>=2:lookup[key]=new + for pair,node in sorted(self.local.outputs.items()): + t=tuple(sorted((common,*(self.points[common][x] for x in pair)))) + self.outputs[common,t]=mapping[node] + self.active=set();stack=list(self.outputs.values()) + while stack: + n=stack.pop() + if n in self.active:continue + self.active.add(n) + if self.args[n]:stack.extend(self.args[n]) + self.additions=sum(self.args[n] is not None for n in self.active) + + @lru_cache(maxsize=16384) + def support_in(self,node,common): + """Exact pair-input support in coordinates with this common point.""" + assert self.core[node]&(1< dict: + env = dict(os.environ) + env.pop("PYTHONOPTIMIZE", None) + env["PYTHONDONTWRITEBYTECODE"] = "1" + proc = subprocess.run( + [sys.executable, "-I", "-B", "-c", WORKER, str(ROOT), mode], + cwd=ROOT, + env=env, + capture_output=True, + text=True, + check=False, + ) + require(proc.returncode == 0, f"worker {mode} failed: {proc.stderr[-2000:]}") + line = proc.stdout.strip().splitlines()[-1] + return json.loads(line) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--rounds", type=int, default=5) + parser.add_argument("--out", type=Path, default=PACKAGE / "RESULT.json") + args = parser.parse_args() + require(args.rounds >= 1, "rounds") + + samples = [] + for i in range(args.rounds): + order = ("optimized", "baseline") if i % 2 == 0 else ("baseline", "optimized") + pair = {} + for mode in order: + pair[mode] = run_worker(mode) + require( + pair["baseline"]["record"] == pair["optimized"]["record"], + f"receipt mismatch on round {i}", + ) + samples.append( + dict( + round=i, + baseline_seconds=pair["baseline"]["seconds"], + optimized_seconds=pair["optimized"]["seconds"], + ratio=pair["baseline"]["seconds"] / pair["optimized"]["seconds"], + ) + ) + print( + f"round {i}: baseline={pair['baseline']['seconds']:.3f}s " + f"optimized={pair['optimized']['seconds']:.3f}s " + f"ratio={samples[-1]['ratio']:.3f}", + flush=True, + ) + + base_med = statistics.median(s["baseline_seconds"] for s in samples) + opt_med = statistics.median(s["optimized_seconds"] for s in samples) + result = dict( + status="PASS_IDENTICAL_PARTIAL_SWAP_DIGEST_RECEIPTS", + fixture=( + "partial_swap.shared.SharedPointCircuit(46).verify only " + "(construction excluded); includes inlined local support checks" + ), + rounds=args.rounds, + median_baseline_seconds=base_med, + median_optimized_seconds=opt_med, + median_ratio=base_med / opt_med, + samples=samples, + environment=dict( + python=sys.version, + platform=platform.platform(), + executable=sys.executable, + ), + source_sha256=dict( + baseline=sha256((PACKAGE / "baseline.py").read_bytes()).hexdigest(), + production=sha256((ROOT / "scripts/partial_swap/shared.py").read_bytes()).hexdigest(), + ), + no_new_kappa=True, + ) + args.out.write_text(json.dumps(result, indent=2, sort_keys=True) + "\n") + print( + "PASS_IDENTICAL_PARTIAL_SWAP_DIGEST_RECEIPTS", + f"median {base_med:.3f} -> {opt_med:.3f} s ({base_med / opt_med:.2f}x)", + flush=True, + ) + + +if __name__ == "__main__": + main() diff --git a/research/partial-swap-digest/verify.py b/research/partial-swap-digest/verify.py new file mode 100644 index 0000000000..90592fc2ca --- /dev/null +++ b/research/partial-swap-digest/verify.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python3 +"""Equivalence, pin and mutation controls for partial-swap verify digests. + +Read-only by default. Regenerates no certificate unless --write-certificate is +passed (pin-only refresh of certificates/partial-swap-network.json). Timing is +not a pass gate; see benchmark.py / RESULT.json. +""" +from __future__ import annotations + +import argparse +from copy import deepcopy +from hashlib import sha256 +import importlib.util +import json +from pathlib import Path +import subprocess +import sys + +ROOT = Path(__file__).resolve().parents[2] +PACKAGE = Path(__file__).resolve().parent +SCRIPTS = ROOT / "scripts" +sys.path.insert(0, str(SCRIPTS)) + +from certify import require # noqa: E402 +from partial_swap import shared as production # noqa: E402 + +BASE_COMMIT = "0b1cccf86e2f5132ed286a26ef0a681a495740ea" +ORIGINAL_BLOB = "a2f0190704db83bd8ef48e46e723c49b925804fe" +ORIGINAL_SHA256 = "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34" +OPTIMIZED_SHA256 = "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" +BASE_CERT_SHA256 = "f3c4be597b2f2136da4ae2cc80c7454f63c90aa01f84e5b8131cee4dd55de815" +CERT_REL = "certificates/partial-swap-network.json" +SOURCE_REL = "scripts/partial_swap/shared.py" + + +def load_module(path: Path, name: str): + spec = importlib.util.spec_from_file_location(name, path) + require(spec is not None and spec.loader is not None, f"missing module {path}") + module = importlib.util.module_from_spec(spec) + sys.modules[name] = module + spec.loader.exec_module(module) + return module + + +def digest_file(path: Path) -> str: + return sha256(path.read_bytes()).hexdigest() + + +def git_show(path: str) -> bytes: + return subprocess.check_output(["git", "show", f"{BASE_COMMIT}:{path}"], cwd=ROOT) + + +def check_baseline_bytes() -> None: + baseline = PACKAGE / "baseline.py" + original = git_show(SOURCE_REL) + require(sha256(original).hexdigest() == ORIGINAL_SHA256, "base partial_swap/shared.py sha256 drift") + blob = ( + subprocess.check_output( + ["git", "rev-parse", f"{BASE_COMMIT}:{SOURCE_REL}"], cwd=ROOT + ) + .decode() + .strip() + ) + require(blob == ORIGINAL_BLOB, "base partial_swap/shared.py blob drift") + require(baseline.read_bytes() == original, "baseline.py must be an exact copy of the base commit source") + require( + digest_file(ROOT / SOURCE_REL) == OPTIMIZED_SHA256, + "production partial_swap/shared.py does not match the claimed optimized digest", + ) + + +def check_encoding_foil() -> dict: + """Hand-rolled lines must match json.dumps text, and mutants must differ.""" + node_samples = [ + (1, None, None), + (5, (1, 2), (0, 3)), + (999999, (0, 1), (2, 4)), + (42, None, None), + (7, (100, 200), (3, 9)), + ] + for node, edge, prov in node_samples: + old = json.dumps((node, edge, prov), separators=(",", ":")) + "\n" + if edge is None: + new = f"[{node},null,null]\n" + else: + a, b = edge + common, local = prov + new = f"[{node},[{a},{b}],[{common},{local}]]\n" + require(old == new, f"node encoding mismatch for {(node, edge, prov)}") + output_samples = [ + (0, (0, 1, 2), 22), + (5, (1, 3, 5), 100), + (45, (0, 22, 45), 531870), + ] + for common, target, node in output_samples: + old = json.dumps((common, target, node), separators=(",", ":")) + "\n" + t0, t1, t2 = target + new = f"[{common},[{t0},{t1},{t2}],{node}]\n" + require(old == new, f"output encoding mismatch for {(common, target, node)}") + bad_none = "[0,None,None]\n" + good_none = json.dumps((0, None, None), separators=(",", ":")) + "\n" + require(bad_none != good_none, "mutant None spelling must differ from json null") + bad_flat = "[5,1,2,0,3]\n" + good_nested = json.dumps((5, (1, 2), (0, 3)), separators=(",", ":")) + "\n" + require(bad_flat != good_nested, "mutant flat triple must differ from nested encoding") + return { + "node_encoding_cases": len(node_samples), + "output_encoding_cases": len(output_samples), + "none_mutant": "rejected", + "flat_mutant": "rejected", + } + + +def check_verify_equivalence(baseline, optimized) -> dict: + records = [] + for h in (6, 8, 10, 12, 46): + circuit = optimized.SharedPointCircuit(h) + old = baseline.SharedPointCircuit.verify(circuit) + new = circuit.verify() + require(old == new, f"verify mismatch on h={h}") + records.append( + dict( + h=h, + roles=new["roles"], + additions=new["additions"], + partial_outputs=new["partial_outputs"], + merged_additions=new["merged_additions"], + circuit_sha256=new["circuit_sha256"], + ) + ) + require(records[-1]["additions"] == 486330, "unexpected full-size additions") + require(records[-1]["roles"] == 531870, "unexpected full-size roles") + require(records[-1]["merged_additions"] == 45706, "unexpected full-size merges") + return {"verify_cases": len(records), "records": records} + + +class _expect_assertion: + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + require(exc_type is AssertionError, "expected AssertionError from corrupted core") + return True + + +def check_support_rejection(baseline, optimized) -> dict: + circuit = optimized.SharedPointCircuit(8) + node = next(n for n in circuit.active if circuit.args[n]) + a, _b = circuit.args[node] + circuit.core[node] = circuit.core[a] + with _expect_assertion(): + optimized.SharedPointCircuit.verify(circuit) + with _expect_assertion(): + baseline.SharedPointCircuit.verify(circuit) + return {"support_rejection": "preserved"} + + +def check_certificate_pin_discipline() -> dict: + """Working certificate may change only the partial_swap/shared.py source pin.""" + base = json.loads(git_show(CERT_REL)) + live = json.loads((ROOT / CERT_REL).read_text(encoding="utf-8")) + require(sha256(git_show(CERT_REL)).hexdigest() == BASE_CERT_SHA256, "base certificate digest drift") + base_pin = base["source_sha256"][SOURCE_REL] + live_pin = live["source_sha256"][SOURCE_REL] + require(base_pin == ORIGINAL_SHA256, "unexpected base shared.py pin") + require(live_pin == OPTIMIZED_SHA256, "optimized shared.py pin missing") + restored = deepcopy(live) + restored["source_sha256"][SOURCE_REL] = ORIGINAL_SHA256 + require(restored == base, "changed fields beyond the partial_swap/shared.py pin") + return { + "certificate": CERT_REL, + "base_pin": base_pin, + "live_pin": live_pin, + "only_pin_changed": True, + } + + +def maybe_write_certificate(write: bool) -> None: + if not write: + return + # Pin-only refresh: replace the single shared.py digest in the committed JSON text. + raw = git_show(CERT_REL).decode() + require(raw.count(ORIGINAL_SHA256) == 1, "base certificate pin occurrence drift") + updated = raw.replace(ORIGINAL_SHA256, OPTIMIZED_SHA256) + (ROOT / CERT_REL).write_text(updated, encoding="utf-8") + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument( + "--write-certificate", + action="store_true", + help="rewrite certificates/partial-swap-network.json with the optimized shared.py pin only", + ) + args = parser.parse_args() + + check_baseline_bytes() + baseline = load_module(PACKAGE / "baseline.py", "partial_swap_digest_baseline") + encoding = check_encoding_foil() + verifies = check_verify_equivalence(baseline, production) + if __debug__: + rejection = check_support_rejection(baseline, production) + else: + # Historical SharedPointCircuit.verify uses assert, stripped under -O. + rejection = {"support_rejection": "skipped_under_-O"} + maybe_write_certificate(args.write_certificate) + pins = check_certificate_pin_discipline() + print( + "PASS_PARTIAL_SWAP_DIGEST", + f"verify_cases={verifies['verify_cases']}", + f"encoding_cases={encoding['node_encoding_cases'] + encoding['output_encoding_cases']}", + "certs=1", + "no_new_kappa", + ) + print( + "controls", + rejection["support_rejection"], + "certificate_pin_only=" + str(pins["only_pin_changed"]), + flush=True, + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/partial_swap/shared.py b/scripts/partial_swap/shared.py index a2f0190704..77a3672dce 100644 --- a/scripts/partial_swap/shared.py +++ b/scripts/partial_swap/shared.py @@ -13,7 +13,6 @@ from functools import lru_cache from hashlib import sha256 from itertools import combinations -import json from exclusion_circuit import ExclusionCircuit @@ -91,6 +90,14 @@ def contained(self,a,b): self.support_in(a,common)&~self.support_in(b,common)) def verify(self): + """Exact support nesting and a byte-stable circuit digest. + + Tooling note (partial-swap replay): node and partial-output digest lines + are written with the same UTF-8 text that + ``json.dumps(..., separators=(',',':'))`` produced historically, but + without building JSON encoder objects per row. Support checks and + ``circuit_sha256`` are unchanged. See ``research/partial-swap-digest/``. + """ # Totals add the empty exclusion set to the original pair outputs. for excluded, node in self.local.outputs.items(): expected = sum(1 << j for j, pair in enumerate(self.local.inputs) @@ -103,22 +110,42 @@ def verify(self): assert not self.local.support[a] & self.local.support[b] assert self.local.support[node] == self.local.support[a] | self.local.support[b] digest=sha256() + update=digest.update + encode=str.encode + args=self.args + provenance=self.provenance + support_in=self.support_in + local_support=self.local.support + core=self.core + union=self.union for node in sorted(self.active): - if self.args[node]: - a,b=self.args[node];common,local=self.provenance[node] + edge=args[node] + if edge: + a,b=edge;common,local=provenance[node] assert a Date: Wed, 14 Oct 2026 17:52:30 +0000 Subject: [PATCH 2/3] =?UTF-8?q?Record=20partial-swap=20digest=20benchmark:?= =?UTF-8?q?=202.07=C3=97=20identical=20receipts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five alternating fresh-process pairs on CPython 3.12.3; median verify 2.176 → 1.050 s. Prepared by Wentao Li with substantial AI assistance. --- research/partial-swap-digest/README.md | 15 +++---- research/partial-swap-digest/RESULT.json | 50 +++++++++++++++++++++++- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/research/partial-swap-digest/README.md b/research/partial-swap-digest/README.md index a422fa40e5..685a408018 100644 --- a/research/partial-swap-digest/README.md +++ b/research/partial-swap-digest/README.md @@ -44,13 +44,14 @@ historical-checker change. ## Result -On Linux / CPython 3.12 (see [RESULT.json](RESULT.json) for the exact -interpreter and platform strings), five alternating fresh-process pairs timing -only `partial_swap.shared.SharedPointCircuit(46).verify` (construction -excluded; inlined local support checks included) gave the median wall-time -ratio recorded in `RESULT.json`. Timing is host-descriptive and is not a -correctness gate. Every verify receipt matches the baseline checker fieldwise -(`roles`, `additions`, `merged_additions`, `circuit_sha256`, flags). +On Linux / CPython 3.12.3 (Linux-6.12.94+-x86_64-with-glibc2.39), five +alternating fresh-process pairs timing only +`partial_swap.shared.SharedPointCircuit(46).verify` (construction excluded; +inlined local support checks included) gave median wall time +**2.176 → 1.050 seconds (2.07×)**. Timing is host-descriptive and is not a +correctness gate; all samples and environment pins are in +[RESULT.json](RESULT.json). Every verify receipt matches the baseline checker +fieldwise (`roles`, `additions`, `merged_additions`, `circuit_sha256`, flags). ## Equivalence diff --git a/research/partial-swap-digest/RESULT.json b/research/partial-swap-digest/RESULT.json index b5c333f7ea..7d1b55491b 100644 --- a/research/partial-swap-digest/RESULT.json +++ b/research/partial-swap-digest/RESULT.json @@ -1,4 +1,50 @@ { - "status": "PENDING_BENCHMARK", - "note": "Filled by research/partial-swap-digest/benchmark.py after the implementation commit." + "environment": { + "executable": "/usr/bin/python3.12", + "platform": "Linux-6.12.94+-x86_64-with-glibc2.39", + "python": "3.12.3 (main, Aug 31 2026, 10:18:26) [GCC 13.3.0]" + }, + "fixture": "partial_swap.shared.SharedPointCircuit(46).verify only (construction excluded); includes inlined local support checks", + "median_baseline_seconds": 2.176399500000116, + "median_optimized_seconds": 1.0500758960001804, + "median_ratio": 2.0726116162557284, + "no_new_kappa": true, + "rounds": 5, + "samples": [ + { + "baseline_seconds": 2.1735980080002264, + "optimized_seconds": 1.0412321750000046, + "ratio": 2.0875248193326494, + "round": 0 + }, + { + "baseline_seconds": 2.176399500000116, + "optimized_seconds": 1.0671551489999729, + "ratio": 2.0394405649821508, + "round": 1 + }, + { + "baseline_seconds": 2.1539880980003545, + "optimized_seconds": 1.0212636050000583, + "ratio": 2.109140174441281, + "round": 2 + }, + { + "baseline_seconds": 2.3100297329997375, + "optimized_seconds": 1.0500758960001804, + "ratio": 2.1998693063985355, + "round": 3 + }, + { + "baseline_seconds": 2.2508478529998683, + "optimized_seconds": 1.0912254210002175, + "ratio": 2.0626790850755112, + "round": 4 + } + ], + "source_sha256": { + "baseline": "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34", + "production": "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" + }, + "status": "PASS_IDENTICAL_PARTIAL_SWAP_DIGEST_RECEIPTS" } From 1baf7a8bc296cdb28bbb5572ed3937052a239244 Mon Sep 17 00:00:00 2001 From: Wentao Li Date: Wed, 14 Oct 2026 18:33:21 +0000 Subject: [PATCH 3/3] Tooling: fold partial-swap SharedPointCircuit.__init__ rewrite into #2039 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port the #2054 merge/lookup construction rewrite onto the producer fork after #2039's verify digests. Identical DAG and circuit_sha256; one re-pin of certificates/partial-swap-network.json; package research/partial-swap-init/. Median construction 0.771 → 0.523 s (1.47×). Prepared by Wentao Li with substantial AI assistance. --- certificates/partial-swap-network.json | 2 +- research/partial-swap-digest/README.md | 8 +- research/partial-swap-digest/RESULT.json | 2 +- research/partial-swap-digest/verify.py | 2 +- research/partial-swap-init/NOTICE.md | 25 +++ research/partial-swap-init/README.md | 126 +++++++++++ research/partial-swap-init/RESULT.json | 50 +++++ research/partial-swap-init/SOURCES.json | 60 ++++++ research/partial-swap-init/TASK.json | 70 ++++++ research/partial-swap-init/VERIFY.json | 55 +++++ research/partial-swap-init/baseline.py | 190 +++++++++++++++++ research/partial-swap-init/benchmark.py | 152 +++++++++++++ research/partial-swap-init/verify.py | 259 +++++++++++++++++++++++ scripts/partial_swap/shared.py | 80 ++++--- tests/test_partial_swap_digest.py | 2 +- tests/test_partial_swap_init.py | 91 ++++++++ 16 files changed, 1136 insertions(+), 38 deletions(-) create mode 100644 research/partial-swap-init/NOTICE.md create mode 100644 research/partial-swap-init/README.md create mode 100644 research/partial-swap-init/RESULT.json create mode 100644 research/partial-swap-init/SOURCES.json create mode 100644 research/partial-swap-init/TASK.json create mode 100644 research/partial-swap-init/VERIFY.json create mode 100644 research/partial-swap-init/baseline.py create mode 100644 research/partial-swap-init/benchmark.py create mode 100644 research/partial-swap-init/verify.py create mode 100644 tests/test_partial_swap_init.py diff --git a/certificates/partial-swap-network.json b/certificates/partial-swap-network.json index 0bd2ac6025..a72693d486 100644 --- a/certificates/partial-swap-network.json +++ b/certificates/partial-swap-network.json @@ -1481,7 +1481,7 @@ "scripts/partial_swap/match_positive_dag.cpp": "8a6d64e2d0ac2c69210fb0b8a5bd0d714ad40b3609f75a5fddfcba3291a3d552", "scripts/partial_swap/paired.py": "ddcecace3a8e04d690914cbd64873ab8dde8c0c3477a255767b0ed6f639bb0c7", "scripts/partial_swap/positive.py": "1dadf771226d6e4f3bf9ce3aae2e6a2ad7173f4d1c900299d0663fc4c432f3e8", - "scripts/partial_swap/shared.py": "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8", + "scripts/partial_swap/shared.py": "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c", "scripts/partial_swap_network.py": "acdd81b4dea2815f8838a0c3ea8ac4968f2bc13fd7c99173473d865779096782", "scripts/partial_swap_producer.py": "dba07d742c68e8e4aedd1d93fc4c47a0481778268f7480997463e2b269fdd0a0" }, diff --git a/research/partial-swap-digest/README.md b/research/partial-swap-digest/README.md index 685a408018..caf471f84e 100644 --- a/research/partial-swap-digest/README.md +++ b/research/partial-swap-digest/README.md @@ -81,13 +81,7 @@ controls. Support and topology checks remain the historical `assert` gates. **Blocked by:** Pin repair outside `certificates/partial-swap-network.json` is outside this tooling change. -2. **Question:** Is `partial_swap.shared.SharedPointCircuit.__init__` - merge/lookup construction worth a separate identical-receipt rewrite? - **Why it matters:** Large partial-swap / skip-strip builds still spend - substantial wall time constructing the shared-point DAG. - **First step:** Profile `SharedPointCircuit(46).__init__` alone after this - digest change. - **Blocked by:** Out of this session’s stop rule. +2. **Answered in-tree:** `partial_swap.shared.SharedPointCircuit.__init__` merge/lookup rewrite lands in the same production file as `research/partial-swap-init/` (identical DAG/`circuit_sha256`; one re-pin). ## Overlap and credit diff --git a/research/partial-swap-digest/RESULT.json b/research/partial-swap-digest/RESULT.json index 7d1b55491b..b17d7c2c42 100644 --- a/research/partial-swap-digest/RESULT.json +++ b/research/partial-swap-digest/RESULT.json @@ -44,7 +44,7 @@ ], "source_sha256": { "baseline": "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34", - "production": "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" + "production": "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c" }, "status": "PASS_IDENTICAL_PARTIAL_SWAP_DIGEST_RECEIPTS" } diff --git a/research/partial-swap-digest/verify.py b/research/partial-swap-digest/verify.py index 90592fc2ca..b659164f63 100644 --- a/research/partial-swap-digest/verify.py +++ b/research/partial-swap-digest/verify.py @@ -27,7 +27,7 @@ BASE_COMMIT = "0b1cccf86e2f5132ed286a26ef0a681a495740ea" ORIGINAL_BLOB = "a2f0190704db83bd8ef48e46e723c49b925804fe" ORIGINAL_SHA256 = "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34" -OPTIMIZED_SHA256 = "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" +OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c" BASE_CERT_SHA256 = "f3c4be597b2f2136da4ae2cc80c7454f63c90aa01f84e5b8131cee4dd55de815" CERT_REL = "certificates/partial-swap-network.json" SOURCE_REL = "scripts/partial_swap/shared.py" diff --git a/research/partial-swap-init/NOTICE.md b/research/partial-swap-init/NOTICE.md new file mode 100644 index 0000000000..41d20b509d --- /dev/null +++ b/research/partial-swap-init/NOTICE.md @@ -0,0 +1,25 @@ +# Notice + +This package accelerates the historical partial-swap shared-point merge +construction in `scripts/partial_swap/shared.py:SharedPointCircuit.__init__` +while preserving node allocation order, merge counts, support checks and +`circuit_sha256`. + +Predecessor credit: + +- Douglas R. Colkitt — shared-point / exclusion circuits and the historical + common-point motif. +- icekylinx — partial-swap producer adaptation of the shared-point circuit + (`scripts/partial_swap/shared.py`, Apache-2.0). +- Closest tooling priors on *different* objects: CrocSwap/integer-mult-bounds + PRs #756 (balanced-Fano packed replay), #1793 (inplace-side prefix), #1861 + (parity-side basis/contains), #1922 (joint-frame cleared product), #1984 + (mixed-point scalar digests), #1994 (canonical shared-point verify digests), + #2039 (partial-swap verify digests; this package stacks on that tip and only + rewrites `__init__`), #2054 (canonical `SharedPointCircuit.__init__` merge + rewrite; this ports the same construction object to the partial-swap fork), + and #2001 (ExclusionCircuit / DisjointTensor support masks — not touched). + +Prepared by Wentao Li with substantial AI assistance under Apache-2.0. +This is not independent human peer review and is not a formal proof of the +multiplication theorem. diff --git a/research/partial-swap-init/README.md b/research/partial-swap-init/README.md new file mode 100644 index 0000000000..dc45f90434 --- /dev/null +++ b/research/partial-swap-init/README.md @@ -0,0 +1,126 @@ +# Faster exact partial-swap merge construction with identical receipts + +**Tooling improvement; no new kappa.** Stacked on open +[CrocSwap/integer-mult-bounds#2039](https://github.com/CrocSwap/integer-mult-bounds/pull/2039) +tip `3b29a00f972bd15871baac0acf5ac204740a9863` (verify digests already applied), +`partial_swap.shared.SharedPointCircuit.__init__` builds the common-point merge +DAG by, for each of `h` commons, sorting the local active set, unpacking child +mappings through a per-node generator, and looking up merge keys with repeated +attribute access. Profiling on the historical full-size circuit (`h=46`) shows +construction wall time dominated by that merge/lookup loop. Open +[CrocSwap/integer-mult-bounds#2054](https://github.com/CrocSwap/integer-mult-bounds/pull/2054) +applied the same construction rewrite to the canonical +`scripts/shared_point_circuit.py`; this package ports it to the distinct +partial-swap producer copy named in #2039's open question. + +This change pre-sorts `local.active` and `local.outputs` once, unpacks children +directly, binds hot lists/dicts locally, and keeps the historical node-allocation +order (including the producer-specific `point_order` / sorted `pair_ids` +contracts). Every structural field (`args`, `core`, `union`, `provenance`, +`outputs`, `active`, `merged_additions`, `additions`) and every verify receipt +(`circuit_sha256`, roles, flags) stays identical. Production `verify` keeps +#2039's hand-rolled digests. `certificates/partial-swap-network.json` updates +only the `scripts/partial_swap/shared.py` `source_sha256` pin relative to the +#2039 tip. + +## Reproduce + +Python **3.12**, standard library only, from the repository root: + +```sh +python3.12 -I -B research/partial-swap-init/verify.py +python3.12 -I -O -B research/partial-swap-init/verify.py +python3.12 -B scripts/research_package.py --package research/partial-swap-init +python3.12 -I -B research/partial-swap-init/benchmark.py --rounds 5 +``` + +Expected: + +```text +PASS_PARTIAL_SWAP_INIT verify_cases=5 mutant=rejected certs=1 no_new_kappa +PASS_REGISTERED_RESEARCH_PACKAGE research/partial-swap-init outcome=completed +PASS_IDENTICAL_PARTIAL_SWAP_INIT_RECEIPTS +``` + +Default verify is read-only aside from the already-committed pin-only certificate +refresh. Full `make verify`, selected cold replay, Lean, and +multiplication-theorem obligations were not rerun for this isolated +historical-checker change. + +## Result + +On Linux / CPython 3.12.3 (Linux-6.12.94+-x86_64-with-glibc2.39), five +alternating fresh-process pairs timing only +`partial_swap.shared.SharedPointCircuit(46)` construction (verify excluded from +the timer; nested `ExclusionCircuit(45)` construction included) gave median wall +time **0.771 → 0.523 seconds (1.47×)**. Timing is host-descriptive and is not a +correctness gate; all samples and environment pins are in +[RESULT.json](RESULT.json). Every verify receipt matches the baseline checker +fieldwise (`roles`, `additions`, `merged_additions`, `circuit_sha256`, flags), +and the constructed DAG matches fieldwise. + +## Equivalence + +The historical constructor walks `sorted(self.local.active)` and +`sorted(self.local.outputs.items())` inside each common-point group, allocates a +new node unless `(core, union)` already appears in the cross-common lookup when +`core.bit_count() >= 2`, and records `(common, local_node)` provenance in +allocation order. This rewrite: + +- sorts those two collections once before the common-point loop; +- replaces `a,b=(mapping[x] for x in self.local.args[node])` with direct indexing; +- uses one `bit_count` and `lookup.get` per internal node; +- binds `args`/`core`/`union`/`provenance` append methods locally; + +and does not change when a merge hits, which node id is allocated, or which +output key is written. A reverse-common-order mutant that walks commons +descending changes `args` / provenance numbering and is rejected by the package +controls. The #2039 tip `circuit_sha256` for `h=46` remains +`b0402f9eaaf138129939521c2a2ef1c3e8230b730de0a7bdea3596eb415dd173`. + +## Open next questions + +1. **Question:** Should research packages that pin live + `scripts/partial_swap/shared.py` bytes refresh that one SHA-256 entry after + this equivalence-preserving constructor rewrite? + **Why it matters:** Those provenance packages bind working-tree bytes; leaving + the old pin keeps this tooling PR focused. + **First step:** Dedicated provenance follow-up that only rewrites that one + entry after confirming `circuit_sha256` identity. + **Blocked by:** Pin repair outside `certificates/partial-swap-network.json` + is outside this tooling change. + +2. **Question:** Once open #2039 and #2054 land, should the partial_swap and + canonical constructors share a single tested helper for the merge/lookup loop? + **Why it matters:** The producers diverge on `point_order` / `pair_ids` + sorting and inlined local support checks; a shared helper risks coupling + those contracts, but duplicated micro-opts drift. + **First step:** Diff the two optimized `__init__` bodies after both land. + **Blocked by:** Depends on merge order of #2039 / #2054 / this follow-up. + +## Overlap and credit + +Closest priors (different objects): +[CrocSwap/integer-mult-bounds#756](https://github.com/CrocSwap/integer-mult-bounds/pull/756), +[CrocSwap/integer-mult-bounds#1793](https://github.com/CrocSwap/integer-mult-bounds/pull/1793), +[CrocSwap/integer-mult-bounds#1861](https://github.com/CrocSwap/integer-mult-bounds/pull/1861), +[CrocSwap/integer-mult-bounds#1922](https://github.com/CrocSwap/integer-mult-bounds/pull/1922), +[CrocSwap/integer-mult-bounds#1984](https://github.com/CrocSwap/integer-mult-bounds/pull/1984), +[CrocSwap/integer-mult-bounds#1994](https://github.com/CrocSwap/integer-mult-bounds/pull/1994), +[CrocSwap/integer-mult-bounds#2039](https://github.com/CrocSwap/integer-mult-bounds/pull/2039) +(partial-swap verify digests; this stacks on that tip and only rewrites +`__init__`), +[CrocSwap/integer-mult-bounds#2054](https://github.com/CrocSwap/integer-mult-bounds/pull/2054) +(canonical `__init__` rewrite; this ports the same object to the partial-swap +fork), +[CrocSwap/integer-mult-bounds#1874](https://github.com/CrocSwap/integer-mult-bounds/pull/1874), +[CrocSwap/integer-mult-bounds#2001](https://github.com/CrocSwap/integer-mult-bounds/pull/2001) +(ExclusionCircuit / DisjointTensor support masks — not touched). +No competing open PR on the `partial_swap.shared` `__init__` merge object at +refresh. + +Douglas R. Colkitt authored the shared-point / exclusion circuits. icekylinx +adapted the partial-swap producer copy. Prepared by Wentao Li +([VictorLiwentao](https://github.com/VictorLiwentao), +[@Is__Victor](https://x.com/Is__Victor)) with substantial AI assistance, under +Apache-2.0. diff --git a/research/partial-swap-init/RESULT.json b/research/partial-swap-init/RESULT.json new file mode 100644 index 0000000000..14c4fb4c00 --- /dev/null +++ b/research/partial-swap-init/RESULT.json @@ -0,0 +1,50 @@ +{ + "environment": { + "executable": "/usr/bin/python3.12", + "platform": "Linux-6.12.94+-x86_64-with-glibc2.39", + "python": "3.12.3 (main, Aug 31 2026, 10:18:26) [GCC 13.3.0]" + }, + "fixture": "partial_swap.shared.SharedPointCircuit(46).__init__ only (verify excluded from timer); includes nested ExclusionCircuit(45) construction", + "median_baseline_seconds": 0.7706708210000102, + "median_optimized_seconds": 0.5226033470000289, + "median_ratio": 1.4746763973556556, + "no_new_kappa": true, + "rounds": 5, + "samples": [ + { + "baseline_seconds": 0.7852667320000251, + "optimized_seconds": 0.5226033470000289, + "ratio": 1.5026056310350835, + "round": 0 + }, + { + "baseline_seconds": 0.8132675960000029, + "optimized_seconds": 0.5527705239999818, + "ratio": 1.4712571685534188, + "round": 1 + }, + { + "baseline_seconds": 0.7420148750000521, + "optimized_seconds": 0.525431913000034, + "ratio": 1.4121998619448228, + "round": 2 + }, + { + "baseline_seconds": 0.7706708210000102, + "optimized_seconds": 0.5023050579999904, + "ratio": 1.5342684863030485, + "round": 3 + }, + { + "baseline_seconds": 0.7317583920000175, + "optimized_seconds": 0.5156376169999817, + "ratio": 1.4191330653055196, + "round": 4 + } + ], + "source_sha256": { + "baseline": "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8", + "production": "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c" + }, + "status": "PASS_IDENTICAL_PARTIAL_SWAP_INIT_RECEIPTS" +} diff --git a/research/partial-swap-init/SOURCES.json b/research/partial-swap-init/SOURCES.json new file mode 100644 index 0000000000..c78579e86f --- /dev/null +++ b/research/partial-swap-init/SOURCES.json @@ -0,0 +1,60 @@ +{ + "schema_version": 1, + "base_commit": "3b29a00f972bd15871baac0acf5ac204740a9863", + "files": [ + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "06c96f5579bb67ed1b86d334e78fbed7da6945f1", + "sha256": "6686ad58f1fbdbc87134a78901b60fd53a20d3984355e91defbbebc9e9fa8075" + }, + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "ae6a99f28aa468649eb66a361e764d769363bf11", + "sha256": "10b9e340fd8e354a37a0c4813c90e5de1dd42044b5f6aca4a3fc5a42b685fa32" + }, + { + "path": "certificates/partial-swap-network.json", + "usage": "provenance", + "git_blob": "0bd2ac6025f43f3b735a4c443fab399b6b4b4471", + "sha256": "6e6ebabf06ee125e58f6871748aaa1fddc4cbf5e70338c61742bca85b9b3e7d4" + }, + { + "path": "scripts/partial_swap/shared.py", + "usage": "provenance", + "git_blob": "77a3672dce3b377eee30a6c3e993a63c2d3840d5", + "sha256": "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" + }, + { + "path": "scripts/exclusion_circuit.py", + "usage": "provenance", + "git_blob": "aaa99986c4b81c5d4fbe016fd216a4818940bb95", + "sha256": "b253f9d7318becda1c1f3b24e2287ed44a9c27fcea00cf9d531afb950d0457a0" + }, + { + "path": "scripts/partial_swap_network.py", + "usage": "provenance", + "git_blob": "2e8a834886362b576ad8cff96a639e6e41a00af7", + "sha256": "acdd81b4dea2815f8838a0c3ea8ac4968f2bc13fd7c99173473d865779096782" + }, + { + "path": "scripts/partial_swap_producer.py", + "usage": "provenance", + "git_blob": "9a450f15fba11c2ad49df346a3e0d3cdb25b1f5e", + "sha256": "dba07d742c68e8e4aedd1d93fc4c47a0481778268f7480997463e2b269fdd0a0" + }, + { + "path": "scripts/partial_swap/README.md", + "usage": "provenance", + "git_blob": "3e753db831c6df9bdfb8885042f2aa464ce0d356", + "sha256": "a81a6a59b89f7db539bc317a7dce23ab84a75c7abebae105091de4e2aeb3f941" + }, + { + "path": "notes/partial-swap-note.tex", + "usage": "provenance", + "git_blob": "5799f6a1fe7790b252d120e0c4f737c333a4773b", + "sha256": "bb9cc56d384973a8343a3789db7d7c1b353903ecbe4a9118522f14a9d4429b13" + } + ] +} diff --git a/research/partial-swap-init/TASK.json b/research/partial-swap-init/TASK.json new file mode 100644 index 0000000000..799d36a183 --- /dev/null +++ b/research/partial-swap-init/TASK.json @@ -0,0 +1,70 @@ +{ + "schema_version": 1, + "task_id": "replay-runtime", + "priority_revision": 3, + "base_commit": "3b29a00f972bd15871baac0acf5ac204740a9863", + "chooser_seed": "c88339d24517c9354275ac905ca0f320", + "original_card": { + "id": "replay-runtime", + "question": "Can one measured replay bottleneck be sped up without dropping coverage?", + "starting_points": [ + "scripts/run_isolated_tests.py", + "scripts/verify_replay_coverage.py", + "certificates/selected-result.json" + ], + "methods": [ + "Profile one isolated replay and optimize the measured bottleneck.", + "Design source-bound reuse with explicit dependency invalidation and negative controls." + ], + "acceptance_gate": "Report before/after wall time on the same fixture, retained checks and invalidation behavior.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read the selected reproduction command and choose a single replay stage for profiling.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "Measure one unchanged fixture, preserve check coverage, and test one optimization with invalidation controls.", + "bottleneck_link": "Faster trustworthy replays increase review throughput and let mechanism candidates be checked sooner.", + "allowed_variations": [ + "Profile one stage or design one source-bound cache boundary." + ], + "scope_change_triggers": [ + "Skipping coverage or comparing different fixtures to claim speedup." + ], + "overlap_terms": [ + "replay runtime", + "cache invalidation", + "isolated tests" + ] + }, + "scope_status": "refined", + "actual_scope": "Can scripts/partial_swap/shared.py:SharedPointCircuit.__init__ emit the same merge/lookup DAG (same args/core/union/provenance/outputs/active/merged_additions and the same circuit_sha256) with a tighter construction loop, so full-size partial-swap builds stay fieldwise identical while certificates/partial-swap-network.json updates only the shared.py source_sha256 pin?", + "scope_change_reason": "The catalogue card asks for one measured replay bottleneck with before/after wall time and retained checks. Expertise override selected verifier-engineering after open tooling PR #2039 left SharedPointCircuit.__init__ merge/lookup construction as an explicit next question on the partial-swap producer fork, and open #2054 answered the same construction object on the canonical scripts/shared_point_circuit.py. This package ports that constructor rewrite to scripts/partial_swap/shared.py stacked on the #2039 tip so verify digests are not regresssed. Profiling named the per-common-point merge loop (repeated sorted(active), per-node generator unpacks, repeated attribute lookups) as the construction bottleneck; ExclusionCircuit/DisjointTensor support masks (#2001) stay untouched.", + "bottleneck_link": "Side result on review throughput: partial-swap producers, skip-strip graphs and related historical packages construct partial_swap.shared.SharedPointCircuit before verify. A faster identical constructor does not change kappa or the binding complex supplier.", + "budget_minutes": 60, + "stop_rule": "Ship an equivalence-preserving partial_swap SharedPointCircuit.__init__ change with frozen baseline on the #2039 tip, identical structure and receipts on the historical h=46 circuit, pin-only certificate refresh, registered replay and a measured before/after median. Do not reopen verify digests, ExclusionCircuit/DisjointTensor support masks (#2001), or edit scripts/shared_point_circuit.py.", + "outcome": "completed", + "evidence": "PASS_PARTIAL_SWAP_INIT via research/partial-swap-init/verify.py (also under -O); PASS_IDENTICAL_PARTIAL_SWAP_INIT_RECEIPTS via benchmark.py; certificates/partial-swap-network.json changes only scripts/partial_swap/shared.py in source_sha256 relative to the #2039 tip pin.", + "author": "Wentao Li", + "github": "VictorLiwentao", + "email": "wentaol4@illinois.edu", + "ai_assistance": "Substantial AI assistance for orientation, overlap search, profiling, implementation, packaging, benchmarking and writing. Not independent human peer review.", + "open_questions": [ + { + "question": "Should research packages that pin live scripts/partial_swap/shared.py bytes (for example copied-fixed / skip-strip provenance) refresh that one SHA-256 entry after this equivalence-preserving constructor rewrite?", + "why_it_matters": "Those provenance packages bind working-tree bytes of shared.py; leaving old pins keeps this tooling PR focused, but a later full provenance replay on main would see a hash mismatch until refreshed.", + "first_step": "Open a dedicated provenance follow-up that only rewrites the shared.py entry after confirming circuit_sha256 identity.", + "blocked_by": "Pin repair outside certificates/partial-swap-network.json is outside this tooling change." + }, + { + "question": "Once open #2039 and #2054 land, should main's partial_swap and canonical constructors share a single tested helper for the merge/lookup loop?", + "why_it_matters": "The two producers deliberately diverge on point_order / pair_ids sorting and inlined local support checks; a shared helper risks coupling those contracts, but duplicated micro-opts drift.", + "first_step": "Diff the two optimized __init__ bodies after both land and decide whether a private helper preserves both historical contracts.", + "blocked_by": "Depends on merge order of #2039 / #2054 / this follow-up." + } + ] +} diff --git a/research/partial-swap-init/VERIFY.json b/research/partial-swap-init/VERIFY.json new file mode 100644 index 0000000000..408d349d98 --- /dev/null +++ b/research/partial-swap-init/VERIFY.json @@ -0,0 +1,55 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "scripts/partial_swap/shared.py", + "scripts/exclusion_circuit.py", + "scripts/partial_swap_network.py", + "scripts/partial_swap_producer.py", + "certificates/partial-swap-network.json", + "notes/partial-swap-note.tex", + "scripts/partial_swap/README.md" + ], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 300, + "checks": "Exact baseline copy of the #2039-tip scripts/partial_swap/shared.py; identical SharedPointCircuit construction structure and verify receipts on h in {6,8,10,12,46}; reverse-common reorder mutant changes node allocation; support-core rejection preserved; certificates/partial-swap-network.json changes only the shared.py source_sha256 pin relative to the #2039 tip." + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 300, + "checks": "Same construction equivalence under -O. Historical support checks use assert and are stripped under -O; circuit_sha256 identity and structure equality remain the gates." + }, + { + "argv": [ + "{python}", + "-I", + "-B", + "-m", + "unittest", + "discover", + "-s", + "tests", + "-p", + "test_partial_swap_init.py", + "-v" + ], + "timeout_seconds": 120, + "checks": "Focused partial-swap init package controls." + } + ] +} diff --git a/research/partial-swap-init/baseline.py b/research/partial-swap-init/baseline.py new file mode 100644 index 0000000000..77a3672dce --- /dev/null +++ b/research/partial-swap-init/baseline.py @@ -0,0 +1,190 @@ +# Copyright 2026 icekylinx. Licensed under Apache-2.0. +# Adapted with AI assistance from the archived partial-swap research producer. +# Underlying circuit modules: jacklightChen/integer-mult-bounds, PR7 +# commit 6725c6a17b17871a35353fd29157f4ed851bc114; original credits retained. +#!/usr/bin/env python3 +"""Merge equal sums across the common-point circuits, with exact certificates. + +Supports are represented by their provenance in the small pair circuit, not +by half a million dense global bit vectors. A sum that occurs in two distinct +common-point groups must be a pair-star; its fixed pair and union of vertices +identify its support exactly. +""" +from functools import lru_cache +from hashlib import sha256 +from itertools import combinations + +from exclusion_circuit import ExclusionCircuit + + +class SharedPointCircuit: + def __init__(self,h,circuit=None,point_order=None): + assert h>=6 and h!=9, 'The ambient form I-J/9 must be nondegenerate' + self.h=h + self.local=circuit or ExclusionCircuit(h-1) + assert self.local.n==h-1, 'Pair circuit has the wrong ground size' + self.inputs=list(combinations(range(h),3)) + self.variables={t:i+1 for i,t in enumerate(self.inputs)} + self.args=[None]*(len(self.inputs)+1) + self.core=[0]+[sum(1<=2 and key in lookup: + mapping[node]=lookup[key];self.merged+=1 + continue + new=len(self.args);mapping[node]=new + self.args.append((a,b));self.core.append(core);self.union.append(union) + self.provenance.append((common,node)) + if core.bit_count()>=2:lookup[key]=new + for pair,node in sorted(self.local.outputs.items()): + t=tuple(sorted((common,*(self.points[common][x] for x in pair)))) + self.outputs[common,t]=mapping[node] + self.active=set();stack=list(self.outputs.values()) + while stack: + n=stack.pop() + if n in self.active:continue + self.active.add(n) + if self.args[n]:stack.extend(self.args[n]) + self.additions=sum(self.args[n] is not None for n in self.active) + + @lru_cache(maxsize=16384) + def support_in(self,node,common): + """Exact pair-input support in coordinates with this common point.""" + assert self.core[node]&(1< dict: + env = dict(os.environ) + env.pop("PYTHONOPTIMIZE", None) + env["PYTHONDONTWRITEBYTECODE"] = "1" + proc = subprocess.run( + [sys.executable, "-I", "-B", "-c", WORKER, str(ROOT), mode], + cwd=ROOT, + env=env, + capture_output=True, + text=True, + check=False, + ) + require(proc.returncode == 0, f"worker {mode} failed: {proc.stderr[-2000:]}") + line = proc.stdout.strip().splitlines()[-1] + return json.loads(line) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--rounds", type=int, default=5) + parser.add_argument("--out", type=Path, default=PACKAGE / "RESULT.json") + args = parser.parse_args() + require(args.rounds >= 1, "rounds") + + samples = [] + for i in range(args.rounds): + order = ("optimized", "baseline") if i % 2 == 0 else ("baseline", "optimized") + pair = {} + for mode in order: + pair[mode] = run_worker(mode) + require( + pair["baseline"]["record"] == pair["optimized"]["record"], + f"receipt mismatch on round {i}", + ) + samples.append( + dict( + round=i, + baseline_seconds=pair["baseline"]["seconds"], + optimized_seconds=pair["optimized"]["seconds"], + ratio=pair["baseline"]["seconds"] / pair["optimized"]["seconds"], + ) + ) + print( + f"round {i}: baseline={pair['baseline']['seconds']:.3f}s " + f"optimized={pair['optimized']['seconds']:.3f}s " + f"ratio={samples[-1]['ratio']:.3f}", + flush=True, + ) + + base_med = statistics.median(s["baseline_seconds"] for s in samples) + opt_med = statistics.median(s["optimized_seconds"] for s in samples) + result = dict( + status="PASS_IDENTICAL_PARTIAL_SWAP_INIT_RECEIPTS", + fixture=( + "partial_swap.shared.SharedPointCircuit(46).__init__ only " + "(verify excluded from timer); includes nested ExclusionCircuit(45) construction" + ), + rounds=args.rounds, + median_baseline_seconds=base_med, + median_optimized_seconds=opt_med, + median_ratio=base_med / opt_med, + samples=samples, + environment=dict( + python=sys.version, + platform=platform.platform(), + executable=sys.executable, + ), + source_sha256=dict( + baseline=sha256((PACKAGE / "baseline.py").read_bytes()).hexdigest(), + production=sha256((ROOT / "scripts/partial_swap/shared.py").read_bytes()).hexdigest(), + ), + no_new_kappa=True, + ) + args.out.write_text(json.dumps(result, indent=2, sort_keys=True) + "\n") + print( + "PASS_IDENTICAL_PARTIAL_SWAP_INIT_RECEIPTS", + f"median {base_med:.3f} -> {opt_med:.3f} s ({base_med / opt_med:.2f}x)", + flush=True, + ) + + +if __name__ == "__main__": + main() diff --git a/research/partial-swap-init/verify.py b/research/partial-swap-init/verify.py new file mode 100644 index 0000000000..fd2290bff7 --- /dev/null +++ b/research/partial-swap-init/verify.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python3 +"""Equivalence, pin and mutation controls for partial-swap merge construction. + +Read-only by default. Regenerates no certificate unless --write-certificate is +passed (pin-only refresh of certificates/partial-swap-network.json). Timing is +not a pass gate; see benchmark.py / RESULT.json. +""" +from __future__ import annotations + +import argparse +from copy import deepcopy +from hashlib import sha256 +import importlib.util +import json +from pathlib import Path +import subprocess +import sys + +ROOT = Path(__file__).resolve().parents[2] +PACKAGE = Path(__file__).resolve().parent +SCRIPTS = ROOT / "scripts" +sys.path.insert(0, str(SCRIPTS)) + +from certify import require # noqa: E402 +from partial_swap import shared as production # noqa: E402 + +# Stacked on open CrocSwap/integer-mult-bounds#2039 tip (digest rewrite already applied). +BASE_COMMIT = "3b29a00f972bd15871baac0acf5ac204740a9863" +ORIGINAL_BLOB = "77a3672dce3b377eee30a6c3e993a63c2d3840d5" +ORIGINAL_SHA256 = "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" +OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c" +BASE_CERT_SHA256 = "6e6ebabf06ee125e58f6871748aaa1fddc4cbf5e70338c61742bca85b9b3e7d4" +FULL_SIZE_SHA256 = "b0402f9eaaf138129939521c2a2ef1c3e8230b730de0a7bdea3596eb415dd173" +CERT_REL = "certificates/partial-swap-network.json" +SOURCE_REL = "scripts/partial_swap/shared.py" + + +def load_module(path: Path, name: str): + spec = importlib.util.spec_from_file_location(name, path) + require(spec is not None and spec.loader is not None, f"missing module {path}") + module = importlib.util.module_from_spec(spec) + sys.modules[name] = module + spec.loader.exec_module(module) + return module + + +def digest_file(path: Path) -> str: + return sha256(path.read_bytes()).hexdigest() + + +def git_show(path: str) -> bytes: + return subprocess.check_output(["git", "show", f"{BASE_COMMIT}:{path}"], cwd=ROOT) + + +def check_baseline_bytes() -> None: + baseline = PACKAGE / "baseline.py" + original = git_show(SOURCE_REL) + require(sha256(original).hexdigest() == ORIGINAL_SHA256, "base partial_swap/shared.py sha256 drift") + blob = ( + subprocess.check_output( + ["git", "rev-parse", f"{BASE_COMMIT}:{SOURCE_REL}"], cwd=ROOT + ) + .decode() + .strip() + ) + require(blob == ORIGINAL_BLOB, "base partial_swap/shared.py blob drift") + require(baseline.read_bytes() == original, "baseline.py must be an exact copy of the base commit source") + require( + digest_file(ROOT / SOURCE_REL) == OPTIMIZED_SHA256, + "production partial_swap/shared.py does not match the claimed optimized digest", + ) + + +def circuit_structure(circuit) -> dict: + return dict( + args=circuit.args, + core=circuit.core, + union=circuit.union, + provenance=circuit.provenance, + outputs=dict(sorted(circuit.outputs.items())), + active=sorted(circuit.active), + additions=circuit.additions, + merged=circuit.merged, + pair_ids=circuit.pair_ids, + variables=circuit.variables, + points=circuit.points, + ) + + +def check_construction_equivalence(baseline, optimized) -> dict: + records = [] + for h in (6, 8, 10, 12, 46): + old = baseline.SharedPointCircuit(h) + new = optimized.SharedPointCircuit(h) + require(circuit_structure(old) == circuit_structure(new), f"structure mismatch on h={h}") + old_receipt = old.verify() + new_receipt = new.verify() + require(old_receipt == new_receipt, f"verify mismatch on h={h}") + require( + baseline.SharedPointCircuit.verify(new) == new_receipt, + f"cross-engine verify mismatch on h={h}", + ) + records.append( + dict( + h=h, + roles=new_receipt["roles"], + additions=new_receipt["additions"], + partial_outputs=new_receipt["partial_outputs"], + merged_additions=new_receipt["merged_additions"], + circuit_sha256=new_receipt["circuit_sha256"], + ) + ) + require(records[-1]["additions"] == 486330, "unexpected full-size additions") + require(records[-1]["roles"] == 531870, "unexpected full-size roles") + require(records[-1]["merged_additions"] == 45706, "unexpected full-size merges") + require( + records[-1]["circuit_sha256"] == FULL_SIZE_SHA256, + "unexpected full-size circuit_sha256", + ) + return {"verify_cases": len(records), "records": records} + + +def check_reorder_mutant_rejected(baseline, optimized) -> dict: + """A mutant that walks commons in reverse must change node allocation order.""" + from itertools import combinations + + circuit = optimized.SharedPointCircuit(8) + local = circuit.local + active_sorted = sorted(local.active) + h = 8 + inputs = list(combinations(range(h), 3)) + variables = {t: i + 1 for i, t in enumerate(inputs)} + args = [None] * (len(inputs) + 1) + core = [0] + [sum(1 << i for i in t) for t in inputs] + union = list(core) + provenance = [None] * len(args) + points = [[j for j in range(h) if j != i] for i in range(h)] + lookup = {} + merged = 0 + # Historical contract: commons ascend. Reverse order preserves per-common + # topology but changes when cross-common merges are discovered. + for common in range(h - 1, -1, -1): + mapping = {} + pts = points[common] + for node in active_sorted: + if local.args[node] is None: + a, b = local.inputs[node - 1] + t = tuple(sorted((common, pts[a], pts[b]))) + mapping[node] = variables[t] + continue + a, b = (mapping[x] for x in local.args[node]) + cval = core[a] & core[b] + uval = union[a] | union[b] + key = (cval, uval) + if cval.bit_count() >= 2 and key in lookup: + mapping[node] = lookup[key] + merged += 1 + continue + new = len(args) + mapping[node] = new + args.append((a, b)) + core.append(cval) + union.append(uval) + provenance.append((common, node)) + if cval.bit_count() >= 2: + lookup[key] = new + require(args != circuit.args, "reverse-common mutant must change args allocation") + require(provenance != circuit.provenance, "reverse-common mutant must change provenance order") + require(merged > 0, "mutant should still perform some merges") + return {"reorder_mutant": "rejected"} + + +class _expect_assertion: + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + require(exc_type is AssertionError, "expected AssertionError from corrupted core") + return True + + +def check_support_rejection(baseline, optimized) -> dict: + circuit = optimized.SharedPointCircuit(8) + node = next(n for n in circuit.active if circuit.args[n]) + a, _b = circuit.args[node] + circuit.core[node] = circuit.core[a] + with _expect_assertion(): + optimized.SharedPointCircuit.verify(circuit) + with _expect_assertion(): + baseline.SharedPointCircuit.verify(circuit) + return {"support_rejection": "preserved"} + + +def check_certificate_pin_discipline() -> dict: + """Working certificate may change only the partial_swap/shared.py source pin.""" + base = json.loads(git_show(CERT_REL)) + live = json.loads((ROOT / CERT_REL).read_text(encoding="utf-8")) + require(sha256(git_show(CERT_REL)).hexdigest() == BASE_CERT_SHA256, "base certificate digest drift") + base_pin = base["source_sha256"][SOURCE_REL] + live_pin = live["source_sha256"][SOURCE_REL] + require(base_pin == ORIGINAL_SHA256, "unexpected base shared.py pin") + require(live_pin == OPTIMIZED_SHA256, "optimized shared.py pin missing") + restored = deepcopy(live) + restored["source_sha256"][SOURCE_REL] = ORIGINAL_SHA256 + require(restored == base, "changed fields beyond the partial_swap/shared.py pin") + return { + "certificate": CERT_REL, + "base_pin": base_pin, + "live_pin": live_pin, + "only_pin_changed": True, + } + + +def maybe_write_certificate(write: bool) -> None: + if not write: + return + raw = git_show(CERT_REL).decode() + require(raw.count(ORIGINAL_SHA256) == 1, "base certificate pin occurrence drift") + updated = raw.replace(ORIGINAL_SHA256, OPTIMIZED_SHA256) + (ROOT / CERT_REL).write_text(updated, encoding="utf-8") + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument( + "--write-certificate", + action="store_true", + help="rewrite certificates/partial-swap-network.json with the optimized shared.py pin only", + ) + args = parser.parse_args() + + check_baseline_bytes() + baseline = load_module(PACKAGE / "baseline.py", "partial_swap_init_baseline") + verifies = check_construction_equivalence(baseline, production) + mutant = check_reorder_mutant_rejected(baseline, production) + if __debug__: + rejection = check_support_rejection(baseline, production) + else: + # Historical SharedPointCircuit.verify uses assert, stripped under -O. + rejection = {"support_rejection": "skipped_under_-O"} + maybe_write_certificate(args.write_certificate) + pins = check_certificate_pin_discipline() + print( + "PASS_PARTIAL_SWAP_INIT", + f"verify_cases={verifies['verify_cases']}", + f"mutant={mutant['reorder_mutant']}", + "certs=1", + "no_new_kappa", + ) + print( + "controls", + rejection["support_rejection"], + "certificate_pin_only=" + str(pins["only_pin_changed"]), + flush=True, + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/partial_swap/shared.py b/scripts/partial_swap/shared.py index 77a3672dce..9a48086000 100644 --- a/scripts/partial_swap/shared.py +++ b/scripts/partial_swap/shared.py @@ -19,49 +19,75 @@ class SharedPointCircuit: def __init__(self,h,circuit=None,point_order=None): + """Merge equal pair-star sums across common-point groups. + + Tooling note (partial-swap / skip-strip replay): the merge/lookup loop + keeps the historical node-allocation order and output keys, but + pre-sorts the local active set and output items once, unpacks child + mappings without a per-node generator, and binds hot attributes locally. + ``merged_additions``, topology and ``circuit_sha256`` are unchanged. + See ``research/partial-swap-init/``. + """ assert h>=6 and h!=9, 'The ambient form I-J/9 must be nondegenerate' self.h=h self.local=circuit or ExclusionCircuit(h-1) assert self.local.n==h-1, 'Pair circuit has the wrong ground size' self.inputs=list(combinations(range(h),3)) self.variables={t:i+1 for i,t in enumerate(self.inputs)} - self.args=[None]*(len(self.inputs)+1) + nin=len(self.inputs) + self.args=[None]*(nin+1) self.core=[0]+[sum(1<=2 and key in lookup: - mapping[node]=lookup[key];self.merged+=1 + pts=self.points[common] + bit=1<=2:lookup[key]=new - for pair,node in sorted(self.local.outputs.items()): - t=tuple(sorted((common,*(self.points[common][x] for x in pair)))) - self.outputs[common,t]=mapping[node] - self.active=set();stack=list(self.outputs.values()) + a=mapping[ab[0]];b=mapping[ab[1]] + cval=core[a]&core[b];uval=union[a]|union[b] + assert cval&bit + if cval.bit_count()>=2: + key=(cval,uval) + hit=lookup.get(key) + if hit is not None: + mapping[node]=hit;self.merged+=1 + continue + new=len(args);mapping[node]=new + append_args((a,b));append_core(cval);append_union(uval) + append_prov((common,node));lookup[key]=new + else: + new=len(args);mapping[node]=new + append_args((a,b));append_core(cval);append_union(uval) + append_prov((common,node)) + outs=self.outputs + for pair,node in outputs_items: + outs[common,tuple(sorted((common,*(pts[x] for x in pair))))]=mapping[node] + self.active=set();stack=list(self.outputs.values());active=self.active while stack: n=stack.pop() - if n in self.active:continue - self.active.add(n) - if self.args[n]:stack.extend(self.args[n]) - self.additions=sum(self.args[n] is not None for n in self.active) + if n in active:continue + active.add(n) + edge=args[n] + if edge:stack.extend(edge) + self.additions=sum(args[n] is not None for n in active) @lru_cache(maxsize=16384) def support_in(self,node,common): diff --git a/tests/test_partial_swap_digest.py b/tests/test_partial_swap_digest.py index 706fce2af7..409e07e282 100644 --- a/tests/test_partial_swap_digest.py +++ b/tests/test_partial_swap_digest.py @@ -16,7 +16,7 @@ from partial_swap import shared as production # noqa: E402 ORIGINAL_SHA256 = "81e9af92cdf38243a540cdcff2062778e449467848d444da37a9553c12ca4c34" -OPTIMIZED_SHA256 = "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" +OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c" def load_baseline(): diff --git a/tests/test_partial_swap_init.py b/tests/test_partial_swap_init.py new file mode 100644 index 0000000000..23f0505a28 --- /dev/null +++ b/tests/test_partial_swap_init.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +"""Focused controls for the partial-swap merge-construction tooling package.""" +from __future__ import annotations + +from copy import deepcopy +from hashlib import sha256 +import importlib.util +import json +import subprocess +import unittest +from pathlib import Path +import sys + +ROOT = Path(__file__).resolve().parents[1] +PACKAGE = ROOT / "research" / "partial-swap-init" +sys.path.insert(0, str(ROOT / "scripts")) + +from partial_swap import shared as production # noqa: E402 + +BASE_COMMIT = "3b29a00f972bd15871baac0acf5ac204740a9863" +ORIGINAL_SHA256 = "b27c8bfe1de3f7d2d5fb19ac742adf11597c2aaa7add68430443119997e646e8" +OPTIMIZED_SHA256 = "7290bd639600aecff11941d3faf95c9ce95589125cc6a7f7440fb86af7a0f17c" + + +def load_baseline(): + spec = importlib.util.spec_from_file_location("baseline_pspc_init_test", PACKAGE / "baseline.py") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +class PartialSwapInitTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.baseline = load_baseline() + + def test_baseline_matches_base_commit_bytes(self): + original = subprocess.check_output( + ["git", "show", f"{BASE_COMMIT}:scripts/partial_swap/shared.py"], + cwd=ROOT, + ) + self.assertEqual((PACKAGE / "baseline.py").read_bytes(), original) + self.assertEqual(sha256(original).hexdigest(), ORIGINAL_SHA256) + + def test_small_circuit_structure_and_receipts_match(self): + for h in (6, 8, 10): + old = self.baseline.SharedPointCircuit(h) + new = production.SharedPointCircuit(h) + self.assertEqual(old.args, new.args) + self.assertEqual(old.core, new.core) + self.assertEqual(old.union, new.union) + self.assertEqual(old.provenance, new.provenance) + self.assertEqual(old.outputs, new.outputs) + self.assertEqual(old.active, new.active) + self.assertEqual(old.merged, new.merged) + self.assertEqual(old.additions, new.additions) + self.assertEqual(old.verify(), new.verify()) + + def test_support_rejection_preserved(self): + circuit = production.SharedPointCircuit(8) + node = next(n for n in circuit.active if circuit.args[n]) + a, _b = circuit.args[node] + circuit.core[node] = circuit.core[a] + with self.assertRaises(AssertionError): + circuit.verify() + with self.assertRaises(AssertionError): + self.baseline.SharedPointCircuit.verify(circuit) + + def test_production_digest_pin(self): + self.assertEqual( + sha256((ROOT / "scripts/partial_swap/shared.py").read_bytes()).hexdigest(), + OPTIMIZED_SHA256, + ) + + def test_certificate_pin_only(self): + base = json.loads( + subprocess.check_output( + ["git", "show", f"{BASE_COMMIT}:certificates/partial-swap-network.json"], + cwd=ROOT, + ) + ) + live = json.loads((ROOT / "certificates/partial-swap-network.json").read_text(encoding="utf-8")) + self.assertEqual(base["source_sha256"]["scripts/partial_swap/shared.py"], ORIGINAL_SHA256) + self.assertEqual(live["source_sha256"]["scripts/partial_swap/shared.py"], OPTIMIZED_SHA256) + restored = deepcopy(live) + restored["source_sha256"]["scripts/partial_swap/shared.py"] = ORIGINAL_SHA256 + self.assertEqual(restored, base) + + +if __name__ == "__main__": + unittest.main()