Thread ForwardDiff chunk size through FunctionWrapper compilation#1287
Merged
ChrisRackauckas merged 2 commits intoSciML:masterfrom Feb 22, 2026
Merged
Conversation
Use the new `SciMLBase.forwarddiff_chunksize` trait to compile FunctionWrapper variants with the algorithm's actual chunk size instead of hardcoding chunk=1. Changes: - Add `_forwarddiff_chunksize` helper in solve.jl - Thread `Val(CS)` through `get_concrete_problem` → `promote_f` → `wrapfun_iip` - Add parameterized `dualgen(T, Val(CS))` in ForwardDiff extension - Add 3-arg `wrapfun_iip(ff, inputs, Val(CS))` in ForwardDiff extension - Add 3-arg fallback `wrapfun_iip(ff, inputs, ::Val)` in norecompile.jl This fixes NoFunctionWrapperFoundError when algorithms specify a non-default chunk size (e.g. AutoForwardDiff(chunksize=3)) on mass matrix problems. Requires SciMLBase >= 2.143.0. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
2 tasks
…ranching
Now that SciMLBase.forwarddiff_chunksize returns Val{N}(), dispatch on
it directly via _resolve_chunksize(::Val{0}) = Val(1) instead of runtime
Int comparison. Removes Val() wrapping at call sites since
_forwarddiff_chunksize already returns Val.
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Contributor
Author
|
Updated to dispatch on Now that _forwarddiff_chunksize(::Nothing) = Val(1)
_forwarddiff_chunksize(alg) = _resolve_chunksize(SciMLBase.forwarddiff_chunksize(alg))
_resolve_chunksize(::Val{0}) = Val(1)
_resolve_chunksize(v::Val) = vNo runtime |
Member
|
locally handled. |
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.
Summary
_forwarddiff_chunksizehelper to read the newSciMLBase.forwarddiff_chunksizetraitVal(CS)throughget_concrete_problem→promote_f→wrapfun_iipfor both ODE and DAE problemsdualgen(T, Val(CS))in the ForwardDiff extensionwrapfun_iip(ff, inputs, Val(CS))that compiles FunctionWrapper variants with chunk=CS for u-related duals (Jacobian) and chunk=1 for t-related duals (time derivative)wrapfun_iip(ff, inputs, ::Val)in norecompile.jl for when ForwardDiff extension isn't loadedContext
DiffEqBase PR #1284 enabled FunctionWrapper wrapping for mass matrix ODEProblems. The FunctionWrapper variants were compiled with
Dual{..., 1}(chunk=1 hardcoded indualgen). When algorithms use a different chunk size (e.g.AutoForwardDiff(chunksize=3)), the solver createsDual{..., 3}values but the wrapper only hasDual{..., 1}variants, causingNoFunctionWrapperFoundError.The key insight is that u-related duals (Jacobian computation) use the algorithm's chunk size, while t-related duals (time derivative) always use chunk=1 since it's scalar differentiation. The 3-arg
wrapfun_iiphandles this by creating variants with different chunk sizes for the u-derivative vs t-derivative paths.Depends on: SciML/SciMLBase.jl#1244
Test plan
Val(1)default preserves existing behavior when trait returns 0🤖 Generated with Claude Code