From e95cabb81aea8fc09bfa62e3188a93bcd6b79b7c Mon Sep 17 00:00:00 2001 From: Nick Petalas Date: Fri, 30 Oct 2026 18:21:48 +0000 Subject: [PATCH] perf(research): reuse native setup in complete history replay --- .../native-history-setup-cache/BENCHMARK.json | 189 ++++++++++++++++++ research/native-history-setup-cache/README.md | 133 ++++++++++++ .../native-history-setup-cache/SOURCES.json | 60 ++++++ research/native-history-setup-cache/TASK.json | 74 +++++++ .../native-history-setup-cache/VERIFY.json | 40 ++++ .../native-history-setup-cache/benchmark.py | 77 +++++++ research/native-history-setup-cache/run.py | 87 ++++++++ research/native-history-setup-cache/verify.py | 139 +++++++++++++ 8 files changed, 799 insertions(+) create mode 100644 research/native-history-setup-cache/BENCHMARK.json create mode 100644 research/native-history-setup-cache/README.md create mode 100644 research/native-history-setup-cache/SOURCES.json create mode 100644 research/native-history-setup-cache/TASK.json create mode 100644 research/native-history-setup-cache/VERIFY.json create mode 100644 research/native-history-setup-cache/benchmark.py create mode 100644 research/native-history-setup-cache/run.py create mode 100644 research/native-history-setup-cache/verify.py diff --git a/research/native-history-setup-cache/BENCHMARK.json b/research/native-history-setup-cache/BENCHMARK.json new file mode 100644 index 0000000000..af70696dc6 --- /dev/null +++ b/research/native-history-setup-cache/BENCHMARK.json @@ -0,0 +1,189 @@ +{ + "errors": 0, + "executable": "/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12", + "optimized": false, + "platform": "macOS-27.0.1-arm64-arm-64bit", + "python": "3.12.15 (main, Oct 14 2026, 00:55:37) [Clang 23.1.3 ]", + "samples": [ + { + "mode": "baseline", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 1.246776457875967, + "statistics": { + "cache": { + "currsize": 0, + "hits": 0, + "maxsize": 256, + "misses": 0 + }, + "mode": "baseline" + }, + "trial": 0 + }, + { + "mode": "cached", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 0.9610304171219468, + "statistics": { + "cache": { + "currsize": 58, + "hits": 158, + "maxsize": 256, + "misses": 58 + }, + "mode": "cached" + }, + "trial": 0 + }, + { + "mode": "baseline", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 1.281701625091955, + "statistics": { + "cache": { + "currsize": 0, + "hits": 0, + "maxsize": 256, + "misses": 0 + }, + "mode": "baseline" + }, + "trial": 1 + }, + { + "mode": "cached", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 1.0426137920003384, + "statistics": { + "cache": { + "currsize": 58, + "hits": 158, + "maxsize": 256, + "misses": 58 + }, + "mode": "cached" + }, + "trial": 1 + }, + { + "mode": "baseline", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 1.304742000065744, + "statistics": { + "cache": { + "currsize": 0, + "hits": 0, + "maxsize": 256, + "misses": 0 + }, + "mode": "baseline" + }, + "trial": 2 + }, + { + "mode": "cached", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 1.0262446249835193, + "statistics": { + "cache": { + "currsize": 58, + "hits": 158, + "maxsize": 256, + "misses": 58 + }, + "mode": "cached" + }, + "trial": 2 + }, + { + "mode": "baseline", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 1.2796051658224314, + "statistics": { + "cache": { + "currsize": 0, + "hits": 0, + "maxsize": 256, + "misses": 0 + }, + "mode": "baseline" + }, + "trial": 3 + }, + { + "mode": "cached", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 0.9767264169640839, + "statistics": { + "cache": { + "currsize": 58, + "hits": 158, + "maxsize": 256, + "misses": 58 + }, + "mode": "cached" + }, + "trial": 3 + }, + { + "mode": "baseline", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 1.2514010828454047, + "statistics": { + "cache": { + "currsize": 0, + "hits": 0, + "maxsize": 256, + "misses": 0 + }, + "mode": "baseline" + }, + "trial": 4 + }, + { + "mode": "cached", + "output_sha256": "31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d", + "returncode": 0, + "seconds": 0.966591291828081, + "statistics": { + "cache": { + "currsize": 58, + "hits": 158, + "maxsize": 256, + "misses": 58 + }, + "mode": "cached" + }, + "trial": 4 + } + ], + "schema": "native-history-setup-benchmark/v1", + "source_sha256": { + "SOURCES.json": "a8665633efa339149c3e1b936b0770a8f1de1a914538ed79c85e01f3f8a2e6c7", + "benchmark.py": "97bc142fe47b2911dae2f7695cae9cbb106bf3235a09dd9d66cea9ded6238f78", + "run.py": "78a2b5038354facf910908af2d9a533d759d444b79edd5ffce1122916cf77606" + }, + "summary": { + "baseline": { + "maximum_seconds": 1.304742000065744, + "median_seconds": 1.2796051658224314, + "minimum_seconds": 1.246776457875967 + }, + "cached": { + "maximum_seconds": 1.0426137920003384, + "median_seconds": 0.9767264169640839, + "minimum_seconds": 0.9610304171219468 + }, + "fraction_less_time": 0.23669703510745088 + }, + "timed_region": "fresh interpreter, authentication and complete direct caller" +} diff --git a/research/native-history-setup-cache/README.md b/research/native-history-setup-cache/README.md new file mode 100644 index 0000000000..7e4320639a --- /dev/null +++ b/research/native-history-setup-cache/README.md @@ -0,0 +1,133 @@ +# Reuse native-map setup in the complete full-history caller + +The complete PR5447 direct-history caller takes **23.67% less wall time** with +an invocation-owned cache of exact native-map construction. Five alternating +fresh-process runs per side give medians of 1.279605 s and 0.976726 s. Baseline +range is 1.246776 to 1.304742 s; cached range is 0.961030 to 1.042614 s. All ten +complete executions succeed with identical scientific stdout bytes. +[BENCHMARK.json](BENCHMARK.json) is generated by the retained harness and binds +its source hashes. + +Claim type: scoped implementation-preservation proof, finite conformance and +local performance evidence. This is a newly posed runtime question on the +unchanged predecessor caller. No new kernel theorem, kappa or supplier admission +is claimed. + +## Change and preservation argument + +The complete caller initializes three separate native registries for its +provider-backward, source-backward and source-forward cases. They request 216 +native constructions but use only 58 distinct binary maps. The adapter reuses +158 exact results. It neither caches history rows nor shares native registries. + +The pinned `monomial.native(columns)` function is deterministic. It reads nine +binary map columns and returns one immutable 1,024-byte signed permutation. +The key snapshots all nine columns, so equal keys have equal outputs. Each miss +calls the original function. Each hit returns the bytes that function would +construct. Mutating an input list cannot change a stored tuple key; callers +cannot mutate returned bytes. Exceptions are not cached. Capacity is 256 entries, +and the cache is cleared on every invocation exit, including exceptional exits. + +Every `intern` call therefore receives the original bytes in the original order. +Operator IDs, products, scalar rows, histories and final output remain the same. +This implication does not depend on a small-width sample. The adapter +authenticates all seven external inputs before installing reuse and runs the +original `verify_kernel.py` unchanged. Its three complete cases, literal +permutation checks, equations, frozen-result comparison and four original +controls still execute. + +## Evidence and measurement + +The new verifier compares original and cached construction on 300 distinct +invertible nine-dimensional unitriangular maps. It checks full-key reuse, +256-entry capacity, eviction, mutable lists, restored contents and independent +cache owners. Six malformed inputs reject at the boundary. Two singular-map +executions retain the original exception and leave no cached value. + +Both complete callers must agree byte for byte and match every field of the +predecessor's frozen result. Their stdout SHA256 is +`31116d29f77eaa5732cc76eb0c716c808f063c195e2aa886f4993ea33f51d29d`. +The cached path must record exactly 58 misses and 158 hits. The verifier +authenticates the generated measurement against its implementation, harness and +manifest, and recomputes the measurement summary. Timing itself is not a CI gate. + +Local measurement uses CPython 3.12.15, standard library, macOS arm64 and 18 +logical CPUs. Initial load averages were 2.86, 2.41 and 1.74; other work could +run concurrently. Alternating sides exposes both to that load. Their observed +ranges are disjoint. Each subprocess includes startup, authentication and the +entire direct caller inside the timed region. Baseline uses the same adapter +without installing reuse. Neither side skips checks or uses a cross-process +cache. All ten return codes are zero. Profiler runs are excluded from samples. + +The initial complete profile identifies 216 `monomial.native` calls; a separate +cached profile has 58. Fraction arithmetic remains a larger cost after reuse. +The repeated setup is only part of the complete caller. This explains a bounded +end-to-end saving and does not predict a twofold speedup. The first improvement +is packaged without further arithmetic optimization. + +## Reproduce + +From the repository root on the recorded machine: + +```sh +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -W error -B research/native-history-setup-cache/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -W error -O -B research/native-history-setup-cache/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/research_package.py --package research/native-history-setup-cache +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/check_research_commit.py --package research/native-history-setup-cache --check-source-history +``` + +Direct status is `PASS_NATIVE_HISTORY_SETUP_CACHE`: 300 maps, eight rejecting +executions, two complete callers, 58 misses and 158 hits. Registered status is +`PASS_REGISTERED_RESEARCH_PACKAGE`. Other machines may substitute CPython 3.12. + +Run the complete cached caller or generate a new measurement outside the checkout: + +```sh +python3.12 -W error -B research/native-history-setup-cache/run.py --mode cached +python3.12 -W error -B research/native-history-setup-cache/benchmark.py --output /absolute/scratch/new-benchmark.json +``` + +The harness refuses to overwrite its output. For a diagnostic profile, insert +`-m cProfile -o /absolute/scratch/profile.pstats` before `run.py`. Profiler timings +are not comparable to the retained uninstrumented samples. + +## Limits and code discipline + +Timing is local to this complete direct caller and environment. Other PR5447 +commands, selected cold replay, physical native admission, compiler closure, +ownership, precision/tape and analytic recovery remain unrun or inherited. +Independent human and formal proof-kernel review are unclaimed. No predecessor +source, credit line or selected-frontier file changes. + +The adapter accepts nine integer columns in `[0,512)`; invertibility retains the +original check. Retained payload is at most 256 times 1,024 bytes plus bounded +keys and bookkeeping. Python allocation is a managed-runtime deviation from +fixed allocation. Finite loops are bounded by 300 maps, 36 triangular positions, +six malformed inputs and two singular executions. Benchmarking runs ten children +with 120-second timeouts. New functions fit within 60 lines. Standard import +loading and `runpy` load only the pinned modules, a bounded dynamic-loading +deviation with no generated code. Explicit exceptions remain active under `-O`. +Warning-strict normal and optimized replay supply the interpreted diagnostics. + +## Open next questions + +1. Can exact rational row arithmetic reduce the remaining complete caller cost? + Start with a new cached profile and preserve all scientific output. No such + implementation or measurement is supplied here. +2. Should a future native compiler expose an invocation-owned operator factory? + First specify its exact key, lifetime and source invalidation on one consumer. + Shared API design and other caller replays remain open. + +Structured questions are in [TASK.json](TASK.json). + +## Credit and sources + +The adapter, preservation argument, conformance checks and measurements were +produced by Nick Petalas. Memoization is classical; priority for it is unclaimed. + +Credit THU New Media Research Center / thu-nmrc PR5447 for the native algebra, +complete caller, kernel proofs and controls; Mark / Matarener PR5427 for event +and ownership semantics; Dillon Amburgey PR5402, Cao Yifan PR4610, Cinna Davis, +zxv, David Ganz, Jacob Alan Sussman, Ali Romman and the retained +native/query/compiler lineage. Their original files and credit are unchanged. +Exact main-branch pins and hashes are in [SOURCES.json](SOURCES.json). Apache-2.0. diff --git a/research/native-history-setup-cache/SOURCES.json b/research/native-history-setup-cache/SOURCES.json new file mode 100644 index 0000000000..dcce11da6b --- /dev/null +++ b/research/native-history-setup-cache/SOURCES.json @@ -0,0 +1,60 @@ +{ + "schema_version": 1, + "base_commit": "2485805a6d47f36ea83ddde6327d453ac82d44dc", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "d59b5035e7b4cbaa9d688a1d32dd0d6eb79c466a", + "sha256": "9b8d0eea95b3bf0dfcb7938a732a6439b87a2685dec2a5ab9e525b3b34debbfa" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "3404fbdd5e7529a0674eef26114b5071e4586cec", + "sha256": "ead6cdc9d0af6d58e8a49744d8ec8c7c15e13d2ba93c276c434bcf9b51b93a81" + }, + { + "path": "research/kappa-round3-warp-20261022/ACTUAL-WORD.json.gz", + "usage": "input", + "git_blob": "46d929df83817b85a5387bcdb9745e0627d6366e", + "sha256": "7679daa4ec6a40f56fc7f0202379a6f454310e94945aba4f48beaaaafb838d05" + }, + { + "path": "research/native-rank8-helper-provider/WORD.json.gz", + "usage": "input", + "git_blob": "f3111b47e89496da8ca0ee45b2e4b258c0634d8e", + "sha256": "7dc356001ed597ad6fc9fd3e0bc6ff7e3ec3a580a579a956827aa17fccfdd2dc" + }, + { + "path": "research/physical-zqy-scalar-span/KERNEL-RESULT.json", + "usage": "input", + "git_blob": "f57f4accbc0d334db480d2b31db4185420654567", + "sha256": "0d56847d579aa195c6ee462a631a5ccdbfbb128dccc26503dbdc481963b6cab8" + }, + { + "path": "research/physical-zqy-scalar-span/KERNEL.json", + "usage": "input", + "git_blob": "cd699656f9192ccf6d462a45617b5e56d6799dfb", + "sha256": "ad403cdd98975ae9a8033afff5a86f96d055e44c5be19c1f171387cf26cd3b81" + }, + { + "path": "research/physical-zqy-scalar-span/monomial.py", + "usage": "input", + "git_blob": "1a4483808478808784fe6b3e0b88cdc959752a66", + "sha256": "87cdb1688b841891eccefdcaebe67b97a6c86b7af676bbbb667d1d5ee5d45d3e" + }, + { + "path": "research/physical-zqy-scalar-span/native.py", + "usage": "input", + "git_blob": "0784aa84b7bd49454e57530be3ded522313a91f8", + "sha256": "1bad1ffe747c3977d1a6bc1cfa9faa4127e38cbf49d7fcf4ae8060fbc7f67d4e" + }, + { + "path": "research/physical-zqy-scalar-span/verify_kernel.py", + "usage": "input", + "git_blob": "036d1f199f03a2a3e2792e33d28c6e5a7e4d26c2", + "sha256": "29af4fd8536aa10d8ed0459087744fd077113073ec7e3a682fde970593fd857d" + } + ] +} diff --git a/research/native-history-setup-cache/TASK.json b/research/native-history-setup-cache/TASK.json new file mode 100644 index 0000000000..e4f19a1437 --- /dev/null +++ b/research/native-history-setup-cache/TASK.json @@ -0,0 +1,74 @@ +{ + "schema_version": 1, + "task_id": "replay-runtime", + "priority_revision": 8, + "base_commit": "2485805a6d47f36ea83ddde6327d453ac82d44dc", + "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_selected_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Resolve the current selected review, separate complex/ordinary BIT/admitted BIT/outer budgets, and compare the card against live handoffs before starting. Historical ceilings require exact source/model equivalence.", + "scope": "Source-binding orientation only; not a scientific replay or all-size proof. Materialize selected inputs if this checkout is sparse." + }, + "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": "Reuse exact immutable native-map construction across the three complete PR5447 direct-history caller cases.", + "scope_change_reason": "The replay-runtime card is specialized to one profiled complete caller and a bounded content-keyed setup cache.", + "bottleneck_link": "Reduces complete scientific replay time while preserving every original source binding, history equation, literal operator check and rejection control.", + "budget_minutes": 60, + "stop_rule": "Ship the first complete-path runtime improvement with byte-identical scientific output; do not optimize another kernel.", + "outcome": "completed", + "evidence": "BENCHMARK.json and normal/optimized verify.py; five alternating fresh-process pairs, zero errors, identical complete output bytes.", + "author": "Nick Petalas", + "ai_assistance": "Independent human and formal proof-kernel review are unclaimed.", + "open_questions": [ + { + "question": "Can the unchanged rational row arithmetic dominate less of the complete caller?", + "why_it_matters": "After setup reuse, Fraction arithmetic remains the largest measured caller cost.", + "first_step": "Profile one complete cached execution and propose one exact arithmetic change with the same scientific output.", + "blocked_by": "No such implementation or measurement is supplied here." + }, + { + "question": "Should a future native compiler expose an invocation-owned reusable operator factory?", + "why_it_matters": "The isolated adapter proves the scoped reuse without changing frozen predecessor packages.", + "first_step": "Specify a factory lifetime, exact column key and source invalidation contract for one current consumer.", + "blocked_by": "Shared API design, other consumers and their complete replay obligations are outside scope." + } + ], + "claim_url": "https://github.com/CrocSwap/integer-mult-bounds/discussions/1166#discussioncomment-19299733", + "claim_type": "scoped implementation-preservation proof with finite conformance and local performance evidence", + "environment": { + "python": "CPython 3.12.15", + "dependencies": "standard library only", + "platform": "macOS arm64" + } +} diff --git a/research/native-history-setup-cache/VERIFY.json b/research/native-history-setup-cache/VERIFY.json new file mode 100644 index 0000000000..ecff7be35a --- /dev/null +++ b/research/native-history-setup-cache/VERIFY.json @@ -0,0 +1,40 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/kappa-round3-warp-20261022/ACTUAL-WORD.json.gz", + "research/native-rank8-helper-provider/WORD.json.gz", + "research/physical-zqy-scalar-span/KERNEL-RESULT.json", + "research/physical-zqy-scalar-span/KERNEL.json", + "research/physical-zqy-scalar-span/monomial.py", + "research/physical-zqy-scalar-span/native.py", + "research/physical-zqy-scalar-span/verify_kernel.py" + ], + "commands": [ + { + "argv": [ + "{python}", + "-W", + "error", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Complete baseline/cached caller byte equality, 300 exact maps, cache capacity, mutation, lifetime, eight rejection executions and generated benchmark source bindings." + }, + { + "argv": [ + "{python}", + "-W", + "error", + "-O", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "All same checks with optimization enabled; proof checks use explicit exceptions." + } + ] +} diff --git a/research/native-history-setup-cache/benchmark.py b/research/native-history-setup-cache/benchmark.py new file mode 100644 index 0000000000..d5833bcd49 --- /dev/null +++ b/research/native-history-setup-cache/benchmark.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""Time five alternating fresh-process pairs of the complete caller.""" + +import argparse +from hashlib import sha256 +import json +from pathlib import Path +import platform +import statistics +import subprocess +import sys +from time import perf_counter + +HERE = Path(__file__).resolve().parent + + +def need(condition, message): + if not condition: + raise ValueError(message) + + +def measure(root, optimized): + samples, expected = [], None + flags = ["-W", "error", "-B"] + (["-O"] if optimized else []) + for trial in range(5): + for mode in ("baseline", "cached"): + command = [sys.executable, *flags, str(HERE / "run.py"), + "--root", str(root), "--mode", mode] + start = perf_counter() + result = subprocess.run(command, capture_output=True, timeout=120, check=False) + elapsed = perf_counter() - start + need(result.returncode == 0, result.stderr.decode()) + output = json.loads(result.stdout) + need(output["status"] == "PASS_EXACT_ALL_WIDTH_FULL_HISTORY_Y_BLINDNESS", + "complete caller status") + digest = sha256(result.stdout).hexdigest() + if expected is None: + expected = digest + need(digest == expected, "complete scientific output bytes differ") + samples.append({"trial": trial, "mode": mode, "seconds": elapsed, + "output_sha256": digest, "returncode": result.returncode, + "statistics": json.loads(result.stderr)}) + return samples + + +def summarize(samples): + result = {} + for mode in ("baseline", "cached"): + values = [row["seconds"] for row in samples if row["mode"] == mode] + result[mode] = {"median_seconds": statistics.median(values), + "minimum_seconds": min(values), "maximum_seconds": max(values)} + result["fraction_less_time"] = (1 - result["cached"]["median_seconds"] + / result["baseline"]["median_seconds"]) + return result + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output", required=True, type=Path) + parser.add_argument("--root", type=Path, default=HERE.parents[1]) + parser.add_argument("--optimized", action="store_true") + args = parser.parse_args() + samples = measure(args.root.resolve(), args.optimized) + bound = {name: sha256((HERE / name).read_bytes()).hexdigest() + for name in ("run.py", "benchmark.py", "SOURCES.json")} + report = {"schema": "native-history-setup-benchmark/v1", "samples": samples, + "summary": summarize(samples), "errors": 0, "source_sha256": bound, + "python": sys.version, "executable": sys.executable, + "platform": platform.platform(), "optimized": args.optimized, + "timed_region": "fresh interpreter, authentication and complete direct caller"} + with args.output.open("x") as handle: + handle.write(json.dumps(report, indent=2, sort_keys=True) + "\n") + print(json.dumps(report["summary"], sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/research/native-history-setup-cache/run.py b/research/native-history-setup-cache/run.py new file mode 100644 index 0000000000..7ccf3d0653 --- /dev/null +++ b/research/native-history-setup-cache/run.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +"""Run the unchanged direct-history caller with bounded native setup reuse.""" + +import argparse +from functools import lru_cache +from hashlib import sha256 +import importlib.util +import json +from pathlib import Path +import runpy +import sys + +HERE = Path(__file__).resolve().parent +SOURCE = Path("research/physical-zqy-scalar-span") +CAPACITY = 256 + + +def need(condition, message): + if not condition: + raise ValueError(message) + + +def authenticate(root): + manifest = json.loads((HERE / "SOURCES.json").read_text()) + for item in manifest["files"]: + if item["usage"] == "input": + raw = (root / item["path"]).read_bytes() + need(sha256(raw).hexdigest() == item["sha256"], + "source bytes " + item["path"]) + + +def cached_native(original): + """Snapshot all nine columns; retain at most 256 immutable results.""" + @lru_cache(maxsize=CAPACITY) + def compile_columns(columns): + result = original(columns) + need(type(result) is bytes and len(result) == 1024, + "one immutable 512-column monomial") + return result + + def native(columns): + key = tuple(columns) + need(len(key) == 9 and all(type(v) is int and 0 <= v < 512 for v in key), + "nine binary native-map columns") + return compile_columns(key) + + return native, compile_columns + + +def execute(root, mode): + authenticate(root) + need("native" not in sys.modules and "monomial" not in sys.modules, + "a fresh caller process") + runtime = root / SOURCE + spec = importlib.util.spec_from_file_location("monomial", runtime / "monomial.py") + need(spec is not None and spec.loader is not None, "monomial module loader") + module = importlib.util.module_from_spec(spec) + sys.modules["monomial"] = module + spec.loader.exec_module(module) + original = module.native + wrapped, cache = cached_native(original) + if mode == "cached": + module.native = wrapped + saved_argv, saved_path = sys.argv, list(sys.path) + try: + sys.path.insert(0, str(runtime)) + sys.argv = [str(runtime / "verify_kernel.py")] + runpy.run_path(str(runtime / "verify_kernel.py"), run_name="__main__") + info = cache.cache_info() + print(json.dumps({"mode": mode, "cache": info._asdict()}, sort_keys=True), + file=sys.stderr) + finally: + module.native = original + cache.cache_clear() + sys.argv, sys.path = saved_argv, saved_path + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--mode", choices=("baseline", "cached"), default="cached") + parser.add_argument("--root", type=Path, default=HERE.parents[1]) + args = parser.parse_args() + execute(args.root.resolve(), args.mode) + + +if __name__ == "__main__": + main() diff --git a/research/native-history-setup-cache/verify.py b/research/native-history-setup-cache/verify.py new file mode 100644 index 0000000000..42533ddcc0 --- /dev/null +++ b/research/native-history-setup-cache/verify.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +"""Check cache semantics and both complete unchanged caller executions.""" + +from hashlib import sha256 +import importlib.util +import json +from pathlib import Path +import subprocess +import sys + +from run import CAPACITY, HERE, SOURCE, authenticate, cached_native, need +from benchmark import summarize + + +def source_module(root): + spec = importlib.util.spec_from_file_location("oracle_monomial", root / SOURCE / "monomial.py") + need(spec is not None and spec.loader is not None, "oracle loader") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def unitriangular(mask): + columns = [1 << j for j in range(9)] + bit = 0 + for j in range(9): + for i in range(j): + if mask >> bit & 1: + columns[j] ^= 1 << i + bit += 1 + return columns + + +def conformance(module): + wrapped, cache = cached_native(module.native) + for mask in range(300): + columns = unitriangular(mask) + need(wrapped(columns) == module.native(columns), "literal monomial bytes") + need(wrapped(list(columns)) == wrapped(tuple(columns)), "content-key reuse") + info = cache.cache_info() + need(info.misses == 300 and info.hits == 600 and info.currsize == CAPACITY, + "bounded capacity and complete-key hits") + before = info.misses + need(wrapped(unitriangular(0)) == module.native(unitriangular(0)), "evicted value") + need(cache.cache_info().misses == before + 1, "oldest value was evicted") + cache.cache_clear() + columns = unitriangular(0) + first = wrapped(columns) + columns[1] ^= 1 + changed = wrapped(columns) + need(first != changed, "mutated columns cannot reuse the old key") + columns[1] ^= 1 + need(wrapped(columns) == first and cache.cache_info().hits == 1, + "restored contents reuse their own immutable result") + other, other_cache = cached_native(module.native) + need(other_cache.cache_info().currsize == 0, "new invocation owns an empty cache") + need(other(unitriangular(0)) == first and other_cache.cache_info().misses == 1, + "no state leaks between cache owners") + cache.cache_clear() + other_cache.cache_clear() + return 300 + + +def rejection_controls(module): + wrapped, cache = cached_native(module.native) + invalid = [[], [0] * 8, [0] * 10, [-1] + [0] * 8, + [512] + [0] * 8, [False] + [0] * 8] + for columns in invalid: + try: + wrapped(columns) + except ValueError: + pass + else: + raise ValueError("invalid native-map boundary accepted") + for _ in range(2): + try: + wrapped([0] * 9) + except ValueError as error: + need(str(error) == "singular native map", "same singular-map failure") + else: + raise ValueError("singular map accepted") + need(cache.cache_info().misses == 2 and cache.cache_info().currsize == 0, + "failed constructions are never cached") + return len(invalid) + 2 + + +def complete_callers(root): + outputs, reports = [], [] + for mode in ("baseline", "cached"): + command = [sys.executable, "-W", "error", "-B"] + if sys.flags.optimize: + command.append("-O") + command += [str(HERE / "run.py"), "--mode", mode, "--root", str(root)] + result = subprocess.run(command, capture_output=True, timeout=120, check=False) + need(result.returncode == 0, result.stderr.decode()) + outputs.append(result.stdout) + reports.append(json.loads(result.stderr)) + need(outputs[0] == outputs[1], "all complete scientific output bytes agree") + actual = json.loads(outputs[1]) + expected = json.loads((root / SOURCE / "KERNEL-RESULT.json").read_bytes()) + need(actual == expected, "every source scientific result field is retained") + need(reports[1]["cache"] == {"currsize": 58, "hits": 158, + "maxsize": CAPACITY, "misses": 58}, + "all 216 construction requests consumed on the actual complete path") + return sha256(outputs[0]).hexdigest(), reports[1]["cache"] + + +def benchmark_binding(digest): + receipt = json.loads((HERE / "BENCHMARK.json").read_text()) + for name, source_digest in receipt["source_sha256"].items(): + need(sha256((HERE / name).read_bytes()).hexdigest() == source_digest, + "generated measurement source binding " + name) + need(receipt["errors"] == 0 and len(receipt["samples"]) == 10, + "five alternating successful complete pairs") + for trial in range(5): + pair = receipt["samples"][2 * trial:2 * trial + 2] + need([row["mode"] for row in pair] == ["baseline", "cached"], "alternating order") + need(all(row["trial"] == trial and row["returncode"] == 0 for row in pair), + "successful trial ownership") + need({row["output_sha256"] for row in receipt["samples"]} == {digest}, + "all measured complete scientific outputs agree") + need(receipt["summary"] == summarize(receipt["samples"]), "measurement summary") + + +def main(): + root = HERE.parents[1] + authenticate(root) + module = source_module(root) + matrices = conformance(module) + rejections = rejection_controls(module) + digest, stats = complete_callers(root) + benchmark_binding(digest) + print(json.dumps({"status": "PASS_NATIVE_HISTORY_SETUP_CACHE", "maps": matrices, + "rejection_executions": rejections, "complete_callers": 2, + "complete_output_sha256": digest, "cache": stats}, sort_keys=True)) + + +if __name__ == "__main__": + main()