feat(domain): benchmark all differentiable solvers in the loop - #116
Draft
andrinr wants to merge 27 commits into
Draft
feat(domain): benchmark all differentiable solvers in the loop#116andrinr wants to merge 27 commits into
andrinr wants to merge 27 commits into
Conversation
andrinr
force-pushed
the
feat/ns-grid-solver-in-loop
branch
from
July 24, 2026 15:02
2b53888 to
358e231
Compare
This was referenced Jul 27, 2026
andrinr
force-pushed
the
feat/ns-grid-solver-in-loop
branch
from
July 27, 2026 12:51
7d6a683 to
04b56d8
Compare
Contributor
📊 View the full benchmark resultsNo benchmarks ran for this PR, so there is no status report. |
…n-loop Pick up the canonical recurrent-state refactors from #121: solvers now inherit the state/return_state fields instead of redeclaring them, the recurrent layout utilities moved to mosaic_shared, and the INS.jl periodic field adapters are shared. Regenerate production.uv.lock and requirements.txt from the merged pyproject so the equinox and jax[cuda12] additions sit on top of the updated base dependency set.
The shared-target solver-loop comparison trains every corrector against one external pseudo-spectral reference, so corrected error carries each solver's own discretization error and the ranking mostly reports which coarse forward started closest to that reference. The self-reference task gives each solver its own refined target, so all six face the same problem -- remove your own discretization error through your own gradients -- which is the fairness 3D initial-condition recovery gets by having each solver invert its own forward map. The ranked quantity is the normalized refinement-gap closure. Train it to a converged budget: a 200 -> 1000 -> 4000 update ladder showed correction gain still climbing well past 1000 updates, so a 200-update ranking ranked whoever trained fastest. Switch to the plain mean objective, which beat solver_terminal at equal budget in a paired probe.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One 2D solver-in-the-loop neural-correction benchmark, shared by all six
differentiable Navier–Stokes grid solvers: JAX-CFD, INS.jl, PhiFlow, PICT,
Warp-NS, XLB. Same corrector, same data, same optimizer, same protocol —
only the differentiable solver transition and its VJP change between cells.
It reports two things that are usually conflated, and keeps them apart:
solver? Reference-dependent, reported per target.
autoregressive solver–corrector transitions beat the identical forward
recurrence with the state stopped at every solver output? This is the
primary differentiability result: a recurrent credit-assignment audit.
Stacked on #121 (opt-in canonical recurrent state); draft until that lands.
The ranked result
Which solver should you pick for solver-in-the-loop training? Each solver's
corrector is trained against that solver's own spatially and temporally
refined trajectory, so every solver faces the same task — remove your own
discretization error using your own gradients — and none is penalised for
where its raw forward happens to sit relative to some external reference. This
is the fairness that 3D initial-condition recovery gets by having each solver
invert its own forward map. The ranked quantity is the fraction of a solver's
own coarse-to-fine gap that its corrector closes; raw errors are not
comparable across solvers here, and are shown only for context.
Three model seeds each, 3000 updates, mean objective:
Two things fall out, and they are the same two the shared-target study found:
Only velocity-complete solvers produce a corrector worth running. PICT and
Warp-NS close their own refinement gap by 1.87× and 1.36×. The three admitted
checkpoint solvers make their own rollout worse than not correcting at all,
at a converged budget, against their own target — so this is not an artifact of
chasing someone else's discretization.
The solver VJP is worth the most exactly where the corrector fails. Lift is
0.98–0.99 for the two solvers whose correctors work, and 1.13–1.40 for the
three that lose. Backpropagating through the solver reliably separates two bad
correctors and does nothing for a good one.
The ranking does not depend on the target. Repeating the comparison with
every solver trained against one shared 128² pseudo-spectral reference gives
PICT 1.95×, Warp-NS 1.37×, JAX-CFD 0.87×, INS.jl 0.79×, XLB 0.79× — the same
top two, the same split, and the same inverse relation to lift. Since the two
designs fail in opposite ways (a shared target confounds correctability with
forward accuracy; per-solver targets differ in difficulty), agreement between
them is the strongest evidence in this PR.
PhiFlow is the one gap: its native state closes the shared-target task but its
refined-reference closure audit spikes, so it is refused admission to the fair
comparison and can only be ranked in the shared-target view. An admission
failure is reported as a result, as elsewhere in this benchmark.
Paired differentiability result
Differentiating through the solver pays, and that is the robust part of the
story. Under both independent references, four of six solvers show a
resolved paired benefit from full temporal credit over local one-step
supervision. Nothing about the forward recurrence or the supervision changes
between the two arms — only whether gradients cross solver steps.
A better gradient does not buy you a better corrector. At this training
budget only PICT's corrector beats its own uncorrected solver under both
references; the other five are worse than doing nothing, and the three with
the largest VJP lift are among the worst absolute performers. Temporal credit
and corrector usefulness are separate axes, and a benchmark that reports only
one of them will mislead. The 200-update budget is part of why the other five
lose here — see the follow-up
for what a 15× budget changes, and what it does not.
The solver's error is a property of the solver; the corrector's error is a
property of the target you picked. Repeating the whole study against an
independently discretized reference — dealiased pseudo-spectral versus
conservative finite volume, whose held-out fields agree to a median 0.16% —
moves native solver error by at most 2.7% but moves trained corrected error by
up to 40.3% (PhiFlow), and flips PICT's paired VJP verdict from significantly
harmful to significantly beneficial. Very similar targets do not imply the
same learned endpoint. If you benchmark a hybrid solver against one reference,
you are reporting a property of that reference too.
Protocol
Paired training and evaluation — click to expand
Every cell shares a 32² candidate grid, viscosity, physical time step, 16
training ICs, eight held-out ICs, three model seeds, 200 optimizer updates,
recurrent training to
t=1.92, and evaluation tot=2.88. The learnedcomponent is the same zero-initialized Equinox periodic residual CNN (56,098
parameters).
Training uses truncated backpropagation through eight consecutive correction
intervals. Each interval advances four native solver steps (
4 × 0.02 = 0.08),applies the corrector, and feeds both the corrected velocity and the native
solver checkpoint into the next interval. There is no teacher forcing inside
the sampled window. The loss averages all eight corrected states and adds a
0.1-weight terminal loss on the last provisional solver state. Held-out
evaluation is fully free-running for 36 solver–corrector intervals — after the
initial condition no reference field re-enters the rollout.
The two paired arms are:
transitions, including solver velocity and native state;
recurrent velocity and native state are stopped at every solver output.
The VJP lift is the geometric paired
error_local / error_fullratio.Correction gain is a separate quantity:
error_uncorrected / error_corrected.Reference design and convergence audits — click to expand
dt/4dt/8dt/4dt/8Both start from the same Fourier-prolonged continuum initial condition and
compare seeds 0 and 100 at frames 1, 8, 24, 36. Training is rejected if the p95
128²-versus-256² discrepancy exceeds 0.5%.
The finite-volume method uses an FFT only for the periodic discrete Poisson
solve; transport and diffusion use conservative grid stencils, so this is not a
second spectral integrator.
Recurrent-state admission — click to expand
Native recurrence is detected only when
stateis differentiable in both theTesseract input and output schemas. JAX-CFD, INS.jl, PhiFlow and XLB carry a
native checkpoint through training, evaluation, plotting, finite-difference
validation and differentiation; PICT and Warp-NS are velocity-complete. All six
pass the same nonlinear and Taylor–Green recurrence gate.
Controls: analytic Taylor–Green and method-local reference — click to expand
Analytic Taylor–Green. All six solvers pass and train against the analytic
solution. JAX-CFD, INS.jl, PhiFlow, PICT and Warp-NS improve absolute error;
XLB is close to neutral. The paired VJP effect is small near this error floor,
as expected.
Method-local refined reference. Five solvers also complete a task against
their own 64², half-step target. Absolute errors are not ranked across solvers
because the targets differ. PICT improves absolute error by 1.119×; the paired
VJP benefit is resolved for JAX-CFD (37.0%), INS.jl (29.8%), XLB (13.3%) and
PICT (4.60%), and inconclusive for Warp-NS. PhiFlow is rejected before training
in this control only: its native state closes the common-reference task, but
the chaotic refined-reference audit spikes to 0.0101/0.0252 maximum
coarse/fine closure residuals, 22.8%/70.7% of the refinement signal.
Full fields, physics diagnostics and GIFs for every task are in the
artifact index.
Limits
differentiation; it is not a cross-solver gradient-quality ranking.
It does not say the corrector beats the uncorrected solver: across six
solvers the two properties are anti-correlated (see the follow-up above).
sweep tests whether conclusions survive one independent discretization
change; it does not establish a universally neutral reference.
distribution, viscosity, resolution and horizon only.
Follow-up: is the sub-one correction gain a budget artifact?
Partly, and the answer separates the solvers along the recurrent-state
interface. A budget ladder (200 → 1000 → 4000 updates) and a paired objective
probe showed both published choices understate the corrector: the plain
meanobjective beats the
solver_terminalone at equal budget, and correction gainkeeps climbing with updates. Repeating the whole nonlinear task at 3000 updates
with
mean, three model seeds per solver:The two axes oppose each other across the six solvers (Spearman 0.77 between
better gain and lower lift, XLB the exception): every solver with a resolved
VJP lift trails its uncorrected solver, and neither solver that beats its
uncorrected solver shows one. Per-solver, against a zero log-lift:
No cell in this benchmark shows the solver VJP helping a corrector that is
itself useful. Where the VJP clearly helps, it separates two correctors that
both lose to doing nothing; where the corrector wins, the VJP is worth nothing
or slightly negative. The fair per-solver ranking above reproduces this
independently.
One caveat on the metric itself: the paired control stops the recurrent
velocity and the native checkpoint. A checkpoint solver therefore loses
strictly more gradient path to the control than a velocity-complete solver,
which has no checkpoint to stop. Part of the measured lift may reflect how much
the control removes rather than what differentiating through the solver is
worth, so lift magnitudes are not directly comparable across the two interface
classes.
Two limits on how far that should be read:
cell scored 1.059×, which looked like a crossover. Replicating it across
three seeds gives 0.949× (log sd 0.096) — the seed spread at 4000 updates is
six times wider than at 3000, and the apparent jump was seed noise, not
budget. Checkpoint correctors do not cross 1.0 out to 4000 updates.
within-solver probe that forces a checkpoint solver onto the velocity-complete
path reproduces both halves of the split, but it fails this benchmark's own
recurrence-closure gate (
long_closure_error_p950.52 and 0.26 against a 0.01tolerance) and is therefore diagnostic only. Two solvers per class is a small
sample: the split is a robust observation, not an established causal claim
about recurrent-state interfaces.
One gradient-quality result fell out of the same runs: PhiFlow's training
gradient went non-finite at update 2021 in one of three seeds and the harness
stopped that cell, consistent with the existing repository finding that
projection-based schemes accumulate modes that corrupt long gradients. That
seed is excluded from the PhiFlow row above rather than averaged in.
Implementation
stateis differentiable in both schemas.finite-difference checks, long-closure checks and self-reference generation.
resolution audits, and a gated 128²-versus-256² space-time convergence check.
optimization/solver_in_loop_reference_sensitivityexperiment.Validation and offline execution — click to expand
All experiments ran offline on Kander through the shared Slurm/Pyxis solver
tooling. No hosted benchmark was triggered; this draft carries
benchmark:none.1697345; all-held-out reference-disagreementaudit:
1697383;1697346–1697351; finite-volume production:1697352,1697371–1697375; merge/render:1697376;21db5ff: Ruff and format passed; 522 testspassed, three skipped (
1697344);passed; hosted Python checks are reported on this PR head.