You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add integrand_inplace option to IntegratingSumCallback/IntegratingGKSumCallback (#313)
The integrating sum callbacks chose the integrand calling convention from the
problem's in-placeness: out-of-place problems always used the allocating
3-arg `integrand_func(u, t, integrator)` form, even when an
`integrand_prototype` was supplied. But the integrand output is often
parameter-shaped (e.g. the dG/dp quadrature in adjoint methods), so it can be
a mutable buffer even when the state is immutable (e.g. SVector) — and the
allocating form then forces an output allocation on every quadrature node of
every step.
Add an `integrand_inplace::Union{Nothing, Bool} = nothing` keyword:
- `nothing` (default) keeps the existing behavior (in-place form for
in-place problems with a prototype, allocating form otherwise),
- `true` forces the in-place 4-arg form into `integrand_cache` regardless
of problem in-placeness (requires an `integrand_prototype`),
- `false` forces the allocating form.
Benchmark (OOP SVector ODE, 10 states, cheap 100-element integrand,
Tsit5 over [0, 10], abstol=reltol=1e-10, full solve):
- allocating 3-arg integrand: 196.8 μs (865 allocations: 380.70 KiB)
- in-place 4-arg integrand: 123.3 μs (253 allocations: 103.38 KiB)
For expensive integrands (e.g. AD-based vjps) the difference is negligible
since the integrand itself dominates.
Motivated by SciML/SciMLSensitivity.jl#1479 (GaussAdjoint on immutable
SVector state), which currently has to use the allocating form for immutable
state.
Co-authored-by: Chris Rackauckas (Claude) <accounts@chrisrackauckas.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
0 commit comments