Run this on EVERY machine before it joins the campaign.
python check_machine.py # compare against the committed reference
python check_machine.py --write # (re)generate the reference, once, on one machine
Why this exists
---------------
The C++ solver is NOT in git -- `build/` is ignored, so every machine compiles
its own from cpp_utils/. Four machines with different compiler or SUNDIALS
versions produce numerically different results while every hash in the
provenance block still looks plausible, and merge_and_sobol would then mix them
into one Sobol estimate. That is the same class of error as the grid
saturation this project already hit: a believable number with no validity.
So: pin one fixed configuration, run it, and compare against a reference
committed from a known-good machine. It takes ~30 s and it is the difference
between "the four machines agree" and "the four machines were assumed to
agree".
The check deliberately uses a SMALL, FAST configuration. It is verifying that
the toolchain agrees, not that the physics is right -- the run is expected to be
inadmissible (the grid is far too coarse), and that is fine.
Tolerance: 1e-6 relative -- the campaign's own integration rtol. CVODE with
fixed tolerances is bit-deterministic for a FIXED BINARY, so an earlier 1e-9
bar was right as long as every machine ran the same build. It is unreachable
across ARCHITECTURES: Windows/x86 (MSVC + MKL, /arch:AVX2) and macOS/arm64
(AppleClang + Accelerate, -march=native) reassociate and vectorise the same
reductions differently, which shows up as ~1e-7 drift on the CVODE-integrated
fields while the closed-form fields (Di_eff, Dv_eff, conv_*) still match to
0.0 exactly. Holding the gate tighter than the integrator's own accuracy
rejects machines whose physics is identical, so the bar is set AT the
integration tolerance: anything above it is a real discrepancy, anything below
it is beneath the resolution the solver claims in the first place.
OMP_NUM_THREADS is pinned to 1 so reduction order cannot vary within a build.