Automatic Differentiation and Sensitivity Algorithms (Adjoints)
Automatic differentiation control is exposed through the sensealg keyword argument to solve. A sensealg value is a lightweight AbstractSensitivityAlgorithm configuration object, or nothing to let the sensitivity package choose a default. SciMLBase owns the common dispatch surface and fallback errors; packages such as SciMLSensitivity.jl provide the concrete algorithms and ChainRules definitions that compute derivatives of solver calls.
High-level solve methods make the differentiable inputs explicit before dropping into the internal solve path. A representative shape is:
function solve(
prob::AbstractDEProblem, args...; sensealg = nothing,
u0 = nothing, p = nothing, kwargs...
)
u0 = u0 !== nothing ? u0 : prob.u0
p = p !== nothing ? p : prob.p
if sensealg === nothing && haskey(prob.kwargs, :sensealg)
sensealg = prob.kwargs[:sensealg]
end
return solve_up(prob, sensealg, u0, p, args...; kwargs...)
endsolve_up receives sensealg, u0, and p as positional arguments so ChainRules.jl rules can dispatch on the selected sensitivity algorithm and on the primal data being differentiated. Sensitivity packages then overload the internal calls with rules of the following form:
function ChainRulesCore.frule(
::typeof(solve_up), prob,
sensealg::Union{Nothing, AbstractSensitivityAlgorithm},
u0, p, args...;
kwargs...
)
return _solve_forward(prob, sensealg, u0, p, args...; kwargs...)
end
function ChainRulesCore.rrule(
::typeof(solve_up), prob::SciMLBase.AbstractDEProblem,
sensealg::Union{Nothing, AbstractSensitivityAlgorithm},
u0, p, args...;
kwargs...
)
return _solve_adjoint(prob, sensealg, u0, p, args...; kwargs...)
endIf no package has loaded compatible sensitivity rules, SciMLBase's default definitions throw informative errors:
function _concrete_solve_adjoint(args...; kwargs...)
throw(AdjointNotFoundError())
end
function _concrete_solve_forward(args...; kwargs...)
throw(ForwardSensitivityNotFoundError())
endThese errors tell users to load SciMLSensitivity.jl. The sensitivity mechanism lives outside SciMLBase because the automatic-differentiation stack has substantial dependency and load-time cost.
Solver and Algorithm Contracts
Solver authors should keep differentiable inputs visible to the SciMLBase solve interface. In practice, u0, p, and differentiable keyword data should flow through solve instead of being hidden in closures or global state. Solvers should document which problem fields can receive derivatives and which outputs may be differentiated, including interactions with saveat, save_idxs, dense output, callbacks, events, stochastic noise, and mutation.
Concrete sensitivity algorithms should be small configuration objects. They select how derivatives are computed, such as forward sensitivity equations, adjoint sensitivity equations, second-order sensitivity propagation, shadowing methods, or direct AD through solver operations. They should not store the problem or solution being differentiated. Algorithm docstrings should state the supported problem families, the differentiable quantities, the AD backends used for local derivative products, and the behavior for unsupported solver features.
Forward sensitivity algorithms propagate tangent information with the primal solve and are usually appropriate when the seed dimension is modest. Adjoint algorithms implement reverse-mode rules that propagate cotangents from solution values or objectives back to problem data. Second-order algorithms compute Hessians, Hessian-vector products, or related second derivatives. Shadowing algorithms target long-time statistics or trajectory quantities where direct trajectory sensitivities are not the right object.
Sensitivity Algorithm Interfaces
SciMLBase.AbstractSensitivityAlgorithm — Type
abstract type AbstractSensitivityAlgorithm{CS, AD, FDT} <: SciMLBase.AbstractSciMLAlgorithmBase interface for sensitivity algorithms passed through the sensealg keyword argument to solve. A sensealg value chooses the method used to differentiate the solver call, such as forward sensitivity equations, adjoint sensitivity equations, direct AD through solver operations, second-order methods, or shadowing methods for long-time averages.
SciMLBase owns the lightweight dispatch interface and fallback errors, while sensitivity packages provide the concrete algorithms and ChainRules definitions that implement derivatives of solve. Concrete sensitivity algorithms should be small configuration objects: they should describe how derivatives are computed, not store the problem being differentiated.
The type parameters are part of the dispatch key for downstream sensitivity packages. Concrete algorithms should document the meaning of those parameters, the supported problem families, the differentiable quantities (u0, p, save values, observables, or problem-specific data), the automatic-differentiation backends they use, and any restrictions on callbacks, events, mutation, interpolation, or saved output.
SciMLBase.AbstractOverloadingSensitivityAlgorithm — Type
abstract type AbstractOverloadingSensitivityAlgorithm{CS, AD, FDT} <: SciMLBase.AbstractSensitivityAlgorithm{CS, AD, FDT}Base interface for sensitivity algorithms that differentiate through, or otherwise overload, solver behavior. Subtypes participate in the solve automatic-differentiation path by providing rules that replace the default fallbacks for forward-mode and/or reverse-mode differentiation.
Concrete subtypes should document whether they differentiate the numerical solver directly, solve auxiliary sensitivity equations, or combine solver rules with an AD backend. They should also specify which solver features remain differentiable, how saved values and interpolation are treated, and what happens for unsupported problem or callback features.
SciMLBase.AbstractForwardSensitivityAlgorithm — Type
abstract type AbstractForwardSensitivityAlgorithm{CS, AD, FDT} <: SciMLBase.AbstractOverloadingSensitivityAlgorithm{CS, AD, FDT}Base interface for forward sensitivity algorithms. Forward sensitivity methods propagate tangent information alongside the primal solve and are typically used when the derivative seed dimension is modest or when the caller needs full solution sensitivities.
Concrete subtypes should document how tangent information is initialized, propagated, and returned; which inputs are differentiated; how parameters and initial conditions are seeded; and which problem, parameter, event, and callback features are supported. If the method relies on an AD backend for Jacobian-vector products or local derivative calculations, that backend and its limitations should be documented by the concrete algorithm.
SciMLBase.AbstractAdjointSensitivityAlgorithm — Type
abstract type AbstractAdjointSensitivityAlgorithm{CS, AD, FDT} <: SciMLBase.AbstractOverloadingSensitivityAlgorithm{CS, AD, FDT}Base interface for adjoint sensitivity algorithms. Adjoint methods implement the reverse-mode differentiation path for solve, propagating cotangents from saved solution values or user objectives back to differentiable problem data.
Concrete subtypes should document their adjoint equation, what primal-solve data must be retained or recomputed, checkpointing behavior, interpolation requirements, vector-Jacobian product backend, and assumptions about callbacks, events, discontinuities, noise, and mutation. They should also state which solution outputs and problem fields may receive gradients.
SciMLBase.AbstractSecondOrderSensitivityAlgorithm — Type
abstract type AbstractSecondOrderSensitivityAlgorithm{CS, AD, FDT} <: SciMLBase.AbstractOverloadingSensitivityAlgorithm{CS, AD, FDT}Base interface for second-order sensitivity algorithms. These algorithms compute Hessian, Hessian-vector, or related second-derivative information for solver outputs or objectives.
Concrete subtypes should document the first-order sensitivity method or AD backend they build on, the supported second-derivative product or materialized array form, how seeds and cotangents are represented, and any restrictions on problem types, callbacks, saved output, or nested AD backends.
SciMLBase.AbstractShadowingSensitivityAlgorithm — Type
abstract type AbstractShadowingSensitivityAlgorithm{CS, AD, FDT} <: SciMLBase.AbstractOverloadingSensitivityAlgorithm{CS, AD, FDT}Base interface for shadowing sensitivity algorithms. Shadowing methods estimate derivatives of long-time statistics or trajectory-dependent quantities in dynamical systems where direct trajectory sensitivities may be unsuitable.
Concrete subtypes should document the dynamical-systems assumptions required by the method, how trajectories and transients are selected, what objective or statistic is differentiated, how tangent or adjoint shadowing directions are computed, and which solver features, callbacks, and parameterizations are supported.
Concrete Solve Developer Interface
The following developer API is for packages that implement an AD integration or a sensitivity algorithm. Application code must select a documented sensealg through solve; it must not call these hooks or construct originator markers directly.
An integration creates or uses an SciMLBase.ADOriginator that identifies its outer AD system, then adds a narrowly dispatched concrete-solve method for types it owns. The method receives the effective prob, alg, sensealg, u0, and p values in that order and must return the ordinary primal result together with the corresponding pullback or pushforward. It must preserve the primal solve semantics and may not mutate the problem or differentiated inputs.
set_mooncakeoriginator_if_mooncake is the Mooncake overlay boundary for this protocol. Solver packages call it only while constructing their low-level originator keyword; application code must not call it.
SciMLBase.ADOriginator — Type
ADOriginatorDeveloper interface marker for the automatic-differentiation system that initiated a solve derivative.
ADOriginator values are passed to _concrete_solve_adjoint and _concrete_solve_forward so a sensitivity implementation can choose a rule compatible with the outer AD system.
Extension Rules
Packages that integrate a new AD system may define a zero-field subtype and pass an instance only from their own solve-derivative rule. They must also provide concrete-solve hook methods specialized on a problem, sensitivity algorithm, or originator type they own. Do not dispatch a broad fallback on ADOriginator, redefine another package's originator marker, or expose an originator value as an application-facing solver option.
The built-in markers identify ChainRules, Enzyme, ReverseDiff, Tracker, and Mooncake contexts. They are developer API; application code should select a documented sensealg and let the loaded AD integration choose the originator.
SciMLBase.ChainRulesOriginator — Type
ChainRulesOriginator()Zero-field ADOriginator marking a derivative initiated by a ChainRulesCore rule.
Developer Interface
Pass this marker to a concrete-solve hook only from a ChainRules-backed solve rule. Sensitivity packages may specialize hook methods on it to return a ChainRules pullback. Application code must not construct this marker to select a sensitivity algorithm.
SciMLBase.EnzymeOriginator — Type
EnzymeOriginator()Zero-field ADOriginator marking a derivative initiated by Enzyme.
Developer Interface
Pass this marker to a concrete-solve hook only from an Enzyme-backed solve rule. Sensitivity packages may specialize hook methods on it when the primal or derivative values require Enzyme-specific handling. Application code must not construct this marker to select a sensitivity algorithm.
SciMLBase.ReverseDiffOriginator — Type
ReverseDiffOriginator()Zero-field ADOriginator marking a derivative initiated by ReverseDiff.
Developer Interface
Pass this marker to a concrete-solve hook only from a ReverseDiff-backed solve rule. Sensitivity packages may specialize hook methods on it to preserve ReverseDiff tape semantics. Application code must not construct this marker to select a sensitivity algorithm.
SciMLBase.TrackerOriginator — Type
TrackerOriginator()Zero-field ADOriginator marking a derivative initiated by Tracker.
Developer Interface
Pass this marker to a concrete-solve hook only from a Tracker-backed solve rule. Sensitivity packages may specialize hook methods on it to preserve Tracker value and gradient handling. Application code must not construct this marker to select a sensitivity algorithm.
SciMLBase.MooncakeOriginator — Type
MooncakeOriginator()Zero-field ADOriginator marking a derivative initiated by Mooncake.
Developer Interface
Pass this marker to a concrete-solve hook only from a Mooncake-backed solve rule. Sensitivity packages may specialize hook methods on it to return Mooncake-compatible derivative data. Application code must not construct this marker to select a sensitivity algorithm.
SciMLBase.set_mooncakeoriginator_if_mooncake — Function
set_mooncakeoriginator_if_mooncake(originator::ADOriginator)Return the automatic-differentiation originator for a solver call, preserving originator in ordinary execution and switching to MooncakeOriginator() when Mooncake's overlay evaluates the call.
Developer API
Solver and sensitivity packages pass a concrete ADOriginator through their low-level solve path so AD rules can dispatch on its origin. End-user code should not call this function or dispatch on its result.
SciMLBase._concrete_solve_adjoint — Function
_concrete_solve_adjoint(prob, alg, sensealg, u0, p, originator, args...; kwargs...)Construct the reverse-mode derivative result for a solver call.
Arguments
prob: The problem being solved.alg: The selected solver algorithm, which may benothingwhen the caller uses a problem-stored default.sensealg: The selected sensitivity algorithm ornothingfor a package-defined default.u0: The effective initial state passed to the primal solve.p: The effective parameter value passed to the primal solve.originator: AnADOriginatoridentifying the outer AD system.args...: Remaining positional solve arguments.
Keyword Arguments
kwargs... are the solve keywords forwarded by the caller. Implementations must honor the applicable common solve keywords and preserve any values that affect the primal solution or derivative result.
Returns
A pair (primal, pullback). primal is the ordinary solve result and pullback is a callable compatible with the AD system identified by originator.
Developer Interface
Sensitivity packages extend this hook to implement reverse-mode solve derivatives. Methods must specialize on at least one problem type, solver/sensitivity algorithm, or originator type that the extending package owns. They must not mutate prob, u0, or p, must compute the same primal result as the corresponding solve call, and must return cotangents in the positional order expected by the originating AD rule. The fallback throws an informative error until a compatible sensitivity package has loaded.
SciMLBase._concrete_solve_forward — Function
_concrete_solve_forward(prob, alg, sensealg, u0, p, originator, args...; kwargs...)Construct the forward-mode derivative result for a solver call.
Arguments
prob: The problem being solved.alg: The selected solver algorithm, which may benothingwhen the caller uses a problem-stored default.sensealg: The selected sensitivity algorithm ornothingfor a package-defined default.u0: The effective initial state passed to the primal solve.p: The effective parameter value passed to the primal solve.originator: AnADOriginatoridentifying the outer AD system.args...: Remaining positional solve arguments.
Keyword Arguments
kwargs... are the solve keywords forwarded by the caller. Implementations must honor the applicable common solve keywords and preserve any values that affect the primal solution or tangent result.
Returns
A pair (primal, pushforward). primal is the ordinary solve result and pushforward is a callable compatible with the AD system identified by originator.
Developer Interface
Sensitivity packages extend this hook to implement forward-mode solve derivatives. Methods must specialize on at least one problem type, solver/sensitivity algorithm, or originator type that the extending package owns. They must not mutate prob, u0, or p, must compute the same primal result as the corresponding solve call, and must accept tangents in the positional order expected by the originating AD rule. The fallback throws an informative error until a compatible sensitivity package has loaded.
SensitivityADPassThrough
The special sensitivity algorithm SensitivityADPassThrough ignores the SciMLBase sensitivity dispatches and asks the AD backend to differentiate directly through the solver implementation. This is mostly an internal or advanced fallback. It requires the selected solver path to be compatible with the AD backend, and it will not use the specialized forward or adjoint rules that SciMLSensitivity.jl provides.
Note about ForwardDiff
ForwardDiff does not use ChainRules.jl and therefore ignores the ChainRules-based solve handling described above. Direct AD through solver internals may also require a pure Julia solver path and AD-compatible local operations.