300 lines
17 KiB
Python
300 lines
17 KiB
Python
"""New-source four-case repeat of 11901a7; frozen oracle and gates are unchanged."""
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import math
|
|
from pathlib import Path
|
|
|
|
from assess import BASELINE_FACTOR, FLOORS
|
|
from oracle import LIMITS, TIMES, U, rectangles
|
|
from run_case import (INITIALIZATION, sample_steps, NUMERICAL_REVISION, SOURCE_SHA256,
|
|
BUILD_CAPTURE_SHA256, REFERENCE_HARNESS, SCALED_DIAGNOSTIC)
|
|
|
|
# Host-generated snapshots of a135252 at the frozen local configurations.
|
|
# These describe expected inputs; actual sidecars are captured before cleanup.
|
|
BUILD_SOURCES = {
|
|
128: "803177416b7599ab89cc5afd35cf4a28a673b2f4bb8e8a6a1abc0b6d77610873",
|
|
256: "17ec5e60f87b840d3d13b8778bc8a3aecf485469c5a061af46c5cc19b73396cf",
|
|
512: "4e85e38098858ec95c137d1b1e96846a58d9cf3cc242b349a3ad7c8b8e3ce0aa",
|
|
}
|
|
CASES = ((100, 128, 1, "constant"), (100, 256, 1, "constant"),
|
|
(100, 128, 2, "constant"), (100, 128, 2, "projected_linear"))
|
|
REFERENCE_REVISION = "2cf9853952e52f59bea63cf5c1d3a1cd76e53eed"
|
|
# Audited 2cf9853 scalar receipts, archived at evidence commit 90849a55cad4a0da9b72747da7bfe6eb75962a44.
|
|
REFERENCE_RECEIPTS = {
|
|
"uniform128": "724efafc267eaa59dcc59e8d4c16177b67f6c6a08fd2732a481833237bb19cee",
|
|
"uniform256": "3c312a99ebf747a135674dd481b77455a3d2c9a406ca388f30524b37dad9bbe9",
|
|
"constant128": "2ee28efd1e81b2e28b7902b6c4f95bb2c1ea4e5f0ec484638fa5ae83dca34bba",
|
|
"projected128": "ee67b1d4d90a048c0d3d1a16447c6eab3d89c94d151f791306e373f96dd8b963",
|
|
}
|
|
NUMERICS = dict(lattice_model="D2Q9", collision="SRT", store_precision="FP32",
|
|
ddf_shifting=True, streaming="double_buffer", les_enabled=False,
|
|
boundary="periodic", block_shape=[8, 8],
|
|
sample_phase="postcollision G at root synchronization")
|
|
|
|
|
|
def finite(value):
|
|
return isinstance(value, (int, float)) and not isinstance(value, bool) and math.isfinite(value)
|
|
|
|
|
|
def finite_tree(value):
|
|
if isinstance(value, dict):
|
|
return all(finite_tree(v) for v in value.values())
|
|
if isinstance(value, list):
|
|
return all(finite_tree(v) for v in value)
|
|
return not isinstance(value, float) or math.isfinite(value)
|
|
|
|
|
|
def at_steps(rows, steps, n):
|
|
return len(rows) == len(steps) and all(
|
|
type(r.get("step")) is int and r["step"] == step and finite(r.get("tstar"))
|
|
and abs(r["tstar"] - step * U / n) <= 3e-17
|
|
for r, step in zip(rows, steps)
|
|
)
|
|
|
|
|
|
def maximum(rows, metric):
|
|
values = [r.get(metric) for r in rows]
|
|
return max(values) if values and all(finite(v) and v >= 0 for v in values) else None
|
|
|
|
|
|
def valid_builds(record, n, depth):
|
|
builds = record.get("actual_build_sidecars", [])
|
|
if not isinstance(builds, list) or len(builds) != depth:
|
|
return False
|
|
for level, build in enumerate(builds):
|
|
if not isinstance(build, dict):
|
|
return False
|
|
size = n * 2**level
|
|
cfg = build.get("config", {})
|
|
expected = dict(nx=10, ny=10, nz=1, lattice_model="D2Q9", collision="SRT",
|
|
store_precision="FP32", streaming="double_buffer", ddf_shifting=True,
|
|
les_enabled=False, velocity=0.0, viscosity=U*size/100, rho=1.0,
|
|
omega=1/(.5+3*U*size/100), threads_per_block=256)
|
|
ptx = build.get("ptx_sha256", "")
|
|
if (build.get("source_sha256") != BUILD_SOURCES[size]
|
|
or build.get("arch") != "sm_70" or build.get("flags") != ["--use_fast_math"]
|
|
or build.get("n_objects") != 0 or not isinstance(cfg, dict)
|
|
or any(cfg.get(k) != value for k, value in expected.items())
|
|
or not isinstance(ptx, str) or len(ptx) != 64
|
|
or any(c not in "0123456789abcdef" for c in ptx)):
|
|
return False
|
|
return True
|
|
|
|
|
|
def assess(records, expected_revision=None, *, diagnostic=None):
|
|
if diagnostic not in (None, SCALED_DIAGNOSTIC):
|
|
raise ValueError("Unknown diagnostic")
|
|
base_n = 256 if diagnostic else 128
|
|
cases = tuple((re, n * base_n // 128, depth, scheme) for re, n, depth, scheme in CASES)
|
|
indexed, duplicates = {}, []
|
|
for record in records:
|
|
key = tuple(record.get(k) for k in ("re_L", "n", "depth", "explosion"))
|
|
if key in indexed:
|
|
duplicates.append(str(key))
|
|
else:
|
|
indexed[key] = record
|
|
missing = [str(k) for k in cases if k not in indexed]
|
|
checks = dict(complete_matrix=not missing, no_extra_cases=set(indexed) <= set(cases),
|
|
no_duplicate_cases=not duplicates, finite_receipts=finite_tree(records))
|
|
if diagnostic or any("diagnostic" in r for r in records):
|
|
checks["diagnostic_identity"] = all(r.get("diagnostic") == diagnostic for r in records)
|
|
sources = [r.get("source", {}) for r in records]
|
|
checks["same_source_and_harness"] = bool(sources) and len({
|
|
json.dumps(s, sort_keys=True) for s in sources}) == 1
|
|
checks["clean_a135252_numerical_source"] = bool(sources) and all(
|
|
s.get("dirty") is False and s.get("source_tree_sha256") == SOURCE_SHA256
|
|
and bool(s.get("revision")) and bool(s.get("harness_sha256"))
|
|
and s.get("build_capture_sha256") == BUILD_CAPTURE_SHA256
|
|
and (expected_revision is None or s.get("revision") == expected_revision) for s in sources)
|
|
runtimes = [r.get("runtime_identity") for r in records]
|
|
checks["same_recorded_runtime"] = bool(runtimes) and all(
|
|
isinstance(v, dict) and all(v.get(k) for k in
|
|
("device", "nvcc_path", "nvcc_version", "python", "numpy", "pycuda"))
|
|
and isinstance(v["device"], dict) and v["device"].get("capability") == [7, 0]
|
|
and all(v["device"].get(k) for k in ("name", "pci_bus_id", "driver", "runtime"))
|
|
for v in runtimes
|
|
) and len({json.dumps(v, sort_keys=True) for v in runtimes}) == 1
|
|
devices = [r.get("cuda_visible_devices") for r in records]
|
|
checks["same_explicit_device"] = bool(devices) and all(
|
|
isinstance(d, str) and d and "," not in d and d != "-1" for d in devices
|
|
) and len(set(devices)) == 1
|
|
enabled = [r.get("early_pressure", {}).get("enabled") for r in records]
|
|
checks["same_early_sampling"] = bool(enabled) and all(type(v) is bool for v in enabled) and len(set(enabled)) == 1
|
|
if diagnostic:
|
|
checks["diagnostic_early_sampling"] = all(v is True for v in enabled)
|
|
shared_valid = all(checks.values())
|
|
complete, case_valid, early = {}, {}, []
|
|
for key in cases:
|
|
if key not in indexed:
|
|
continue
|
|
r = indexed[key]
|
|
_, n, depth, scheme = key
|
|
label = f"{n}/{depth}/{scheme}"
|
|
rows = r.get("rows", [])
|
|
main_steps, early_steps = sample_steps(n, True)
|
|
complete[key] = r.get("completed") is True and at_steps(rows, main_steps, n)
|
|
checks[label + " complete_times"] = complete[key]
|
|
checks[label + " scales"] = (
|
|
r.get("U") == U and finite(r.get("viscosity"))
|
|
and abs(r["viscosity"] - U * n / 100) < 1e-15
|
|
and r.get("tau_by_level") == [0.5 + 3 * U * n / 100 * 2**l for l in range(depth)]
|
|
and r.get("mach") == U * math.sqrt(3)
|
|
)
|
|
checks[label + " actual_builds"] = valid_builds(r, n, depth)
|
|
checks[label + " reference"] = (r.get("numerical_revision") == NUMERICAL_REVISION
|
|
and r.get("reference_harness") == REFERENCE_HARNESS)
|
|
checks[label + " numerics"] = r.get("numerics") == NUMERICS and r.get("initialization") == INITIALIZATION
|
|
runtime = r.get("runtime_source", {})
|
|
package = Path(runtime.get("checkout", "")) / "src/CelerisLab"
|
|
checks[label + " 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")))
|
|
expected_patch = [] if depth == 1 else rectangles(n, depth)
|
|
checks[label + " patch"] = json.dumps(r.get("refinements")) == json.dumps(expected_patch)
|
|
cells = [n*n] if depth == 1 else [17*n*n//32, 15*n*n//8]
|
|
hops = [16*n * 2**l for l in range(depth)]
|
|
work = r.get("workload", {})
|
|
checks[label + " 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))
|
|
)
|
|
checks[label + " absolute"] = bool(rows) and all(
|
|
finite(row.get(metric)) and 0 <= row[metric] <= limit
|
|
for row in rows for metric, limit in LIMITS.items())
|
|
trace = r.get("early_pressure", {})
|
|
trace_rows = trace.get("rows", [])
|
|
peak = maximum(trace_rows, "pressure_l2")
|
|
trace_complete = at_steps(trace_rows, early_steps, n) and peak is not None
|
|
checks[label + " early_trace"] = (
|
|
trace_complete and trace.get("sampled_max_pressure_l2") == peak
|
|
and len(rows) >= 2 and all(trace_rows[i]["pressure_l2"] == rows[j].get("pressure_l2")
|
|
for i, j in ((0, 0), (-1, 1)))
|
|
if trace.get("enabled") is True else
|
|
trace.get("enabled") is False and trace_rows == [] and trace.get("sampled_max_pressure_l2") is None
|
|
)
|
|
early.append(dict(n=n, depth=depth, explosion=scheme, enabled=trace.get("enabled"),
|
|
samples=len(trace_rows), complete=trace_complete,
|
|
sampled_max_pressure_l2=peak))
|
|
case_valid[key] = all(value for name, value in checks.items() if name.startswith(label + " "))
|
|
|
|
def worst(key, metric):
|
|
return maximum(indexed[key]["rows"][1:], metric) if complete.get(key) else None
|
|
|
|
comparisons, scheme_results = [], {}
|
|
for scheme in ("constant", "projected_linear"):
|
|
key = (100, base_n, 2, scheme)
|
|
for metric, floor in FLOORS.items():
|
|
amr, coarse, fine = (worst(k, metric) for k in (key, cases[0], cases[1]))
|
|
budget = None if coarse is None else max(BASELINE_FACTOR * coarse, floor)
|
|
budget = budget if finite(budget) else None
|
|
ratio = None if amr is None or fine is None else amr / max(fine, 1e-30)
|
|
passed = amr is not None and budget is not None and amr <= budget
|
|
checks[f"baseline {scheme}/{metric}"] = passed
|
|
comparisons.append(dict(explosion=scheme, metric=metric, amr=amr,
|
|
baseline_budget=budget, passed=passed,
|
|
**{f"uniform{base_n}": coarse, f"uniform{2*base_n}": fine,
|
|
f"amr_to_uniform{2*base_n}": ratio if finite(ratio) else None}))
|
|
if diagnostic:
|
|
comparisons[-1]["floor_dominates"] = None if coarse is None else floor >= BASELINE_FACTOR * coarse
|
|
baseline_passed = all(checks[f"baseline {scheme}/{metric}"] for metric in FLOORS)
|
|
valid = shared_valid and all(case_valid.get(k, False) for k in (cases[0], cases[1], key))
|
|
scheme_results[scheme] = dict(passed=valid and baseline_passed,
|
|
valid_case_and_controls=valid, baseline_passed=baseline_passed)
|
|
return dict(passed=all(checks.values()), missing=missing, duplicates=duplicates, checks=checks,
|
|
comparisons=comparisons, scheme_results=scheme_results, early_pressure=early,
|
|
numerical_revision=NUMERICAL_REVISION, source_tree_sha256=SOURCE_SHA256,
|
|
reference_harness=REFERENCE_HARNESS, expected_revision=expected_revision,
|
|
floors=FLOORS, baseline_factor=BASELINE_FACTOR,
|
|
main_statistic="maximum of four post-initial samples at t*=.12,.24,.36,.48",
|
|
early_statistic="sampled pressure maximum only, t*=k*.001875, k=0..64; not an all-step or continuous maximum",
|
|
finest_control=f"uniform{2*base_n} and AMR/ uniform{2*base_n} ratios are descriptive, not acceptance gates",
|
|
scope="2D periodic Re100 smooth-decay diagnostic; no new algorithm, convergence-order or general AMR qualification")
|
|
|
|
|
|
def load_reference(paths):
|
|
"""Use the four audited historical files verbatim, never relabel them fresh controls."""
|
|
blobs = [path.read_bytes() for path in paths]
|
|
hashes = [hashlib.sha256(blob).hexdigest() for blob in blobs]
|
|
if len(hashes) != 4 or set(hashes) != set(REFERENCE_RECEIPTS.values()):
|
|
raise ValueError("Historical N128 receipt hashes differ from the audited 2cf9853 evidence")
|
|
return [json.loads(blob) for blob in blobs]
|
|
|
|
|
|
def resolution_trend(records, reference, expected_revision):
|
|
"""Signed changes are descriptive; they never replace the frozen acceptance budgets."""
|
|
old = assess(reference, REFERENCE_REVISION)
|
|
new = assess(records, expected_revision, diagnostic=SCALED_DIAGNOSTIC)
|
|
# Numerical screen failures still have useful raw errors; only malformed inputs block trends.
|
|
valid = all(v for result in (old, new) for k, v in result["checks"].items()
|
|
if not k.startswith("baseline ") and not k.endswith(" absolute"))
|
|
valid = valid and all(maximum(r["rows"], m) is not None for r in reference + records for m in LIMITS)
|
|
oracle = reference[0]["source"]["harness_sha256"].get("oracle.py") if valid else None
|
|
valid = valid and bool(oracle) and records[0]["source"]["harness_sha256"].get("oracle.py") == oracle
|
|
if not valid:
|
|
return dict(valid=False, per_time=[], worst_post_initial=[], uniform256_bridge=[])
|
|
key = lambda r: (r["re_L"], r["n"], r["depth"], r["explosion"])
|
|
before, after = {key(r): r for r in reference}, {key(r): r for r in records}
|
|
|
|
def change(role, metric, low, high, **extra):
|
|
ratio = high / low if low else None
|
|
percent = 100*(ratio-1) if ratio is not None else None
|
|
return dict(role=role, metric=metric, n128_campaign_error=low, n256_campaign_error=high,
|
|
signed_change=high-low, new_to_old=ratio if finite(ratio) else None,
|
|
ratio_unavailable_reason=None if finite(ratio) else "zero historical error" if not low else "overflow",
|
|
change_percent=percent if finite(percent) else None, **extra)
|
|
|
|
per_time, worst, bridge = [], [], []
|
|
for old_key, role in zip(CASES, ("uniform_root", "uniform_fine", "constant", "projected_linear")):
|
|
re, n, depth, scheme = old_key
|
|
low, high = before[old_key], after[(re, 2*n, depth, scheme)]
|
|
for metric in LIMITS:
|
|
per_time.extend(change(role, metric, a[metric], b[metric], tstar=a["tstar"])
|
|
for a, b in zip(low["rows"], high["rows"]))
|
|
worst.append(change(role, metric, maximum(low["rows"][1:], metric),
|
|
maximum(high["rows"][1:], metric)))
|
|
for a, b in zip(before[CASES[1]]["rows"], after[CASES[1]]["rows"]):
|
|
bridge.extend(dict(metric=m, tstar=a["tstar"], historical=a[m], fresh=b[m], signed_change=b[m]-a[m])
|
|
for m in LIMITS)
|
|
low, high = before[CASES[1]], after[CASES[1]]
|
|
bridge_identity = dict(main_rows_identical=low["rows"] == high["rows"],
|
|
early_pressure_rows_identical=low["early_pressure"]["rows"] == high["early_pressure"]["rows"])
|
|
same_runtime = reference[0]["runtime_identity"] == records[0]["runtime_identity"]
|
|
return dict(valid=True, reference_revision=REFERENCE_REVISION, reference_receipt_sha256=REFERENCE_RECEIPTS,
|
|
reference_scheme_results=old["scheme_results"], per_time=per_time, worst_post_initial=worst,
|
|
uniform256_bridge=bridge, uniform256_bridge_identity=bridge_identity,
|
|
same_recorded_runtime=same_runtime,
|
|
trend_interpretation_ready=all(bridge_identity.values()) and same_runtime,
|
|
scope="Historical same-production/oracle reference versus fresh controls; same-placement two-resolution trend only, not convergence order or phase robustness")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
p = argparse.ArgumentParser(description=__doc__)
|
|
p.add_argument("files", type=Path, nargs="+")
|
|
p.add_argument("--output", type=Path, required=True)
|
|
p.add_argument("--expected-revision", required=True)
|
|
p.add_argument("--diagnostic", choices=[SCALED_DIAGNOSTIC])
|
|
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 bool(args.diagnostic) != bool(args.reference_files):
|
|
p.error("--diagnostic scaled_n256 requires --reference-files; references are diagnostic-only")
|
|
records = [json.loads(path.read_text()) for path in args.files]
|
|
result = assess(records, args.expected_revision, diagnostic=args.diagnostic)
|
|
if args.diagnostic:
|
|
try:
|
|
reference = load_reference(args.reference_files)
|
|
except ValueError as exc:
|
|
p.error(str(exc))
|
|
result["diagnostic"] = args.diagnostic
|
|
result["resolution_trend"] = resolution_trend(records, reference, args.expected_revision)
|
|
result["checks"]["valid_historical_reference_and_trend"] = result["resolution_trend"]["valid"]
|
|
result["passed"] = all(result["checks"].values())
|
|
args.output.write_text(json.dumps(result, indent=2, allow_nan=False) + "\n")
|
|
print(json.dumps(result, indent=2, allow_nan=False))
|
|
raise SystemExit(0 if result["passed"] else 1)
|