diff --git a/certificates/joint-dual-kappa.json b/certificates/joint-dual-kappa.json index 240efb3da1..3373a52446 100644 --- a/certificates/joint-dual-kappa.json +++ b/certificates/joint-dual-kappa.json @@ -838,11 +838,11 @@ "scripts/experiments/binary_frame_replay.py": "1a572dbb33faba6695b3293768a7e61392d11cb4c2d5f708eedcd2cb95d0aff9", "scripts/experiments/joint_dual_compiler.py": "853d3fc4a740c5b74c23b3a6af5d4dc9b41fb38e9b55678539a7e0ee71947c13", "scripts/experiments/joint_dual_compose.py": "3554e957570e2d3f65c5bd7c945338c9e2fc5f3e79efa2b436a4dfc61899c394", - "scripts/experiments/joint_dual_reclaim_compiler.py": "9984aaccf880e4840402322d76678bfddb33ce7e494af78430a43429f51b85fd", + "scripts/experiments/joint_dual_reclaim_compiler.py": "edab206b83cfe3f7a08f1b605b182e354c87cc24e2f3ad81a95f7a083ff342fb", "scripts/experiments/pin_joint_dual_sources.py": "5d41535a73ad62fae7acb5365c5b7f40d7c99e52b6bc4266e44572018080acc5", "scripts/experiments/verify_joint_dual.py": "7a31bba1e9c0ded32ae285df2ca9bc91ef20c330f6789fdba361876f3c7a1985" }, - "source_manifest_sha256": "e60f1f78c9729700ef9606a6576163de0b553792e5e8f24591dce5f51597158c", + "source_manifest_sha256": "330fac72bad557ef4ae999298121c7d63ce237e23bb3184222c9bd6b54264687", "sources": [ { "files": { diff --git a/certificates/joint-dual-validation.json b/certificates/joint-dual-validation.json index a5ee9f485a..093050953c 100644 --- a/certificates/joint-dual-validation.json +++ b/certificates/joint-dual-validation.json @@ -226,7 +226,7 @@ } }, "bit_saving": "2382370177/50000000000000", - "certificate_sha256": "a1329d6c5e78cef5c7381d5e5d79c0a8842db7e569892af3b7e763b6c46d6f96", + "certificate_sha256": "cd820c5f75f2de6b8bf1068e7c9a58010d2cf50062954f7e19ebea97a258be6d", "kappa": "4764513337/100000000000000", "margins": 7, "producer_words_regenerated_and_matched": true, diff --git a/research/joint-dual/SOURCE.json b/research/joint-dual/SOURCE.json index e055d5d63d..f0931acdac 100644 --- a/research/joint-dual/SOURCE.json +++ b/research/joint-dual/SOURCE.json @@ -47,7 +47,7 @@ "scripts/experiments/binary_frame_replay.py": "1a572dbb33faba6695b3293768a7e61392d11cb4c2d5f708eedcd2cb95d0aff9", "scripts/experiments/joint_dual_compiler.py": "853d3fc4a740c5b74c23b3a6af5d4dc9b41fb38e9b55678539a7e0ee71947c13", "scripts/experiments/joint_dual_compose.py": "3554e957570e2d3f65c5bd7c945338c9e2fc5f3e79efa2b436a4dfc61899c394", - "scripts/experiments/joint_dual_reclaim_compiler.py": "9984aaccf880e4840402322d76678bfddb33ce7e494af78430a43429f51b85fd", + "scripts/experiments/joint_dual_reclaim_compiler.py": "edab206b83cfe3f7a08f1b605b182e354c87cc24e2f3ad81a95f7a083ff342fb", "scripts/experiments/pin_joint_dual_sources.py": "5d41535a73ad62fae7acb5365c5b7f40d7c99e52b6bc4266e44572018080acc5", "scripts/experiments/verify_joint_dual.py": "7a31bba1e9c0ded32ae285df2ca9bc91ef20c330f6789fdba361876f3c7a1985", "tests/test_joint_reclaim.py": "c4e2817bf6e699f462aa3c589ee45e24ab0dcad6bcdb6152ca2a1e16ac7bffeb" diff --git a/research/reclaim-order-performance/BENCHMARK.json b/research/reclaim-order-performance/BENCHMARK.json new file mode 100644 index 0000000000..ddb6138284 --- /dev/null +++ b/research/reclaim-order-performance/BENCHMARK.json @@ -0,0 +1,118 @@ +{ + "status": "PASS_IDENTICAL_RECLAIM_WORDS_AND_RECEIPTS", + "pairs": 3, + "platform": "macOS-26.6.1-arm64-arm-64bit-Mach-O", + "python": "3.14.7 (main, Aug 5 2026, 10:29:49) [Clang 21.0.0 (clang-2100.1.1.101)]", + "runs": [ + { + "pair": 0, + "variant": "reference", + "h": 23, + "seconds": 99.31884212512523, + "word_sha256": "c83396d1ea5427eed332c45931d59ed0c8ea5eae23d16e0ea909854d41796d1e", + "receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce" + }, + { + "pair": 0, + "variant": "filtered", + "h": 23, + "seconds": 30.900923082605004, + "word_sha256": "c83396d1ea5427eed332c45931d59ed0c8ea5eae23d16e0ea909854d41796d1e", + "receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce" + }, + { + "pair": 0, + "variant": "reference", + "h": 25, + "seconds": 151.46320916572586, + "word_sha256": "6f6dca829728cb01e6c425ada5878884b13bc6362e0ae2144347bde8a5852dbf", + "receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451" + }, + { + "pair": 0, + "variant": "filtered", + "h": 25, + "seconds": 51.81142037501559, + "word_sha256": "6f6dca829728cb01e6c425ada5878884b13bc6362e0ae2144347bde8a5852dbf", + "receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451" + }, + { + "pair": 1, + "variant": "filtered", + "h": 23, + "seconds": 28.245789624750614, + "word_sha256": "c83396d1ea5427eed332c45931d59ed0c8ea5eae23d16e0ea909854d41796d1e", + "receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce" + }, + { + "pair": 1, + "variant": "reference", + "h": 23, + "seconds": 72.87553708255291, + "word_sha256": "c83396d1ea5427eed332c45931d59ed0c8ea5eae23d16e0ea909854d41796d1e", + "receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce" + }, + { + "pair": 1, + "variant": "filtered", + "h": 25, + "seconds": 50.21983787510544, + "word_sha256": "6f6dca829728cb01e6c425ada5878884b13bc6362e0ae2144347bde8a5852dbf", + "receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451" + }, + { + "pair": 1, + "variant": "reference", + "h": 25, + "seconds": 135.0369677497074, + "word_sha256": "6f6dca829728cb01e6c425ada5878884b13bc6362e0ae2144347bde8a5852dbf", + "receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451" + }, + { + "pair": 2, + "variant": "reference", + "h": 23, + "seconds": 70.33631454175338, + "word_sha256": "c83396d1ea5427eed332c45931d59ed0c8ea5eae23d16e0ea909854d41796d1e", + "receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce" + }, + { + "pair": 2, + "variant": "filtered", + "h": 23, + "seconds": 31.932895791251212, + "word_sha256": "c83396d1ea5427eed332c45931d59ed0c8ea5eae23d16e0ea909854d41796d1e", + "receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce" + }, + { + "pair": 2, + "variant": "reference", + "h": 25, + "seconds": 127.1452476666309, + "word_sha256": "6f6dca829728cb01e6c425ada5878884b13bc6362e0ae2144347bde8a5852dbf", + "receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451" + }, + { + "pair": 2, + "variant": "filtered", + "h": 25, + "seconds": 46.23027937486768, + "word_sha256": "6f6dca829728cb01e6c425ada5878884b13bc6362e0ae2144347bde8a5852dbf", + "receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451" + } + ], + "summary": { + "23": { + "reference": 72.87553708255291, + "filtered": 30.900923082605004, + "speedup": 2.3583611689443864 + }, + "25": { + "reference": 135.0369677497074, + "filtered": 50.21983787510544, + "speedup": 2.6889168397066214 + } + }, + "source_manifest_sha256": "b74995273584bf723998c757d47cf5df94d2c8a6c8e599e64eddf337cad36d6d", + "scope": "Complete scalar compilation and both dirty orientations; not the full repository suite." +} diff --git a/research/reclaim-order-performance/CLAIM.json b/research/reclaim-order-performance/CLAIM.json new file mode 100644 index 0000000000..bb291b6ed0 --- /dev/null +++ b/research/reclaim-order-performance/CLAIM.json @@ -0,0 +1,47 @@ +{ + "track": "Verification engineering", + "seed": 85, + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "claimed_utc": "2026-10-13T04:14:46.842049+00:00", + "expected_finish_utc": "2026-10-13T05:15:00Z", + "candidates": [ + { + "task": "Exact logarithm or exponential acceleration", + "decision": "Excluded; PR667 and PR672 already cover these kernels." + }, + { + "task": "Ranked reclamation candidate ordering", + "decision": "Selected; PR154 identifies repeated sorting as a bottleneck but does not change it." + }, + { + "task": "R420 frame linear algebra", + "decision": "Deferred; close to PR367 frame-algebra work." + } + ], + "object": "scripts/experiments/joint_dual_reclaim_compiler.py acquire() with PR55 h=23 and h=25 inputs", + "hypothesis": "Filter retired slots by exact frame containment before sorting. Preserve descending current rank and slot-ID order on eligible slots. Measure complete compilation and compare every generated word field.", + "method": "Fresh before/after processes on identical frozen inputs; exact semantic and independent replay comparison; no result cache or reduced dirty-basis coverage.", + "expected_deliverable": "Focused compiler optimization with exact-output evidence, benchmark and required source-pin updates, or a recorded failed screen.", + "coordination": "No pinned issues. Open-PR refresh covered 508 PRs through 688. PR154 is credited as the prior bottleneck report.", + "contributor": "Ali Romman", + "assistance": "Substantial OpenAI Codex assistance.", + "pre_submission_overlap": { + "open_prs": 614, + "through_pr": 795, + "pr175_head": "f1081fabbfadaaaaf7292a40d428dbbb865ce920", + "pr779_head": "daa9b0e773b53f36d5b4c3f1c7524600e5714deb", + "finding": "PR175 maintains sorted rank buckets. Concurrent PR779 maintains exact eligibility indexes and reports larger speedups. PR175 is preserved in a historical source archive; the root compiler at the base still sorts all retired slots.", + "distinct_contribution": "Two-line default-compiler filter without a maintained index, update hook or adapter; exact-output evidence and complete affected integration checks. No priority or best-performance claim.", + "timing_scope": "Only the current base and two-line filter were benchmarked on this machine." + }, + "result": { + "status": "Verified two-line default-compiler option", + "median_speedup_h23": 2.3583611689443864, + "median_speedup_h25": 2.6889168397066214, + "unchanged_words_and_receipts": 12, + "required_groups_passed": 18, + "uninterrupted_full_run": false, + "new_kappa": false, + "publication": "PR link and exact head will be saved in the local continuation handoff." + } +} diff --git a/research/reclaim-order-performance/FOLLOWUP-REVIEW.json b/research/reclaim-order-performance/FOLLOWUP-REVIEW.json new file mode 100644 index 0000000000..555fe0c43c --- /dev/null +++ b/research/reclaim-order-performance/FOLLOWUP-REVIEW.json @@ -0,0 +1,65 @@ +{ + "date": "2026-10-14", + "status": "PASS_FOCUSED_RECLAIM_REGRESSION", + "reviewed_head": "b879e8472547bd820ce81b1b9c0463176fe5151c", + "upstream_commit": "418e40eb2572d930b58c1cf9b82b41c0fc7ee08d", + "source_audit": { + "upstream_commit": "418e40eb2572d930b58c1cf9b82b41c0fc7ee08d", + "original_base": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "reviewed_head": "b879e8472547bd820ce81b1b9c0463176fe5151c", + "current_main_compiler_equals_reference": true, + "all_pins_valid": true, + "changes": { + "research/joint-dual/SOURCE.json": [ + [ + "files", + "scripts/experiments/joint_dual_reclaim_compiler.py" + ] + ], + "certificates/joint-dual-kappa.json": [ + [ + "local_source_sha256", + "scripts/experiments/joint_dual_reclaim_compiler.py" + ], + [ + "source_manifest_sha256" + ] + ], + "certificates/joint-dual-validation.json": [ + [ + "certificate_sha256" + ] + ] + } + }, + "fresh_runs": { + "python": "3.14.7", + "platform": "macOS-26.6.1-arm64-arm-64bit-Mach-O", + "runs": [ + { + "h": 23, + "word_sha256": "c83396d1ea5427eed332c45931d59ed0c8ea5eae23d16e0ea909854d41796d1e", + "receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce", + "log_sha256": "75a64ea9169ea22f71f6242d297e09b7b1deedb205f4983d51d7210ce79067fc", + "all_dirty_columns_both_orientations": true, + "dirty_basis_vectors": 34230 + }, + { + "h": 25, + "word_sha256": "6f6dca829728cb01e6c425ada5878884b13bc6362e0ae2144347bde8a5852dbf", + "receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451", + "log_sha256": "f8c7ceb38fb5770f12285831a9bc426737f7139d113a7a22d8c7c13f7a01e1ac", + "all_dirty_columns_both_orientations": true, + "dirty_basis_vectors": 44938 + } + ] + }, + "retained_evidence": "VALIDATION.json and BENCHMARK.json at the reviewed head; no full-suite or timing rerun", + "scope": "Same finite words and compiler receipts. No new kappa or complete multiplication theorem.", + "scheduling": { + "requested_nice": 15, + "request_accepted": false, + "diagnostic": "nice: setpriority: Operation not permitted", + "execution": "One compilation at a time at normal priority; both completed." + } +} diff --git a/research/reclaim-order-performance/FOLLOWUP-REVIEW.md b/research/reclaim-order-performance/FOLLOWUP-REVIEW.md new file mode 100644 index 0000000000..87289ce8f4 --- /dev/null +++ b/research/reclaim-order-performance/FOLLOWUP-REVIEW.md @@ -0,0 +1,72 @@ +# Compiler and certificate follow-up review + +This review addresses the [PR #797 triage request](https://github.com/CrocSwap/integer-mult-bounds/pull/797#issuecomment-6160965282). +The two-line change preserves the complete compiler word. Fresh compilation +at both supported historical sizes passed on 2026-10-14. No code correction +was needed. The result remains a verifier improvement with no new kappa. + +## Exact inputs + +The reviewed PR head is `b879e8472547bd820ce81b1b9c0463176fe5151c`. +Its original base is `66849e1475c930fd7732b1a0067ffee7e1e95f60`. +Refreshed main is `418e40eb2572d930b58c1cf9b82b41c0fc7ee08d`. +The original compiler at that main commit is byte-identical to `reference.py`. +Every input in `SOURCES.json` still matches its digest. The PR can therefore +be reviewed against the same default compiler. This does not compare its +speed with the indexed adapters in [PR #175](https://github.com/CrocSwap/integer-mult-bounds/pull/175) or [PR #779](https://github.com/CrocSwap/integer-mult-bounds/pull/779). + +## Code and binding audit + +`contains` reads two immutable frame descriptions. Its sort key reads the +rank and slot ID. Before a dependent row is found, `ins` changes only the +local elimination basis. It does not change the retired set or any frame. +Both loops thus visit the same eligible slots in the same order. The first +clearing operation is followed by removal of that slot and immediate return. +No later predicate can observe the changed frame. The allocation path is +also unchanged. This proves equality of the emitted word by induction over +calls to `acquire`; the finite runs below are separate regression evidence. + +The three changed historical JSON files have exactly four changed fields: + +| File | Changed fields | +| --- | --- | +| `research/joint-dual/SOURCE.json` | The compiler digest in `files` | +| `certificates/joint-dual-kappa.json` | The compiler digest in `local_source_sha256` and `source_manifest_sha256` | +| `certificates/joint-dual-validation.json` | `certificate_sha256` | + +A recursive, type-sensitive JSON comparison found no other change. These +are source bindings. No numerical field, selected word or paid profile +changed. The historical [PR #626](https://github.com/CrocSwap/integer-mult-bounds/pull/626) / [PR #543](https://github.com/CrocSwap/integer-mult-bounds/pull/543) context belongs to the original +base; it is not the current selected frontier. + +## Fresh execution and retained checks + +Both sizes ran once, sequentially. The request for lower scheduling priority +failed with `nice: setpriority: Operation not permitted`, so the runs used +normal priority. This diagnostic is outside the compiler receipts. +The actual output paths were new files in the maintenance directory. +The interpreter was Python 3.14.7 on macOS arm64. To reproduce these runs, +use new output paths such as those below: + +```sh +python3 -B scripts/experiments/joint_dual_compiler.py --h 23 --output /tmp/reclaim-h23.json --word /tmp/reclaim-h23-word.json.gz +python3 -B scripts/experiments/joint_dual_compiler.py --h 25 --output /tmp/reclaim-h25.json --word /tmp/reclaim-h25-word.json.gz +``` + +Both commands exited 0. Their decompressed words match the committed +`certificates/joint-dual-word-23.json.gz` and `joint-dual-word-25.json.gz` +byte for byte. Their full receipts match the corresponding `compiled` +objects in `certificates/joint-dual-compiler.json`, with JSON types preserved. +The runs check 34,230 and 44,938 dirty basis vectors in both orientations, +all physical frame inclusions, and the admitted [PR #55](https://github.com/CrocSwap/integer-mult-bounds/pull/55) scalar graph. +`FOLLOWUP-REVIEW.json` records the exact output and log digests. + +The three alternating reference/candidate benchmark pairs and the 18-group +validation remain the prior evidence in `BENCHMARK.json` and +`VALIDATION.json`. The reference compiler, native CRT profiles, mutation +suite and complete selected replay were not run again in this follow-up. +No new timing ratio, remote CI result or complete theorem is claimed. + +Prepared by Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +This is an author-side follow-up, not independent human review or a merge +approval. diff --git a/research/reclaim-order-performance/README.md b/research/reclaim-order-performance/README.md new file mode 100644 index 0000000000..1e9bdd13f7 --- /dev/null +++ b/research/reclaim-order-performance/README.md @@ -0,0 +1,157 @@ +# Filter eligible slots before ranked reclamation + +**Verification engineering; no new kappa or physical word.** + +The joint compiler sorts every retired slot before it checks whether the slot +can enter the current frame. +The change first selects the eligible slots, then sorts them with the original +key: descending current frame rank, followed by slot ID. + +The production change is two lines in +`scripts/experiments/joint_dual_reclaim_compiler.py`. No new mode, cache, +data structure, dependency, or test-only interface is added. The original +compiler is retained byte for byte in `reference.py` for comparison. + +## Exact equivalence + +At the start of an `acquire` call, let `R` be the retired set, `P(s)` its frame +containment predicate, and `K(s)=(-rank(frame(s)),s)` its sort key. Filtering +`sort_K(R)` by `P` gives the same ordered list as `sort_K({s in R:P(s)})`. +Slot IDs make the sort keys unique. + +Frame containment and key evaluation read the current frames; neither changes +them. The old loop skips each ineligible slot before it calls `ins`. During +the eligible scan, `ins` changes only its local elimination basis. The first +dependent row, its clearing expression, all emitted XORs, and all frame raises +are therefore identical. Once clearing starts, both implementations return +without another eligibility decision. If no row is usable, both allocate the +same new slot. Induction over `acquire` calls proves the complete compiler word +is unchanged, not only its endpoint matrix or rank histogram. + +If `m` slots are retired and `e` are eligible, sorting changes from +`O(m log m)` to `O(e log e)`, with one scan of the retired set. The new code +can evaluate more containment predicates when the old loop found a reusable +slot early. No universal speedup is claimed. The benchmark measures the two +actual historical PR55 inputs at `h=23` and `h=25`. + +## Reproduce the benchmark + +Use Python 3.10+ and the standard library: + +```sh +python3 -B research/reclaim-order-performance/benchmark.py --pairs 3 --out /tmp/reclaim-order-benchmark.json +``` + +Use a new output path. Expected final line: + +```text +PASS_IDENTICAL_RECLAIM_WORDS_AND_RECEIPTS +``` + +Each pair uses fresh processes on identical source-pinned inputs. Pair order +alternates. Setup copies are outside the timing interval. Each timed command +does the complete scalar compilation, including all input and dirty columns +in both orientations. It also verifies the unchanged PR55 scalar graph. + +After every timed command, the harness compares the decompressed serialized +word with the accepted historical word. It compares the complete compiler +receipt too. After each pair, it compares both outputs directly. Compression +bytes are not used as mathematical equality. Timing includes process startup, +source admission and output serialization; it excludes the independent CRT +profiler and the complete repository suite. + +`BENCHMARK.json` records the final local measurements. `VALIDATION.json` records +the separate required checks and source hashes. There is no timing threshold +in the checks. The benchmark rejects disabled assertions, a nonpositive pair +count, changed pinned sources, and an output path that already exists. These +four rejection controls were tested. OS caches are not flushed, and the +development machine is not an isolated benchmarking host. These are verifier compilation timings, not +integer-multiplication runtimes or latest-frontier replay timings. + +Three fresh alternating-order pairs on macOS arm64 / Python 3.14.7 gave: + +| Axis | Reference median | Filtered median | Speedup | +|---|---:|---:|---:| +| h=23 | 72.876 s | 30.901 s | 2.36x | +| h=25 | 135.037 s | 50.220 s | 2.69x | + +All 12 timed runs produced identical physical words and compiler receipts. +An earlier single-pair screen also passed; it is kept in the local sprint +archive and is not mixed into these medians. +After timing, receipt comparison was tightened to preserve JSON types. +All 12 timed receipt hashes match the retained receipt bytes, which also +match the accepted typed JSON. Timed commands and compiler sources are unchanged. + +## Required mathematical checks + +The existing `make joint-dual-verify` target rebuilds both words and compares +their literal payloads. It independently checks every dirty basis column, +frame transition, actual CRT profile, exact recurrence, 47 strict inequalities +and seven margins. The existing mutation tests cover missing XORs, illegal +frames, omitted transitions, uncharged scatter, aliasing and disabled +assertions. They remain unchanged. + +All 18 groups required by `make verify` passed across the initial run and a +resumption. The initial run passed the first 14 groups, then stopped because +the historical positive-skip compiler did not find the installed Boost +headers. A retry refused its existing output directory. That generated +directory was preserved, and the four remaining groups passed with a fresh +output and `CPLUS_INCLUDE_PATH=/opt/homebrew/include`. The joint target +included all 16 existing controls. The failed attempts and successful +resumption are recorded in `VALIDATION.json`; no uninterrupted full-run pass +is claimed. No repository code was changed for the setup correction. + +Only the compiler source pin and the derived historical certificate bindings +need regeneration. All numerical fields, selected words and profiles remain +the same. This package does not change the accepted #626/#543 frontier or +`upstream/`. It does not discharge the inherited compiler, tape, precision or +analytic assumptions. + +## Sources and attribution + +Base: `66849e1475c930fd7732b1a0067ffee7e1e95f60`. +The accepted conditional kappa at that base remains +`51110230636731/31250000000000000`. + +The measured compiler is the historical PR55/PR57/PR58 ranked-reclamation +lineage. The PR55 graph is pinned at +`03e991aa79f9df1a935726213bb6a8631cd0d823`; the repository retains its exact +dependency manifests. `SOURCES.json` binds those manifests, both input words, +the wrapper, and the before/after compiler sources. + +Credit gupt1156 for the PR55 producer, eumemic for the PR57 compiler, and +Chafik Boukhalfa for ranked reclamation. +[PR154](https://github.com/CrocSwap/integer-mult-bounds/pull/154) +at `f571bcbd6e06618aeae0b8279da48060032dc74b` identified this sorting bottleneck +and explicitly left it unchanged. That report guided the scope; its code is +not a dependency. PR367/452/662/667/672 accelerate other exact checks. + +OS-random seed 85 selected the verification-engineering track. `CLAIM.json` +records the three candidate tasks and local scope. No pinned sprint issue was +available. This change adds measured evidence for the previously identified +bottleneck and does not duplicate the existing frame or arithmetic kernels. + +The final review covered 614 open PRs through PR795. It found +[PR779](https://github.com/CrocSwap/integer-mult-bounds/pull/779), Peter +Carpenter, at `daa9b0e773b53f36d5b4c3f1c7524600e5714deb`. Its separate adapter +maintains exact eligibility indexes and reports larger speedups. It also +credits Chafik Boukhalfa's earlier +[PR175](https://github.com/CrocSwap/integer-mult-bounds/pull/175), at +`f1081fabbfadaaaaf7292a40d428dbbb865ce920`, which maintains sorted rank +buckets. The review ledger records PR175's incorporation in a historical +source archive; the default compiler at this base still uses the full sort. + +This change is a smaller option for that default compiler. It adds no +maintained index, update hook or adapter. Its contribution is the two-line +change, exact-output benchmark and integration checks. It is not a claim of +priority or best performance. PR175 and PR779 were not benchmarked on this +machine; no direct timing comparison with them is claimed. Their source +archives and adapters are unchanged. + +Prepared by Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +Original source credits are retained. No independent human review is claimed. + +## Follow-up review + +The [2026-10-14 follow-up](FOLLOWUP-REVIEW.md) records the response to the +maintainer triage, the fresh checks and the remaining proof boundaries. diff --git a/research/reclaim-order-performance/SOURCES.json b/research/reclaim-order-performance/SOURCES.json new file mode 100644 index 0000000000..fbb4c7eaaf --- /dev/null +++ b/research/reclaim-order-performance/SOURCES.json @@ -0,0 +1,14 @@ +{ + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "reference_git_blob": "1eb8dea9fa13033478a5f83b536b7c291c9bc0c8", + "reference_sha256": "9984aaccf880e4840402322d76678bfddb33ce7e494af78430a43429f51b85fd", + "files": { + "scripts/experiments/joint_dual_reclaim_compiler.py": "edab206b83cfe3f7a08f1b605b182e354c87cc24e2f3ad81a95f7a083ff342fb", + "scripts/experiments/joint_dual_compiler.py": "853d3fc4a740c5b74c23b3a6af5d4dc9b41fb38e9b55678539a7e0ee71947c13", + "references/frame-compiler/pr48/SOURCE.json": "6ccc673f88d3650d75ed600b082fe2fc2866dd88a172d182a38c1d0cd27d24b3", + "references/frame-compiler/pr55/SOURCE.json": "1d39551202a579065355ea781101250920f5c2fc0de747445b433b30b7d1fd2e", + "certificates/joint-dual-compiler.json": "516c4d85158553dabd0a98216a064b2a7397957a9d5dd0df1d6e5aec53a4e805", + "certificates/joint-dual-word-23.json.gz": "634da1cb39634be15c6d4070132c6bdf4f5a927331cac3b4f13dc995dd799b6b", + "certificates/joint-dual-word-25.json.gz": "dd2223d7ee0b91c4445f5acd0b7cad945f56f4e16456b6818f53ddef64a0cb16" + } +} diff --git a/research/reclaim-order-performance/VALIDATION.json b/research/reclaim-order-performance/VALIDATION.json new file mode 100644 index 0000000000..afc363cc3b --- /dev/null +++ b/research/reclaim-order-performance/VALIDATION.json @@ -0,0 +1,168 @@ +{ + "status": "PASS_ALL_18_REQUIRED_GROUPS_WITH_RECORDED_SETUP_RETRIES", + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "verified_utc": "2026-10-13T05:49:05.620216+00:00", + "platform": "macOS-26.6.1-arm64-arm-64bit-Mach-O", + "python": "3.14.7", + "compiler": "Homebrew GCC 16.2.0", + "initial_attempt": { + "command": "make verify", + "exit_code": 2, + "wall_seconds": 3230.3441350460052, + "minimum_free_bytes": 5881888768, + "disk_floor_bytes": 3221225472, + "resource_stop": false, + "log_sha256": "0c91cd4f3835653787509999256ecd96aa60fb34352519a4b5538dab431758a7" + }, + "initial_passed_groups": [ + "verify-community", + "verify-producers", + "verify-partial-gauge", + "verify-three-stage-cover", + "verify-paired-cube", + "verify-recycled-bit", + "verify-entrance-banks", + "gen4-bank-verify", + "frontier626-verify", + "verify-certificates", + "verify-ternary", + "verify-research", + "verify-strips", + "verify-clones" + ], + "first_failure": "Positive-skip did not pass BOOST_INCLUDE to GCC; its Boost header was not found. No compiler source changed.", + "retry_attempt": { + "command": "make verify-positive verify-joint verify-pair verify-tests", + "exit_code": 2, + "wall_seconds": 9.030635125003755, + "minimum_free_bytes": 5869563904, + "disk_floor_bytes": 3221225472, + "resource_stop": false, + "CPLUS_INCLUDE_PATH": "/opt/homebrew/include", + "log_sha256": "2ce5aa16cc3c14f41690dd3c2c6260ffba4ab3025d24ebfdad07b21c84e9d13d" + }, + "retry_failure": "The failed generator left a directory that requires fresh creation. Its 23 MB output was moved to the local archive.", + "successful_resumption": { + "command": "make verify-positive verify-joint verify-pair verify-tests", + "exit_code": 0, + "wall_seconds": 541.3392170411535, + "minimum_free_bytes": 5756592128, + "disk_floor_bytes": 3221225472, + "resource_stop": false, + "CPLUS_INCLUDE_PATH": "/opt/homebrew/include", + "fresh_positive_output": true, + "log_sha256": "da5265cde2b08558ff71f55bf3280448adb6321ec04f0ae8dd430521ac6e36cc" + }, + "resumed_passed_groups": [ + "verify-positive", + "verify-joint", + "verify-pair", + "verify-tests" + ], + "uninterrupted_make_verify_pass": false, + "environment": { + "CXX": "/opt/homebrew/bin/g++-16", + "BOOST_INCLUDE": "/opt/homebrew/include", + "CPLUS_INCLUDE_PATH": "/opt/homebrew/include", + "OPENBLAS_NUM_THREADS": "1", + "OMP_NUM_THREADS": "1", + "MKL_NUM_THREADS": "1", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "joint_controls_passed": 16, + "benchmark": { + "pairs": 3, + "fresh_process_runs": 12, + "status": "PASS_IDENTICAL_RECLAIM_WORDS_AND_RECEIPTS", + "receipt_sha256": "a7da67a893be0ecd2ed66345dff37abde96b0b534d610e1b43cabf2207b8be0f" + }, + "benchmark_admission": { + "status": "PASS_BENCHMARK_ADMISSION_CONTROLS", + "controls": [ + { + "case": "optimized Python", + "exit_code": 1, + "diagnostic": "Run with assertions enabled" + }, + { + "case": "zero pairs", + "exit_code": 1, + "diagnostic": "Need at least one pair" + }, + { + "case": "existing output", + "exit_code": 1, + "diagnostic": "Output already exists" + }, + { + "case": "source drift", + "exit_code": 1, + "diagnostic": "Source changed: scripts/experiments/joint_dual_reclaim_compiler.py" + } + ], + "reference_exact_base_bytes": true, + "benchmark_sha256": "f1ba83e9de84b149b70a3afb215ddee39974dc21bc2d01651caf305986c4fc26", + "post_timing_change": "Only post-timing receipt comparison was tightened to preserve JSON types. All 12 timed receipts were revalidated from retained byte hashes. See typed_receipt_check." + }, + "typed_receipt_check": { + "status": "PASS_ALL_12_TYPED_RECEIPTS", + "rows": [ + { + "h": 23, + "retained_receipt_sha256": "0c39d1dcb82a4642d371a6a3dc49871cb43773cd0ec289f557838995e12175ce", + "all_six_timed_receipts_match_exact_bytes": true, + "typed_json_matches_accepted": true + }, + { + "h": 25, + "retained_receipt_sha256": "da2922d7b8b4f51d679f3fa5f5f052f41aff53e2bb283ffe6b50d00f6c1cc451", + "all_six_timed_receipts_match_exact_bytes": true, + "typed_json_matches_accepted": true + } + ] + }, + "scope_check": { + "status": "PASS_ONLY_BINDING_FIELDS_CHANGED", + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "changed_json_paths": { + "research/joint-dual/SOURCE.json": [ + [ + "files", + "scripts/experiments/joint_dual_reclaim_compiler.py" + ] + ], + "certificates/joint-dual-kappa.json": [ + [ + "local_source_sha256", + "scripts/experiments/joint_dual_reclaim_compiler.py" + ], + [ + "source_manifest_sha256" + ] + ], + "certificates/joint-dual-validation.json": [ + [ + "certificate_sha256" + ] + ] + }, + "mathematical_fields_unchanged": true, + "selected_and_upstream_unchanged": true, + "all_benchmark_source_pins_valid": true, + "benchmark_manifest_matches_measured_receipt": true + }, + "code_sha256": { + "benchmark.py": "f1ba83e9de84b149b70a3afb215ddee39974dc21bc2d01651caf305986c4fc26", + "reference.py": "9984aaccf880e4840402322d76678bfddb33ce7e494af78430a43429f51b85fd" + }, + "production_compiler_sha256": "edab206b83cfe3f7a08f1b605b182e354c87cc24e2f3ad81a95f7a083ff342fb", + "remote_ci": "Not claimed for this branch before submission.", + "proof_scope": "Exact finite output equivalence and required repository checks; no new kappa, all-size theorem, formal proof or independent human review.", + "overlap": { + "open_prs": 614, + "through_pr": 795, + "pr175_head": "f1081fabbfadaaaaf7292a40d428dbbb865ce920", + "pr779_head": "daa9b0e773b53f36d5b4c3f1c7524600e5714deb", + "priority_or_best_performance_claim": false + } +} diff --git a/research/reclaim-order-performance/benchmark.py b/research/reclaim-order-performance/benchmark.py new file mode 100644 index 0000000000..cd0f0967bf --- /dev/null +++ b/research/reclaim-order-performance/benchmark.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +"""Compare complete compilation with the pinned reference on the same inputs. + +Ali Romman, with substantial OpenAI Codex assistance. Apache-2.0. +""" +import argparse +import gzip +import hashlib +import json +from pathlib import Path +import platform +import shutil +import statistics +import subprocess +import sys +import tempfile +import time + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] +COMPILER = "scripts/experiments/joint_dual_reclaim_compiler.py" +WRAPPER = "scripts/experiments/joint_dual_compiler.py" + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--pairs", type=int, default=3) + parser.add_argument("--out", type=Path, required=True) + args = parser.parse_args() + require(not sys.flags.optimize, "Run with assertions enabled") + require(args.pairs >= 1, "Need at least one pair") + require(not args.out.exists(), "Output already exists") + pins = json.loads((HERE / "SOURCES.json").read_text()) + for name, digest in pins["files"].items(): + require(hashlib.sha256((ROOT / name).read_bytes()).hexdigest() == digest, + "Source changed: " + name) + require(hashlib.sha256((HERE / "reference.py").read_bytes()).hexdigest() + == pins["reference_sha256"], "Reference changed") + runs = [] + with tempfile.TemporaryDirectory(prefix="reclaim-order-") as temporary: + work = Path(temporary) + for variant in ("reference", "filtered"): + checkout = work / variant + (checkout / "scripts/experiments").mkdir(parents=True) + shutil.copyfile(ROOT / WRAPPER, checkout / WRAPPER) + source = HERE / "reference.py" if variant == "reference" else ROOT / COMPILER + shutil.copyfile(source, checkout / COMPILER) + for prior in (48, 55): + relative = Path("references/frame-compiler") / ("pr" + str(prior)) + shutil.copytree(ROOT / relative, checkout / relative) + for pair in range(args.pairs): + order = ("reference", "filtered") if pair % 2 == 0 else ("filtered", "reference") + for h in (23, 25): + outputs = {} + for variant in order: + tag = "%s-%d-%d" % (variant, pair, h) + receipt, word, log = [work / (tag + suffix) for suffix in (".json", ".json.gz", ".log")] + command = [sys.executable, "-B", WRAPPER, "--h", str(h), + "--output", str(receipt), "--word", str(word)] + start = time.perf_counter() + with log.open("w") as stream: + result = subprocess.run(command, cwd=work / variant, stdout=stream, + stderr=subprocess.STDOUT) + seconds = time.perf_counter() - start + require(result.returncode == 0, tag + " failed:\n" + log.read_text()[-4000:]) + raw = gzip.decompress(word.read_bytes()) + outputs[variant] = (raw, json.loads(receipt.read_text())) + expected = gzip.decompress((ROOT / ("certificates/joint-dual-word-%d.json.gz" % h)).read_bytes()) + require(raw == expected, tag + " differs from the accepted physical word") + recorded = json.loads((ROOT / "certificates/joint-dual-compiler.json").read_text()) + require(json.dumps(outputs[variant][1], sort_keys=True) + == json.dumps(recorded["axes"][str(h)]["compiled"], sort_keys=True), + tag + " differs from the accepted compiler receipt") + run = dict(pair=pair, variant=variant, h=h, seconds=seconds, + word_sha256=hashlib.sha256(raw).hexdigest(), + receipt_sha256=hashlib.sha256(receipt.read_bytes()).hexdigest()) + runs.append(run) + print(json.dumps(run), flush=True) + require(outputs["reference"] == outputs["filtered"], "Before/after output differs") + summary = {} + for h in (23, 25): + medians = {variant: statistics.median(r["seconds"] for r in runs + if r["h"] == h and r["variant"] == variant) + for variant in ("reference", "filtered")} + summary[str(h)] = dict(medians, speedup=medians["reference"] / medians["filtered"]) + result = dict(status="PASS_IDENTICAL_RECLAIM_WORDS_AND_RECEIPTS", pairs=args.pairs, + platform=platform.platform(), python=sys.version, runs=runs, summary=summary, + source_manifest_sha256=hashlib.sha256((HERE / "SOURCES.json").read_bytes()).hexdigest(), + scope="Complete scalar compilation and both dirty orientations; not the full repository suite.") + args.out.write_text(json.dumps(result, indent=2) + "\n") + print(result["status"], flush=True) + + +if __name__ == "__main__": + main() diff --git a/research/reclaim-order-performance/reference.py b/research/reclaim-order-performance/reference.py new file mode 100644 index 0000000000..1eb8dea9fa --- /dev/null +++ b/research/reclaim-order-performance/reference.py @@ -0,0 +1,240 @@ +"""Exact-envelope block synthesis on the pinned PR48 scalar graph. +Experimental finite compiler; no fixed-I+J profile or multiplication claim. +""" +# Derived from eumemic's PR57 compiler; original notices remain applicable. +# Descending-rank reclamation priority: Chafik Boukhalfa, with OpenAI Codex assistance. +import sys +if sys.flags.optimize: + raise ValueError('Assertions must remain enabled') +sys.dont_write_bytecode=True +from pathlib import Path +ROOT=Path(__file__).resolve().parents[2]/'references/frame-compiler/pr48' +from hashlib import sha256 +import json +manifest=json.loads((ROOT/'SOURCE.json').read_text()) +for name,digest in manifest['files'].items(): + assert sha256((ROOT/name).read_bytes()).hexdigest()==digest, 'Changed producer source: '+name +sys.path[:0]=[str(ROOT/'scripts'),str(ROOT/'research/copied-fixed')] +from changed_graph import graph +from collections import defaultdict,Counter,deque +import argparse,json,time,struct + +def independent(rows,vec): + for row in rows: + vec=min(vec,vec^row) + return bool(vec) +def basis(rows): + out=[] + for vec in rows: + for row in out:vec=min(vec,vec^row) + if vec:out.append(vec) + return out + +def build(h): + c=graph(h);groups={};owner={};signal={};blocks=[] + for x in sorted(c.active): + key=(c.core[x],c.union[x]) + if key not in groups: + groups[key]=len(blocks);blocks.append(dict(nodes=[],frame=key,inputs=set(),uses=[])) + g=groups[key];owner[x]=g;blocks[g]['nodes'].append(x) + signal[x]=(signal[c.args[x][0]]^signal[c.args[x][1]])if c.args[x]else 1<<(x-1) + for x in sorted(c.active): + for y in c.args[x]or(): + if owner[y]!=owner[x]:blocks[owner[x]]['inputs'].add(y) + uses=[];value_uses=defaultdict(list) + for g,b in enumerate(blocks): + b['inputs']=sorted(b['inputs']);b['source']=not c.args[b['nodes'][0]] + for y in b['inputs']: + k=len(uses);uses.append((y,g,None));value_uses[y].append(k);blocks[owner[y]]['uses'].append(k) + for target,x in c.outputs.items(): + k=len(uses);uses.append((x,owner[x],target));value_uses[x].append(k);blocks[owner[x]]['uses'].append(k) + for g,b in enumerate(blocks): + b['rank']=1 if b['source']else b['frame'][1].bit_count()-b['frame'][0].bit_count() + order=sorted(range(len(blocks)),key=lambda g:(blocks[g]['rank'],min(blocks[g]['nodes']))) + place={g:i for i,g in enumerate(order)} + def contained(a,b):return not(b[0]&~a[0])and not(a[1]&~b[1]) + for g,b in enumerate(blocks): + coeff={y:1<1 for b in blocks) + def new(g): + s=len(slots);slots.append(0);frames.append(g);hist[blocks[g]['rank']]+=1;events.append((s,-1,g));return s + def raise_(s,g): + old=frames[s];assert contains(blocks[old]['frame'],blocks[g]['frame']);hist[blocks[g]['rank']-blocks[old]['rank']]+=1;frames[s]=g;events.append((s,old,g)) + def xor(a,b,g): + assert a!=b;raise_(a,g);raise_(b,g);slots[a]^=slots[b];ops.append((a,b,g)) + def acquire(g,anchors): + if reclaim: + bb={} + def ins(s): + row=slots[s];expr=1<>s&1;e^=1<>i&1) + if j!=i: + # Synthesize swap as three XORs at the single common frame. + for a,z in ((i,j),(j,i),(i,j)):rr[a]^=rr[z];elim.append((a,z)) + for j in range(len(ins)): + if j!=i and rr[j]>>i&1:rr[j]^=rr[i];elim.append((j,i)) + assert rr==[1<>i&1:xor(s,value_slots[y],g) + assert slots[s]==signal[x];value_slots[x]=s + used=set() + for u in outuses: + x=uses[u][0];s=value_slots[x] + if x in used: + ss=acquire(g,list(value_slots.values()));xor(ss,s,g);s=ss + used.add(x);assert u not in assign;assign[u]=s + if step%5000==0:print('compile',h,step,len(slots),'reclaimed',stats['reclaimed'],'seconds',time.time()-t0,flush=True,file=sys.stderr) + output_slots=[];output_records=[];scatter=[0]*v;J=[] + for u,(x,g,target)in enumerate(uses): + if target is None:continue + s=assign[u];assert slots[s]==signal[x];raise_(s,g);output_slots.append(s) + common,triple=target;output_records.append((s,g,common,triple)) + targets=[i for i,t in enumerate(c.inputs)if common in t]if len(triple)==1 else[c.inputs.index(triple)] + for i in targets:scatter[i]^=slots[s];J.append((v+i,2*v+s)) + rank=blocks[g]['rank'] + if len(triple)==1:hist[rank]+=1;hist[h-rank]+=1 + else:hist[h-1-rank]+=1;hist[1]+=1 + assert len(set(output_slots))==len(output_slots) + for s in retired:hist[h-blocks[frames[s]]['rank']]+=1 + assert len(retired)+len(output_slots)==len(slots) + assert scatter==[1<>s&1;e^=1<