Freeze SmoothLife model contract and fixtures
This commit is contained in:
1453
tools/contract_oracle.py
Executable file
1453
tools/contract_oracle.py
Executable file
File diff suppressed because it is too large
Load Diff
709
tools/generate_contract_fixtures.py
Executable file
709
tools/generate_contract_fixtures.py
Executable 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())
|
||||
Reference in New Issue
Block a user