test: opt-in scaled_shear_n256 four-case shear diagnostic
- run_case: --diagnostic scaled_shear_n256 (requires --flow shear_wave; U256/U512/constant R256/projected R256, Re100, no early trace); N512 only via one of the two scaled diagnostics; scaled_n256 stays TG-only. - assess_shear_wave: scaled=True contract reusing92b8afescaled case/build/workload checks, shear diagnostic identity; signed rate bias, refined excess over each control; hash-pinnedde5b0ccN128 reference and descriptive N128->N256 signed trend; CLI --diagnostic/--reference-files. - tests: scaled contract, set mixing, trend/reference pin, runner options. - shear_wave.py and oracle.py unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
46100e1d53
commit
5fb95f5f4d
4 files changed
+263
-18
No files matched your search
@@ -4,8 +4,13 @@ Run from this directory with PYTHONPATH=<checkout>/src (same as test_oracle.py).
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import math
|
||||
import sys
|
||||
import tempfile
|
||||
from contextlib import redirect_stdout
|
||||
from unittest.mock import patch
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
@@ -361,7 +366,7 @@ class RunnerSampleTests(unittest.TestCase):
|
||||
self.assertEqual(row["leaf_cells"], N * N)
|
||||
|
||||
|
||||
def receipt(n, depth, explosion="constant"):
|
||||
def receipt(n, depth, explosion="constant", diagnostic=None):
|
||||
"""Synthetic receipt satisfying every contract field of the fixed four-case set."""
|
||||
import assess_projected_pairs as tg
|
||||
steps = run_case.sample_steps(n)[0]
|
||||
@@ -369,7 +374,7 @@ def receipt(n, depth, explosion="constant"):
|
||||
for row, step in zip(rows, steps):
|
||||
row.update(step=step, tstar=step * U / n,
|
||||
spurious_pressure_scaled_by_level=[row["spurious_pressure_scaled"]] * depth)
|
||||
cells = [n * n] if depth == 1 else [8704, 30720]
|
||||
cells = [n * n] if depth == 1 else [17 * n * n // 32, 15 * n * n // 8]
|
||||
hops = [16 * n * 2**level for level in range(depth)]
|
||||
builds = []
|
||||
for level in range(depth):
|
||||
@@ -406,7 +411,8 @@ def receipt(n, depth, explosion="constant"):
|
||||
active_collision_updates=sum(c * h for c, h in zip(cells, hops))),
|
||||
actual_build_sidecars=builds, rows=rows, completed=True,
|
||||
flow="shear_wave", mode=list(sw.MODE), polarization=sw.E.tolist(),
|
||||
angle_deg=sw.ANGLE_DEG, phase=sw.PHI, eps=sw.eps(n))
|
||||
angle_deg=sw.ANGLE_DEG, phase=sw.PHI, eps=sw.eps(n),
|
||||
**({"diagnostic": diagnostic} if diagnostic else {}))
|
||||
|
||||
|
||||
class ContractTests(unittest.TestCase):
|
||||
@@ -448,6 +454,89 @@ class ContractTests(unittest.TestCase):
|
||||
self.assertEqual(a(self.records, "wrong-revision")["status"], "INVALID_SET")
|
||||
|
||||
|
||||
def scaled_set(rate_error=0.0):
|
||||
d = run_case.SCALED_SHEAR
|
||||
out = [receipt(256, 1, diagnostic=d), receipt(512, 1, diagnostic=d),
|
||||
receipt(256, 2, diagnostic=d), receipt(256, 2, "projected_linear", diagnostic=d)]
|
||||
if rate_error:
|
||||
out[3]["rows"] = rows_for(256, rate_error=rate_error)
|
||||
for row, step in zip(out[3]["rows"], run_case.sample_steps(256)[0]):
|
||||
row.update(step=step, tstar=step * U / 256,
|
||||
spurious_pressure_scaled_by_level=[row["spurious_pressure_scaled"]] * 2)
|
||||
return out
|
||||
|
||||
|
||||
class ScaledContractTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
import assess_shear_wave
|
||||
self.mod = assess_shear_wave
|
||||
|
||||
def test_scaled_contract_and_signed_excess(self):
|
||||
result = self.mod.assess(scaled_set(1.5e-3), "r", scaled=True)
|
||||
self.assertTrue(result["contract_valid"], [k for k, v in result["checks"].items() if not v])
|
||||
self.assertEqual([c[1] for c in result["cases"]], [256, 512, 256, 256])
|
||||
projected = result["signed"]["projected_linear"]
|
||||
self.assertAlmostEqual(projected["signed_rate_bias"], 1.5e-3, delta=1e-9)
|
||||
self.assertAlmostEqual(projected["excess_over_uniform_root"]["signed_rate_bias"], 1.5e-3,
|
||||
delta=1e-9)
|
||||
self.assertIn("excess_over_uniform_fine", projected)
|
||||
|
||||
def test_scaled_and_default_sets_do_not_mix(self):
|
||||
n128 = [receipt(128, 1), receipt(256, 1), receipt(128, 2), receipt(128, 2, "projected_linear")]
|
||||
self.assertEqual(self.mod.assess(n128, "r", scaled=True)["status"], "INVALID_SET")
|
||||
self.assertEqual(self.mod.assess(scaled_set(), "r")["status"], "INVALID_SET")
|
||||
unlabeled = scaled_set()
|
||||
unlabeled[0].pop("diagnostic")
|
||||
self.assertEqual(self.mod.assess(unlabeled, "r", scaled=True)["status"], "INVALID_SET")
|
||||
tg_label = scaled_set()
|
||||
tg_label[2]["diagnostic"] = run_case.SCALED_DIAGNOSTIC
|
||||
self.assertEqual(self.mod.assess(tg_label, "r", scaled=True)["status"], "INVALID_SET")
|
||||
|
||||
def test_resolution_trend_and_reference_pin(self):
|
||||
reference = [receipt(128, 1), receipt(256, 1), receipt(128, 2),
|
||||
receipt(128, 2, "projected_linear")]
|
||||
new = self.mod.assess(scaled_set(1.5e-3), "r", scaled=True)
|
||||
trend = self.mod.resolution_trend(new, reference, "r")
|
||||
self.assertTrue(trend["valid"])
|
||||
change = trend["changes"]["projected_linear"]["signed_rate_bias"]
|
||||
self.assertAlmostEqual(change["signed_change"], 1.5e-3, delta=1e-9)
|
||||
self.assertIn("excess_over_uniform_fine.residual_l2", trend["changes"]["constant"])
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
paths = []
|
||||
for i, r in enumerate(reference):
|
||||
paths.append(Path(tmp) / f"{i}.json")
|
||||
paths[-1].write_text(json.dumps(r))
|
||||
with self.assertRaises(ValueError):
|
||||
self.mod.load_reference(paths)
|
||||
|
||||
def test_scaled_runner_options(self):
|
||||
repo = Path(__file__).resolve().parents[3]
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
base = ["run_case.py", "--repo", str(repo), "--expected-revision", "f" * 40,
|
||||
"--output", str(Path(tmp) / "case.json"), "--dry-run", "--re", "100"]
|
||||
shear = ["--flow", "shear_wave"]
|
||||
scaled = ["--diagnostic", run_case.SCALED_SHEAR]
|
||||
for extra, valid in (
|
||||
(["--n", "512", "--depth", "1"] + shear + scaled, True),
|
||||
(["--n", "256", "--depth", "2", "--explosion", "projected_linear"] + shear + scaled, True),
|
||||
(["--n", "512", "--depth", "1"] + shear, False),
|
||||
(["--n", "128", "--depth", "2"] + shear + scaled, False),
|
||||
(["--n", "512", "--depth", "1"] + scaled, False), # needs shear flow
|
||||
(["--n", "512", "--depth", "1", "--early-pressure", "--diagnostic",
|
||||
run_case.SCALED_DIAGNOSTIC] + shear, False), # mutually exclusive
|
||||
(["--n", "256", "--depth", "2", "--early-pressure"] + shear + scaled, False)):
|
||||
argv = base + extra
|
||||
with self.subTest(argv=argv), patch.object(sys, "argv", argv), \
|
||||
patch.object(run_case, "verify_source", return_value={}), \
|
||||
patch.object(run_case, "runtime_source", return_value={}), \
|
||||
redirect_stdout(io.StringIO()), patch("sys.stderr", io.StringIO()):
|
||||
if valid:
|
||||
self.assertEqual(run_case.main(), 0)
|
||||
else:
|
||||
with self.assertRaises(SystemExit):
|
||||
run_case.main()
|
||||
|
||||
|
||||
class DefaultPathTests(unittest.TestCase):
|
||||
def test_frozen_oracle_is_byte_identical(self):
|
||||
digest = hashlib.sha256((HERE / "oracle.py").read_bytes()).hexdigest()
|
||||
|
||||
Reference in new issue
Block a user