Files
CelerisLab/tests/validation/taylor_green/assess_shear_wave.py
T
ClaudeandClaude Opus 5.5 02bde0f751 test: depth-2 twin of the nested shear preset (twin_shear_n128)
Test-only opt-in. New shear_twin.py: same two L0->L1 boxes as
shear_nested, no L2; leaves [7936,33792], hops [2048,4096], work
154664960. Four fresh cases U128/U256/constant R128 d2/projected R128 d2;
physics is the unchanged depth-2/2N shear_wave.assess. run_case:
--diagnostic twin_shear_n128 with shear_twin.py+shear_nested.py pins, no
snapshot. assess_shear_wave: nested contract made preset-generic (PRESETS)
with nested behaviour unchanged. Labels: twin vs nested = effect of adding
this nested refinement (not abstract depth). shear_wave.py, shear_nested.py
and oracle.py byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 02:52:20 +00:00

337 lines
17 KiB
Python

"""Fixed four-case shear-wave contracts.
Default: N128 (U128, U256, constant R128, projected R128). Opt-in
--diagnostic scaled_shear_n256: N256 (U256, U512, constant R256, projected
R256), same physical rectangle, t* schedule, nu = U N / 100, eps(N), limits
and floors, plus a descriptive comparison with the hash-pinned N128 receipts.
Shared provenance, build, workload and sample-time checks are reused from
assess_projected_pairs (same cases, source pins and geometry); only the
Taylor-Green-specific checks are replaced by shear-wave metadata and physics.
"""
import argparse
import hashlib
import json
import math
from pathlib import Path
import assess_projected_pairs as tg
import shear_wave as sw
import shear_nested as nested
import shear_twin as twin
from run_case import (NESTED_SHEAR, SCALED_DIAGNOSTIC, SCALED_SHEAR, SHEAR_NESTED_SHA256,
SHEAR_TWIN_SHA256, SHEAR_WAVE_SHA256, TWIN_SHEAR, sample_steps)
# Audited de5b0cc N128 receipts (evidence commit cba6bca, shear-wave-de5b0cc zip).
REFERENCE_REVISION = "de5b0cc080794d0ce44d37f845aa8e8dbf8c2016"
REFERENCE_RECEIPTS = {
"uniform128": "d4a60fb806d04bfa8098a862cceba51e00b49979a6a250fef17a5fc8e3ea3255",
"uniform256": "e0b58e734724be5f82ee5d6df84395e3181b4e96e4246dd5a574ea23a8d12386",
"constant128": "c70d7cd14b1257a01cc49f8edfcc7685d430e5301e2f2d60ed426936f8b96c51",
"projected128": "980161458b9463af09a8e3178063fea0f4bbeb465329e1d3becdb0f224537b54",
}
ROLES = ("uniform_root", "uniform_fine", "constant", "projected_linear")
SHARED = ("complete_matrix", "no_extra_cases", "no_duplicate_cases", "finite_receipts",
"same_source_and_harness", "clean_a135252_numerical_source",
"same_recorded_runtime", "same_explicit_device", "same_early_sampling")
PER_CASE = ("complete_times", "scales", "actual_builds", "reference", "runtime_source",
"patch", "workload")
METADATA_ULPS = 4
def close_ulps(recorded, expected, ulps=METADATA_ULPS):
"""Portable check for recomputed float metadata only (e.g. eps = |k|^2).
The recorded value comes from another runtime/libm, so exact equality can
fail by one ULP (observed: 0.012047856934923534 Horsea vs ...532 here).
A few ULPs is far below any meaningful change; hashes, case identity and
scientific thresholds stay exact.
"""
return (isinstance(recorded, float) and math.isfinite(recorded)
and abs(recorded - expected) <= ulps * math.ulp(max(abs(recorded), abs(expected))))
def metadata_ok(record, n):
return (record.get("flow") == "shear_wave" and record.get("mode") == list(sw.MODE)
and record.get("polarization") == sw.E.tolist()
and record.get("angle_deg") == sw.ANGLE_DEG and record.get("phase") == sw.PHI
and close_ulps(record.get("eps"), sw.eps(n))
and record.get("numerics") == tg.NUMERICS
and record.get("initialization") == sw.INITIALIZATION
and record.get("limits") == sw.LIMITS
and record.get("early_pressure") == dict(enabled=False, rows=[],
sampled_max_pressure_l2=None)
and (record.get("source") or {}).get("shear_wave_sha256") == SHEAR_WAVE_SHA256)
def cases_for(scaled):
factor = 2 if scaled else 1
return tuple((re, n * factor, depth, scheme) for re, n, depth, scheme in tg.CASES)
def assess(records, expected_revision=None, *, scaled=False):
if not isinstance(records, list) or not all(isinstance(r, dict) for r in records):
raise ValueError("records must be a list of receipt objects")
# The scaled TG assessor supplies N256/512 cases, builds and workload; its
# TG-only diagnostic identity and early-sampling checks are not used here.
base_checks = tg.assess(records, expected_revision,
diagnostic=SCALED_DIAGNOSTIC if scaled else None)["checks"]
checks = {name: base_checks.get(name, False) for name in SHARED}
checks["shear_diagnostic_identity"] = all(
r.get("diagnostic") == (SCALED_SHEAR if scaled else None) for r in records)
cases = cases_for(scaled)
indexed = {}
for r in records:
indexed.setdefault(tuple(r.get(k) for k in ("re_L", "n", "depth", "explosion")), r)
for key in cases:
_, n, depth, scheme = key
label = f"{n}/{depth}/{scheme}"
for name in PER_CASE:
checks[f"{label} {name}"] = base_checks.get(f"{label} {name}", False)
checks[f"{label} shear_metadata"] = key in indexed and metadata_ok(indexed[key], n)
contract_valid = all(checks.values())
result = dict(checks=checks, contract_valid=contract_valid,
cases=[list(k) for k in cases], expected_revision=expected_revision,
diagnostic=SCALED_SHEAR if scaled else None,
scope="2D periodic Re100 oblique (2,1) shear wave; one phase and one "
"rectangle; no placement robustness or convergence order")
if not contract_valid:
result.update(status="INVALID_SET", passed=False)
return result
try:
physics = sw.assess(indexed[cases[0]], indexed[cases[1]],
[indexed[cases[2]], indexed[cases[3]]])
except (KeyError, ValueError) as error:
result.update(status="INVALID_SET", passed=False, reason=str(error))
return result
result.update(physics=physics, status=physics["status"],
passed=physics["status"] == "PASS")
try:
result["signed"] = signed_summary([indexed[k] for k in cases])
except (KeyError, TypeError, ValueError) as error:
result["signed_unavailable"] = str(error)
return result
CASE_AGNOSTIC = ("finite_receipts", "same_source_and_harness", "clean_a135252_numerical_source",
"same_recorded_runtime", "same_explicit_device", "same_early_sampling")
# Fixed multi-box presets sharing one contract; only geometry, controls, pins differ.
PRESETS = {
NESTED_SHEAR: dict(
module=nested, physics=nested.assess, snapshot=True,
pins={"shear_nested_sha256": SHEAR_NESTED_SHA256},
finest_control="uniform 4N (U512)",
scope="2D periodic Re100 oblique (2,1) shear wave; fixed three-level/two-region "
"placement; changes placement and refined volume as well as depth, so no "
"isolated-level cost or resolution trend"),
TWIN_SHEAR: dict(
module=twin, physics=sw.assess, snapshot=False,
pins={"shear_nested_sha256": SHEAR_NESTED_SHA256,
"shear_twin_sha256": SHEAR_TWIN_SHA256},
finest_control="uniform 2N (U256)",
scope="2D periodic Re100 oblique (2,1) shear wave; depth-2 twin of the nested "
"preset (same two L0->L1 boxes, no L2). Twin vs nested is the effect of adding "
"this nested refinement; it also changes finest spacing and refined volume, so it "
"does not isolate abstract depth"),
}
def _nested_case_ok(r, n, depth, diagnostic=NESTED_SHEAR):
"""Per-case identity of a fixed multi-box preset (scales, builds, patch, work, pins)."""
preset = PRESETS[diagnostic]
geometry = preset["module"]
runtime = r.get("runtime_source", {})
package = Path(runtime.get("checkout", "")) / "src/CelerisLab"
cells = [n * n] if depth == 1 else geometry.LEAVES
hops = [16 * n * 2**level for level in range(depth)]
work = r.get("workload", {})
snapshot = r.get("final_snapshot")
expected_patch = [] if depth == 1 else geometry.REFINEMENTS
return {
"complete_times": r.get("completed") is True and tg.at_steps(
r.get("rows", []), sample_steps(n)[0], n),
"scales": (r.get("U") == sw.U and tg.finite(r.get("viscosity"))
and abs(r["viscosity"] - sw.U * n / 100) < 1e-15
and r.get("tau_by_level") == [0.5 + 3 * sw.U * n / 100 * 2**l
for l in range(depth)]
and r.get("mach") == sw.U * math.sqrt(3)),
"actual_builds": tg.valid_builds(r, n, depth),
"reference": (r.get("numerical_revision") == tg.NUMERICAL_REVISION
and r.get("reference_harness") == tg.REFERENCE_HARNESS),
"runtime_source": bool(runtime.get("checkout")) and all(
runtime.get(k) == str(package / tail) for k, tail in
(("module", "__init__.py"), ("compiler", "cuda/compiler_v2.py"),
("kernel_root", "lbm/kernels"))),
"patch": json.dumps(r.get("refinements")) == json.dumps(expected_patch),
"workload": (work.get("active_cells_by_level") == cells and work.get("level_hops") == hops
and work.get("root_intervals") == 16 * n
and work.get("active_collision_updates_by_level") == [
c * h for c, h in zip(cells, hops)]
and work.get("active_collision_updates") == sum(
c * h for c, h in zip(cells, hops))),
"shear_metadata": metadata_ok(r, n),
"nested_module_pin": all((r.get("source") or {}).get(key) == pin
for key, pin in preset["pins"].items()),
# Optional, nested projected depth-3 only; bounded and hashed when present.
"snapshot": snapshot is None or (
preset["snapshot"] and depth == nested.DEPTH and r.get("explosion") == "projected_linear"
and snapshot.get("kept") is True and isinstance(snapshot.get("sha256"), str)
and len(snapshot["sha256"]) == 64
and 0 < snapshot.get("bytes", 0) <= nested.SNAPSHOT_MAX_BYTES
and snapshot.get("leaf_counts") == nested.LEAVES
and snapshot.get("step") == sample_steps(n)[0][-1]),
}
def assess_nested(records, expected_revision=None, diagnostic=NESTED_SHEAR):
"""Fixed four-case preset contract: nested_shear_n128 (U128, U512, constant/projected
R128 depth 3) or twin_shear_n128 (U128, U256, constant/projected R128 depth 2)."""
preset = PRESETS[diagnostic]
geometry = preset["module"]
if not isinstance(records, list) or not all(isinstance(r, dict) for r in records):
raise ValueError("records must be a list of receipt objects")
base_checks = tg.assess(records, expected_revision)["checks"]
checks = {name: base_checks.get(name, False) for name in CASE_AGNOSTIC}
indexed, duplicates = {}, []
for r in records:
key = tuple(r.get(k) for k in ("re_L", "n", "depth", "explosion"))
(duplicates.append(key) if key in indexed else indexed.__setitem__(key, r))
checks.update(complete_matrix=all(k in indexed for k in geometry.CASES),
no_extra_cases=set(indexed) <= set(geometry.CASES),
no_duplicate_cases=not duplicates,
shear_diagnostic_identity=all(r.get("diagnostic") == diagnostic
for r in records))
for key in geometry.CASES:
_, n, depth, scheme = key
label = f"{n}/{depth}/{scheme}"
case = _nested_case_ok(indexed[key], n, depth, diagnostic) if key in indexed else {}
for name in ("complete_times", "scales", "actual_builds", "reference", "runtime_source",
"patch", "workload", "shear_metadata", "nested_module_pin", "snapshot"):
checks[f"{label} {name}"] = bool(case.get(name, False))
contract_valid = all(checks.values())
result = dict(checks=checks, contract_valid=contract_valid, diagnostic=diagnostic,
cases=[list(k) for k in geometry.CASES], expected_revision=expected_revision,
finest_control=preset["finest_control"], scope=preset["scope"])
if not contract_valid:
result.update(status="INVALID_SET", passed=False)
return result
try:
cases = geometry.CASES
physics = preset["physics"](indexed[cases[0]], indexed[cases[1]],
[indexed[cases[2]], indexed[cases[3]]])
except (KeyError, ValueError) as error:
result.update(status="INVALID_SET", passed=False, reason=str(error))
return result
result.update(physics=physics, status=physics["status"], passed=physics["status"] == "PASS")
try:
# Role "uniform_fine" is the preset's finest control (4N nested, 2N twin).
result["signed"] = signed_summary([indexed[k] for k in geometry.CASES])
except (KeyError, TypeError, ValueError) as error:
result["signed_unavailable"] = str(error)
return result
def _signed(record):
"""Raw signed quantities of one valid record (None when the fit is unavailable)."""
s = sw.summarize(record)
bias = None if not s["rate_fit_valid"] else s["rate"] / s["exact_rate"] - 1
return dict(n=record["n"], depth=record["depth"], explosion=record["explosion"],
rate_fit_valid=s["rate_fit_valid"], signed_rate_bias=bias,
rate_tstar=s["rate_tstar"], exact_rate_tstar=s["exact_rate_tstar"],
interval_rate_errors=s["interval_rate_errors"],
residual_l2=s["residual_l2"], spurious_pressure_scaled=s["spurious_pressure_scaled"],
spurious_pressure_rms=s["spurious_pressure_rms"],
final_amplitude_error=record["rows"][-1]["amplitude_error"])
def signed_summary(records):
"""Signed bias per case and refined excess over each uniform control."""
rows = dict(zip(ROLES, (_signed(r) for r in records)))
def minus(a, b):
return None if a is None or b is None else a - b
for role in ("constant", "projected_linear"):
for control in ("uniform_root", "uniform_fine"):
rows[role][f"excess_over_{control}"] = {
key: minus(rows[role][key], rows[control][key])
for key in ("signed_rate_bias", "residual_l2", "spurious_pressure_rms")}
return rows
def load_reference(paths):
"""The four audited N128 receipts verbatim; never relabelled as fresh controls."""
blobs = [Path(path).read_bytes() for path in paths]
hashes = {hashlib.sha256(blob).hexdigest() for blob in blobs}
if len(blobs) != 4 or hashes != set(REFERENCE_RECEIPTS.values()):
raise ValueError("N128 receipt hashes differ from the audited de5b0cc evidence")
return [json.loads(blob) for blob in blobs]
def resolution_trend(new_result, reference, reference_revision=REFERENCE_REVISION):
"""Descriptive N128 -> N256 signed changes; never an acceptance gate or an order."""
old_result = assess(reference, reference_revision)
if "signed" not in old_result or "signed" not in new_result:
return dict(valid=False, reason="N128 reference or N256 set lacks a valid signed summary")
out = {}
for role in ROLES:
old, new = old_result["signed"][role], new_result["signed"][role]
out[role] = {}
for key in ("signed_rate_bias", "residual_l2", "spurious_pressure_rms",
*(f"excess_over_{c}" for c in ("uniform_root", "uniform_fine"))):
if key not in old:
continue
pairs = old[key].items() if isinstance(old[key], dict) else [(None, old[key])]
for sub, low in pairs:
high = new[key][sub] if sub else new[key]
ok = low is not None and high is not None
out[role][key if sub is None else f"{key}.{sub}"] = dict(
n128=low, n256=high, signed_change=high - low if ok else None,
n256_to_n128=high / low if ok and low else None)
return dict(valid=True, reference_revision=reference_revision,
reference_receipt_sha256=REFERENCE_RECEIPTS,
reference_status=old_result["status"], changes=out,
scope="same-placement two-resolution trend; not a convergence order, "
"placement robustness or redesign decision")
if __name__ == "__main__":
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("files", type=Path, nargs=4)
p.add_argument("--output", type=Path, required=True)
p.add_argument("--expected-revision", required=True)
p.add_argument("--diagnostic", choices=[SCALED_SHEAR, NESTED_SHEAR, TWIN_SHEAR])
p.add_argument("--reference-files", type=Path, nargs=4)
args = p.parse_args()
if args.output.exists():
p.error("Output already exists; choose a new path to retain prior evidence")
if args.diagnostic in PRESETS:
if args.reference_files:
p.error(f"{args.diagnostic} takes no reference files (no resolution trend)")
result = assess_nested([json.loads(path.read_text()) for path in args.files],
args.expected_revision, args.diagnostic)
text = json.dumps(result, indent=2, allow_nan=False) + "\n"
args.output.write_text(text)
print(text, end="")
raise SystemExit(0 if result["passed"] else 1)
if bool(args.diagnostic) != bool(args.reference_files):
p.error("--diagnostic scaled_shear_n256 requires --reference-files (N128 receipts)")
result = assess([json.loads(path.read_text()) for path in args.files], args.expected_revision,
scaled=bool(args.diagnostic))
if args.diagnostic:
try:
reference = load_reference(args.reference_files)
except ValueError as exc:
p.error(str(exc))
result["resolution_trend"] = resolution_trend(result, reference)
text = json.dumps(result, indent=2, allow_nan=False) + "\n"
args.output.write_text(text)
print(text, end="")
raise SystemExit(0 if result["passed"] else 1)