aquakin.DifferentiationConfig#
- class aquakin.DifferentiationConfig(mode='reverse', method='stable', check_finite=True, adjoint_max_steps=100000, adjoint_low_memory=False)[source]#
Bases:
objectHow a gradient / sensitivity flows through a solve.
A single frozen value object replacing the old AD selectors (
adjoint=,gradient=,ad_mode=,check_finite=,stable_adjoint_max_steps=). Passed asdiff=DifferentiationConfig(...).- Parameters:
mode ({"reverse", "forward"}) – Autodiff direction.
"reverse"(default) is the calibration-gradient direction (jax.grad/ a discrete adjoint);"forward"is the sensitivity-screen direction (jax.jacfwd/ a variational solve).method ({"stable", "through_solve"}) –
How the adjoint / sensitivity is formed for the chosen
mode.mode="reverse", method="stable"(the default) – a plant uses the cap-free hand-written discrete adjoint (the oldgradient="stable_adjoint"/"auto"routing: a concrete forward solve still takes the fast cached path, a differentiated solve takes the discrete adjoint). A reactor has no stable reverse adjoint, so it always usesRecursiveCheckpointAdjointregardless ofmethod.mode="reverse", method="through_solve"– differentiate through the diffrax solve (RecursiveCheckpointAdjoint; the oldgradient="jax_adjoint"). Needs adtmaxcap for a stiff model.mode="forward", method="stable"– the augmented[y; S]variational solve (cap-free, exact). Routed throughsolve_sensitivity/augmented_forward_sensitivity.mode="forward", method="through_solve"–jax.jvp/jacfwdvia a forward-capable adjoint (DirectAdjoint/ForwardMode).
check_finite (bool) – Raise a friendly error if a freshly computed gradient/Jacobian is non-finite, instead of returning silent
NaNvalues.adjoint_max_steps (int) – Buffer length for the discrete-adjoint backward scan (the old
stable_adjoint_max_steps); set it to a tight upper bound on the forward step count.adjoint_low_memory (bool) – Low-memory mode for the
method="stable"discrete adjoint.False(default) saves each forward step’s dense-output stage increments, so the backward reconstructs the stages cheaply – but the saved buffer is~n_stages× the trajectory.Truestores only the step states and recomputes each step’s stages in the backward pass (a per-step Newton scan), so the dense buffer is never allocated – trading compute for memory when that buffer is the binding constraint on a long, large-state plant solve. The recompute matches the saved-stage gradient (it is the same well-conditioned per-stage solve), so it is a pure memory/compute trade. Reversemethod="stable"only – ignored for athrough_solveor forward solve.
- __init__(mode='reverse', method='stable', check_finite=True, adjoint_max_steps=100000, adjoint_low_memory=False)#
- Parameters:
mode (str)
method (str)
check_finite (bool)
adjoint_max_steps (int)
adjoint_low_memory (bool)
- Return type:
None
Methods
__init__([mode, method, check_finite, ...])Whether the AD direction is forward (
jax.jacfwd/ a variational solve) rather than reverse (jax.grad/ a discrete adjoint).The reverse-adjoint backend this config selects.
The diffrax adjoint object a reactor / plant solve should carry.
Validate the
mode/methodvocabulary; returnself.Attributes
adjoint_low_memoryadjoint_max_stepscheck_finitemethodmode- validated()[source]#
Validate the
mode/methodvocabulary; returnself.Raises
ValueErrorfor an out-of-rangemodeormethod. This is the vocabulary check only – whether a particular consumer serves a given valid pairing (e.g.Plant.solverejecting theforward+stableaugmented solve) is that consumer’s own guard.- Return type:
- forms_jacfwd()[source]#
Whether the AD direction is forward (
jax.jacfwd/ a variational solve) rather than reverse (jax.grad/ a discrete adjoint).- Return type:
bool
- gradient_backend()[source]#
The reverse-adjoint backend this config selects.
"stable_adjoint"for the cap-free hand-written discrete adjoint (method="stable"), or"jax_adjoint"for differentiating through the diffrax solve (method="through_solve"). This is the canonicalmethod-> backend meaning the calibration entry points consume; the plant solve routesmethod="stable"through its own"auto"dispatch instead (seePlant._resolve_diff_config()).- Return type:
str
- reactor_adjoint()[source]#
The diffrax adjoint object a reactor / plant solve should carry.
Reactors and the plant have no hand-written (“stable”) reverse adjoint on the reactor object – reverse mode always uses the default
RecursiveCheckpointAdjoint(signalled byNone).methodmatters only for forward mode:through_solve-> a forward-capableDirectAdjoint(forward_adjoint());stable-> the augmentedsolve_sensitivitybackend, invoked explicitly (not via this adjoint), soNoneis still returned.