Freeze SmoothLife model contract and fixtures

This commit is contained in:
2026-07-14 18:26:55 +02:00
parent 51cff7b0f3
commit d587f542eb
25 changed files with 30612 additions and 38 deletions

View File

@@ -0,0 +1,709 @@
#!/usr/bin/env python3
"""Generate or verify the committed Macrostep 00 contract fixtures."""
from __future__ import annotations
import argparse
import hashlib
import json
import math
import sys
from dataclasses import asdict
from pathlib import Path
from typing import Any, Mapping, Sequence
TOOLS_DIR = Path(__file__).resolve().parent
ROOT = TOOLS_DIR.parent
FIXTURE_DIR = ROOT / "tests" / "fixtures" / "contract"
if str(TOOLS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_DIR))
from contract_oracle import ( # noqa: E402
ChaCha12,
Rule,
Scale,
ab3_startup,
circular_convolution,
delayed_boxes,
delayed_step,
euler_step,
f32,
f32_bits,
flat_index,
iter_coords,
legacy_butterfly_plan,
legacy_convolution,
legacy_sphere_map,
legacy_x_conversion_plan,
multiscale_step,
neighborhoods,
planar_splats,
product,
rising_curve,
rk4_relaxation,
rk4_step,
rule_target,
sampled_kernels,
signed_offset,
sphere_geometry,
sphere_overlays,
sphere_step,
unflatten_index,
window_curve,
)
FORMAT_VERSION = 1
def _render(value: Any) -> bytes:
return (
json.dumps(value, indent=2, ensure_ascii=False, allow_nan=False) + "\n"
).encode("utf-8")
def _f32_scalar(value: float) -> dict[str, Any]:
rounded = f32(value)
return {"decimal": rounded, "bits": f"0x{f32_bits(rounded):08x}"}
def _f32_series(values: Sequence[float]) -> dict[str, Any]:
rounded = [f32(value) for value in values]
return {
"decimal": rounded,
"bits": [f"0x{f32_bits(value):08x}" for value in rounded],
}
def _complex_f32_series(values: Sequence[tuple[float, float]]) -> dict[str, Any]:
rounded = [(f32(real), f32(imag)) for real, imag in values]
return {
"decimal": [[real, imag] for real, imag in rounded],
"bits": [
[f"0x{f32_bits(real):08x}", f"0x{f32_bits(imag):08x}"]
for real, imag in rounded
],
}
def _encode_plan(entries: Sequence[Mapping[str, Any]]) -> list[dict[str, Any]]:
return [
{
"output": entry["output"],
"source": entry["source"],
"twiddle": _f32_series(entry["twiddle"]),
}
for entry in entries
]
def _encode_stages(stages: Sequence[dict[str, Any]]) -> list[dict[str, Any]]:
encoded: list[dict[str, Any]] = []
for stage in stages:
values = stage["values"]
if values and isinstance(values[0], tuple):
encoded_values = _complex_f32_series(values)
else:
encoded_values = _f32_series(values)
encoded.append({"name": stage["name"], "values": encoded_values})
return encoded
def indexing_fixture() -> dict[str, Any]:
shape_records = []
for shape in ((8,), (5, 3), (4, 3, 2)):
shape_records.append(
{
"shape": list(shape),
"x_fast_formula": "x + Nx*(y + Ny*z) (truncated to rank)",
"entries": [
{"coords": list(coords), "index": flat_index(coords, shape)}
for coords in iter_coords(shape)
],
"inverse": [
list(unflatten_index(index, shape))
for index in range(product(shape))
],
}
)
return {
"format_version": FORMAT_VERSION,
"description": "Canonical x-fast indexing, inverse indexing, wrapping, and signed even offsets.",
"shapes": shape_records,
"signed_offsets": [
{
"extent": extent,
"values": [signed_offset(index, extent) for index in range(extent)],
}
for extent in (2, 4, 6, 8)
],
"wrap_examples": [
{"value": value, "extent": extent, "wrapped": value % extent}
for value, extent in ((-9, 8), (-1, 8), (8, 8), (17, 8), (-7, 6))
],
}
def curves_fixture() -> dict[str, Any]:
center = 0.5
width = 0.2
epsilon = 1e-12
rising_x = [
center - width,
center - width / 2.0 - epsilon,
center - width / 2.0,
center,
center + width / 2.0,
center + width / 2.0 + epsilon,
center + width,
]
window_x = [0.249999999999, 0.25, 0.3, 0.5, 0.7, 0.75, 0.750000000001]
overshoot_points = [0.096, 0.364, 0.5, 0.636, 0.904]
return {
"format_version": FORMAT_VERSION,
"description": "Boundary samples for every scalar curve and explicit overshoot samples.",
"rising": {
"center": center,
"width": width,
"x": rising_x,
"curves": [
{
"type": curve_type,
"values": [
rising_curve(curve_type, x, center, width) for x in rising_x
],
}
for curve_type in range(8)
],
},
"windows": {
"a": 0.3,
"b": 0.7,
"width": 0.1,
"x": window_x,
"curves": [
{
"type": curve_type,
"values": [
window_curve(curve_type, x, 0.3, 0.7, 0.1) for x in window_x
],
}
for curve_type in range(10)
],
},
"overshoot": [
{
"type": curve_type,
"samples": [
{"x": x, "value": rising_curve(curve_type, x, center, width)}
for x in overshoot_points
],
}
for curve_type in (6, 7)
],
"hard_window_exact_interval": {
"a": 0.3,
"b": 0.7,
"at_a": window_curve(0, 0.3, 0.3, 0.7, 0.1),
"below_b": window_curve(0, math.nextafter(0.7, -math.inf), 0.3, 0.7, 0.1),
"at_b": window_curve(0, 0.7, 0.3, 0.7, 0.1),
},
}
def rule_surface_fixture() -> dict[str, Any]:
m_axis = [0.2, 0.5, 0.8]
n_axis = [0.2, 0.5, 0.8]
base = Rule()
values = []
for sigmode in range(1, 5):
by_sigtype = []
for sigtype in range(10):
by_mixtype = []
for mixtype in range(8):
rule = Rule(
b1=base.b1,
b2=base.b2,
d1=base.d1,
d2=base.d2,
sn=base.sn,
sm=base.sm,
sigmode=sigmode,
sigtype=sigtype,
mixtype=mixtype,
)
by_mixtype.append(
[[rule_target(n, m, rule) for n in n_axis] for m in m_axis]
)
by_sigtype.append(by_mixtype)
values.append(by_sigtype)
return {
"format_version": FORMAT_VERSION,
"description": "Rule surface [sigmode][sigtype][mixtype][M][N], including all 320 enum triples.",
"rule_parameters": {
key: value
for key, value in asdict(base).items()
if key not in ("sigmode", "sigtype", "mixtype")
},
"axes": {
"sigmode": list(range(1, 5)),
"sigtype": list(range(10)),
"mixtype": list(range(8)),
"M": m_axis,
"N": n_axis,
},
"enum_combination_count": 4 * 10 * 8,
"values": values,
}
def planar_fields_fixture() -> dict[str, Any]:
cases = [
((8,), [0.0, 0.17, 0.91, 0.26, 0.73, 0.42, 0.08, 0.64]),
((5, 4), [((index * 11 + 3) % 29) / 28.0 for index in range(20)]),
((4, 3, 2), [((index * 13 + 5) % 37) / 36.0 for index in range(24)]),
]
encoded_cases = []
for shape, field in cases:
m, n, kernels = neighborhoods(field, shape, 1.45, 3.0, 5.0)
encoded_cases.append(
{
"rank": len(shape),
"shape": list(shape),
"field": field,
"kernel": kernels,
"direct_disk_convolution_raw": circular_convolution(
field, kernels["raw_disk"], shape
),
"direct_ring_convolution_raw": circular_convolution(
field, kernels["raw_ring"], shape
),
"M_disk_normalized": m,
"N_ring_normalized": n,
}
)
known = sampled_kernels((64, 64), 10.0, 3.0, 10.0)
return {
"format_version": FORMAT_VERSION,
"description": "Asymmetric f64 fields with complete sampled kernels and direct circular convolutions.",
"convolution_sign": "out[x] = sum_offset field[x-offset] * kernel[offset] with every axis periodic",
"cases": encoded_cases,
"known_2d_check": {
"shape": [64, 64],
"ra": 10.0,
"rr": 3.0,
"rb": 10.0,
"ring_sum": known["ring_sum"],
"disk_sum": known["disk_sum"],
},
}
def _fft_case(
shape: tuple[int, ...], field: list[float], kernel: list[float]
) -> dict[str, Any]:
result = legacy_convolution(field, kernel, shape, capture_stages=True)
nx = shape[0]
plans: dict[str, Any] = {
"x_forward_butterflies": [
{
"stage": stage,
"entries": _encode_plan(legacy_butterfly_plan(nx // 2, stage, -1)),
}
for stage in range(1, (nx // 2).bit_length())
],
"x_forward_real_conversion": _encode_plan(legacy_x_conversion_plan(nx, -1)),
"x_inverse_real_conversion": _encode_plan(legacy_x_conversion_plan(nx, 1)),
"x_inverse_butterflies": [
{
"stage": stage,
"entries": _encode_plan(legacy_butterfly_plan(nx // 2, stage, 1)),
}
for stage in range(1, (nx // 2).bit_length())
],
}
for axis, name in enumerate("yz", start=1):
if axis < len(shape):
plans[f"{name}_forward_butterflies"] = [
{
"stage": stage,
"entries": _encode_plan(
legacy_butterfly_plan(shape[axis], stage, -1)
),
}
for stage in range(1, shape[axis].bit_length())
]
plans[f"{name}_inverse_butterflies"] = [
{
"stage": stage,
"entries": _encode_plan(
legacy_butterfly_plan(shape[axis], stage, 1)
),
}
for stage in range(1, shape[axis].bit_length())
]
return {
"shape": list(shape),
"packed_shape": [nx // 2 + 1, *shape[1:]],
"input_f32": _f32_series(field),
"kernel_f32": _f32_series(kernel),
"kernel_sum_f64": sum(kernel),
"scales_f32": {
"unitary_butterfly": _f32_scalar(1.0 / math.sqrt(2.0)),
"forward_real_conversion": _f32_scalar(0.5 / math.sqrt(2.0)),
"inverse_real_conversion": _f32_scalar(0.5 * math.sqrt(2.0)),
"spectral_correction": _f32_scalar(result["correction"]),
},
"plans": plans,
"forward_field_stages": _encode_stages(result["field_stages"]),
"field_spectrum": _complex_f32_series(result["field_spectrum"]),
"kernel_spectrum": _complex_f32_series(result["kernel_spectrum"]),
"spectral_product": _complex_f32_series(result["spectral_product"]),
"inverse_product_stages": _encode_stages(result["inverse_stages"]),
"convolution_f32": _f32_series(result["output"]),
"direct_normalized_f64": result["direct_normalized"],
"max_abs_error_to_direct": max(
abs(actual - expected)
for actual, expected in zip(
result["output"], result["direct_normalized"], strict=True
)
),
}
def packed_fft_fixture() -> dict[str, Any]:
definitions = []
for shape in ((8,), (4, 4), (4, 2, 2)):
count = product(shape)
field = [((index * 7 + 1) % 19) / 18.0 for index in range(count)]
kernel = [0.2 + ((index * 5 + 2) % 11) / 13.0 for index in range(count)]
definitions.append(_fft_case(shape, field, kernel))
return {
"format_version": FORMAT_VERSION,
"description": "Legacy adjacent-real packed unitary 1D/2D/3D FFT with operation-ordered IEEE-f32 stages.",
"operation_order": {
"butterfly_real": "f32(f32(f32(a.r + f32(cos*b.r)) - f32(sin*b.i)) * f32(1/sqrt(2)))",
"butterfly_imag": "f32(f32(f32(a.i + f32(cos*b.i)) + f32(sin*b.r)) * f32(1/sqrt(2)))",
"complex_multiply": "real=f32(f32(ar*br)-f32(ai*bi)); imag=f32(f32(ar*bi)+f32(ai*br))",
"kernel_scaling": "scale each kernel spectrum component first by f32(sqrt(sample_count)/kernel_sum)",
},
"layout": "adjacent x samples become real/imag; spectrum x extent is Nx/2+1; x remains fastest",
"cases": definitions,
}
def integration_fixture() -> dict[str, Any]:
initial = [0.02, 0.37, 0.81, 0.98]
time = 0.25
dt = 0.4
def derivative(state: Sequence[float], current_time: float) -> list[float]:
return [
0.34 - 0.45 * value + (index + 1) * 0.08 * current_time
for index, value in enumerate(state)
]
def target(state: Sequence[float]) -> list[float]:
return [
0.1
+ 0.65 * state[(index - 1) % len(state)]
+ 0.2 * state[(index + 1) % len(state)]
for index in range(len(state))
]
return {
"format_version": FORMAT_VERSION,
"description": "Clamp-at-commit Euler/AB and clamp-every-stage RK4, including both relaxation references.",
"initial": initial,
"time": time,
"dt": dt,
"synthetic_derivative": "k_i(A,t)=0.34-0.45*A_i+(i+1)*0.08*t",
"euler": euler_step(initial, time, dt, derivative),
"ab3_startup": ab3_startup(initial, time, dt, derivative),
"rk4": rk4_step(initial, time, dt, derivative),
"relaxation_target": "S_i(A)=0.1+0.65*A_(i-1)+0.2*A_(i+1), periodic",
"rk4_relaxation_stage_state": rk4_relaxation(
initial, dt, target, "stage_state"
),
"rk4_relaxation_step_origin": rk4_relaxation(
initial, dt, target, "step_origin"
),
}
def multiscale_fixture() -> dict[str, Any]:
shape = (5, 4)
field = [((index * 17 + 4) % 31) / 30.0 for index in range(product(shape))]
scales = [
Scale(1.65, 3.0, 6.0, 0.18, Rule(sigmode=2, sigtype=4, mixtype=3)),
Scale(1.25, 3.0, 6.0, 0.11, Rule(sigmode=3, sigtype=2, mixtype=5)),
Scale(0.95, 3.0, 6.0, 0.07, Rule(sigmode=4, sigtype=7, mixtype=1)),
]
cases = []
for dynamics in ("growth", "relaxation"):
for interpretation in ("independent", "chained"):
for composition in ("sequential", "ordered_clamped_sum", "mean_increment"):
cases.append(
multiscale_step(
field, shape, scales, interpretation, composition, dynamics
)
)
return {
"format_version": FORMAT_VERSION,
"description": "All 2 interpretations x 3 compositions for growth and corrected relaxation.",
"shape": list(shape),
"field": field,
"scales": [
{
"ra": scale.ra,
"rr": scale.rr,
"rb": scale.rb,
"dt": scale.dt,
"rule": asdict(scale.rule),
}
for scale in scales
],
"chained_inputs": [
["ring_0", "ring_1"],
["ring_1", "ring_2"],
["ring_2", "disk_2"],
],
"case_count": len(cases),
"cases": cases,
}
def sphere_fixture() -> dict[str, Any]:
k = 4
ra = 1.4
rule = Rule(sigmode=2, sigtype=4, mixtype=4)
geometry = sphere_geometry(k)
field = [((index * 19 + 7) % 43) / 42.0 for index in range(6 * k * k)]
constant_value = 0.375
probes = [
{"label": "face0_center", "face": 0, "x": 1, "y": 1},
{"label": "face1_center", "face": 1, "x": 2, "y": 2},
{"label": "face0_left_edge", "face": 0, "x": 0, "y": 1},
{"label": "face2_top_edge", "face": 2, "x": 2, "y": 3},
{"label": "face0_bottom_left_corner", "face": 0, "x": 0, "y": 0},
{"label": "face4_top_right_corner", "face": 4, "x": 3, "y": 3},
]
models = {}
for model in ("corrected", "legacy"):
result = sphere_step(field, k, ra, rule, model)
constant = sphere_step([constant_value] * (6 * k * k), k, ra, rule, model)
probe_values = []
for probe in probes:
index = probe["face"] * k * k + probe["y"] * k + probe["x"]
probe_values.append(
{
**probe,
"index": index,
"M": result["m"][index],
"N": result["n"][index],
"S": result["s"][index],
"next_discrete": result["next_discrete"][index],
"next_smooth": result["next_smooth"][index],
}
)
models[model] = {**result, "constant_field": constant, "probes": probe_values}
legacy_map = []
for face in range(6):
for label, x, y in (
("left", -1, 1),
("right", k, 1),
("bottom", 1, -1),
("top", 1, k),
("masked_bottom_left_diagonal", -1, -1),
("masked_top_right_diagonal", k, k),
):
mapped = legacy_sphere_map(face, x, y, k)
legacy_map.append(
{
"face": face,
"region": label,
"query": [x, y],
"mapped": list(mapped) if mapped is not None else None,
}
)
return {
"format_version": FORMAT_VERSION,
"description": "Compact even-K corrected global enumeration and deterministic legacy side-gutter sphere goldens.",
"k": k,
"radius": k / 2.0,
"ra_planar": ra,
"rule": asdict(rule),
"field": field,
"geometry": geometry,
"probe_definitions": probes,
"legacy_side_and_mask_map": legacy_map,
"models": models,
}
def delayed_time_fixture() -> dict[str, Any]:
shape = (5, 4)
depth = 16
head = 5
history = [[layer / 15.0] * product(shape) for layer in range(depth)]
rule = Rule(sigmode=2, sigtype=4, mixtype=4)
result = delayed_step(history, shape, head, 2.2, rule)
shells: dict[int, list[list[int]]] = {}
for entry in result["stencil"]["entries"]:
shells.setdefault(entry["delay"], []).append([entry["dx"], entry["dy"]])
return {
"format_version": FORMAT_VERSION,
"description": "Layer-coded causal radial shells; head is next overwrite; both direct and fixed smooth updates.",
"shape": list(shape),
"depth": depth,
"history": history,
"head": head,
"latest": (head - 1) % depth,
"rule": asdict(rule),
"shell_offsets_by_rounded_age": [
{
"age": age,
"offsets": offsets,
"selected_layer": ((head - 1) - age) % depth,
}
for age, offsets in sorted(shells.items())
],
"evaluation": result,
}
def initializers_fixture() -> dict[str, Any]:
zero_rng = ChaCha12(0)
seed_one_rng = ChaCha12(1)
seed_one_u64_rng = ChaCha12(1)
seed_one_float_rng = ChaCha12(1)
return {
"format_version": FORMAT_VERSION,
"description": "Exact topology-native seeded f64 initializer arrays; arrays, not hashes, are authoritative.",
"prng": {
"algorithm": "ChaCha12, 256-bit key = LE seed u64 + 24 zero bytes, original 64-bit counter and 64-bit stream both zero",
"u64_order": "low u32 then high u32",
"float": "top 53 bits of u64 multiplied by 2^-53",
"integer": "reject u64 values at or above 2^64-(2^64 mod span), then modulo span",
"seed_0_first_16_u32_hex": [f"0x{zero_rng.u32():08x}" for _ in range(16)],
"seed_1_first_16_u32_hex": [
f"0x{seed_one_rng.u32():08x}" for _ in range(16)
],
"seed_1_first_8_u64_hex": [
f"0x{seed_one_u64_rng.u64():016x}" for _ in range(8)
],
"seed_1_first_8_float53": [seed_one_float_rng.float53() for _ in range(8)],
},
"planar_periodic_splats": [
planar_splats((12,), 3.0, 1),
planar_splats((8, 6), 2.0, 1),
planar_splats((6, 5, 4), 1.6, 1),
],
"sphere_geodesic_overlays": sphere_overlays(6, 1, 1000),
"delayed_time_periodic_boxes": delayed_boxes((17, 16), 1, 16, 1000),
}
DESCRIPTIONS = {
"indexing.json": "Indexing and signed offsets",
"curves.json": "Scalar curves and boundaries",
"rule_surface.json": "Complete rule enum surface",
"planar_fields.json": "Sampled kernels and direct convolution",
"legacy_packed_fft.json": "Packed-unitary f32 FFT oracle",
"integration.json": "Euler, AB startup, RK4 references",
"multiscale.json": "All multiscale policies",
"sphere.json": "Corrected and legacy sphere",
"delayed_time.json": "Causal delayed-time shells",
"initializers.json": "ChaCha12 and exact seeded arrays",
}
def build_payloads() -> dict[str, Any]:
return {
"indexing.json": indexing_fixture(),
"curves.json": curves_fixture(),
"rule_surface.json": rule_surface_fixture(),
"planar_fields.json": planar_fields_fixture(),
"legacy_packed_fft.json": packed_fft_fixture(),
"integration.json": integration_fixture(),
"multiscale.json": multiscale_fixture(),
"sphere.json": sphere_fixture(),
"delayed_time.json": delayed_time_fixture(),
"initializers.json": initializers_fixture(),
}
def expected_files() -> dict[str, bytes]:
payloads = build_payloads()
rendered = {name: _render(payload) for name, payload in payloads.items()}
manifest = {
"format_version": FORMAT_VERSION,
"contract": "Macrostep 00 deterministic oracle fixtures",
"generator": "tools/generate_contract_fixtures.py",
"oracle": "tools/contract_oracle.py",
"standard_library_only": True,
"semantic_float": "IEEE-754 binary64 represented as JSON numbers",
"packed_fft_float": "IEEE-754 binary32 after every operation, with decimal values and hexadecimal bit patterns",
"determinism": "No timestamp, locale, platform RNG, external source tree, or runtime dependency is used.",
"files": [
{
"path": name,
"description": DESCRIPTIONS[name],
"bytes": len(rendered[name]),
"sha256": hashlib.sha256(rendered[name]).hexdigest(),
}
for name in payloads
],
}
rendered["manifest.json"] = _render(manifest)
return rendered
def write_files(files: dict[str, bytes]) -> None:
FIXTURE_DIR.mkdir(parents=True, exist_ok=True)
for name, content in files.items():
(FIXTURE_DIR / name).write_bytes(content)
def check_files(files: dict[str, bytes]) -> int:
failures: list[str] = []
for name, expected in files.items():
path = FIXTURE_DIR / name
if not path.exists():
failures.append(f"missing: {path.relative_to(ROOT)}")
elif path.read_bytes() != expected:
failures.append(f"stale: {path.relative_to(ROOT)}")
if FIXTURE_DIR.exists():
extras = sorted(
path.name for path in FIXTURE_DIR.glob("*.json") if path.name not in files
)
failures.extend(
f"unexpected: {(FIXTURE_DIR / name).relative_to(ROOT)}" for name in extras
)
if failures:
sys.stderr.write("contract fixtures are not current:\n")
for failure in failures:
sys.stderr.write(f" {failure}\n")
return 1
sys.stdout.write(f"verified {len(files)} contract fixture files\n")
return 0
def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--check", action="store_true", help="verify committed bytes without writing"
)
args = parser.parse_args(argv)
files = expected_files()
if args.check:
return check_files(files)
write_files(files)
sys.stdout.write(
f"wrote {len(files)} contract fixture files under "
f"{FIXTURE_DIR.relative_to(ROOT)}\n"
)
return 0
if __name__ == "__main__":
raise SystemExit(main())