Skip to content

Add dynamic parameter despecialization for all SciML functions - #1511

Merged
ChrisRackauckas merged 8 commits into
SciML:masterfrom
ChrisRackauckas-Claude:agent/despecialized-parameters
Aug 10, 2026
Merged

Add dynamic parameter despecialization for all SciML functions#1511
ChrisRackauckas merged 8 commits into
SciML:masterfrom
ChrisRackauckas-Claude:agent/despecialized-parameters

Conversation

@ChrisRackauckas-Claude

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Aug 10, 2026

Copy link
Copy Markdown
Member

Ignore this draft until it has been reviewed by @ChrisRackauckas.

What changed and why

Adds the public DespecializedParameters container and a shared dynamic function barrier. Its params::Any field gives solver-facing code one stable parameter type; invoke_with_despecialized_parameters unwraps immediately before the concrete model call, containing inference loss at that boundary.

The barrier is applied to every callable built-in SciMLFunction family: ODE, nonlinear and interval nonlinear, homotopy nonlinear, integral and batched integral, discrete and implicit discrete, DAE, DDE and SDDE, SDE and RODE, ODE input, optimization and multi-objective optimization, BVP and dynamical BVP, plus split, dynamical, and incrementing variants. FunctionWrappersWrapper keeps receiving the stable outer parameter type so its fixed signature remains valid.

The wrapper forwards common collection operations, SciMLStructures, SymbolicIndexingInterface, ArrayInterface, and Adapt. unwrap_parameters gives AD and transformation code a public opt-out hook. specialization now has instance and type-level queries so modeling packages can choose this behavior without inspecting concrete type-parameter positions.

This is distinct from AutoRespecialize: DespecializedParameters supports arbitrary dynamic parameter objects at the cost of one dispatch barrier, while AutoRespecialize lets supporting solvers recover a concrete parameter type without dynamic dispatch but has solver-specific packing, symbolic-indexing, and differentiation constraints.

This PR is stacked on the rename/API clarification in #1510. ModelingToolkit integration is SciML/ModelingToolkit.jl#4919.

Failing before / passing after

Against the prerequisite branch before DespecializedParameters exists, the exact new test file errors immediately:

julia +release --project=/path/to/rename-branch --startup-file=no -e 'using SciMLBase; include("/path/to/despecialized-branch/test/despecialized_parameters.jl")'
ERROR: LoadError: Some tests did not pass: 0 passed, 0 failed, 1 errored, 0 broken.
UndefVarError: `DespecializedParameters` not defined in `SciMLBase`

The all-family barrier discriminator was also run on commit ebe2bbffd08b660e98f4e6636c83853a9d38e8bf, before the shared SciMLFunction call methods. NonlinearFunction delivered SciMLBase.DespecializedParameters to the user function instead of the concrete wrapped parameter type and failed. With the barrier commit applied, the same discriminator printed nonlinear barrier: pass.

On current HEAD, the complete focused test passes:

julia +release --project=. --startup-file=no -e 'using SciMLBase; include("test/despecialized_parameters.jl")'
Test Summary:                          | Pass  Total
all callable SciMLFunction families    |    4      4
stable container and forwarded interfaces | 28     28
dynamic function barrier               |    7      7

The first test executes 21 callable SciMLFunction containers and verifies that every user function sees the concrete wrapped parameter type.

julia +release --project=. --startup-file=no -e 'using SciMLBase, Test; @show length(Test.detect_ambiguities(SciMLBase))'
length(Test.detect_ambiguities(SciMLBase)) = 0

Runic, typos over the diff, and git diff --check all exit 0.

Additional verification

GROUP=Core julia +release --project=. -e 'using Pkg; Pkg.test()'
Remake | 4430/4430
Testing SciMLBase tests passed

GROUP=QA julia +release --project=. -e 'using Pkg; Pkg.test()'
QA | 51/51
Testing SciMLBase tests passed

The focused ModelingToolkitBase ForwardDiff/Zygote/SciMLSensitivity test passes 2/2 in 5m37.1s. The exact docs build reaches document expansion and then exits only because the pre-existing Problem_Traits link returns HTTP 403; clean upstream/master reproduces the same sixteen link-check failures.

Still running / not yet verified

  • Full ModelingToolkit feature-group rerun
  • A clean docs exit; current upstream/master is blocked by the independently reproduced external HTTP 403
  • Final compile-time and runtime benchmark reruns

The draft was pushed before those long validations completed at the explicit request of @ChrisRackauckas. Results will be added from actual runs.

No dependency was added or newly enabled.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Follow-up commit ChrisRackauckas-Claude@e03cee0 expands the dynamic barrier beyond ODEFunction.

What changed:

  • All callable built-in SciMLFunction containers now route DespecializedParameters through the shared function barrier, including nonlinear, discrete/implicit, DAE, DDE/SDDE, SDE/RODE, ODE-with-input, optimization/multi-objective, BVP, integral/batched integral, split, dynamical, and incrementing forms.
  • The tuple-based developer interface discovers the parameter position from the argument types, so each different call signature does not duplicate barrier logic.
  • FunctionWrappersWrapper calls retain the stable outer parameter object.
  • anyeltypedual now inspects the wrapped value, and SymbolicIndexingInterface forwarding ambiguities are resolved.

Discriminator on the preceding commit ebe2bbf:

Test Failed at none:1
  Expression: seen[] === P
   Evaluated: SciMLBase.DespecializedParameters === P

The identical NonlinearFunction probe on e03cee0 passes and prints:

nonlinear barrier: pass

Focused verification on e03cee0:

Test Summary: all callable SciMLFunction families | 2 pass
Test Summary: stable container and forwarded interfaces | 28 pass
Test Summary: dynamic function barrier | 7 pass
Test.detect_ambiguities(SciMLBase): ambiguities=0

Whole-repository Runic check, typos --diff, and git diff --check exit 0. Full Core, QA, and docs reruns for this follow-up are in progress; this remains a draft and should be ignored until reviewed by @ChrisRackauckas.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Follow-up commit ChrisRackauckas-Claude@4da04dc adds the type-level specialization query needed by ModelingToolkit problem construction.

SciMLBase.specialization now accepts both a SciMLFunction instance and its type/partially applied constructor. Specialization-bearing function families report their marker; function families without that marker, including OptimizationFunction, report FullSpecialize rather than treating their unrelated second type parameter as a specialization mode.

Focused verification:

specialization type trait: pass
Test Summary: all callable SciMLFunction families | 4 pass
Test Summary: stable container and forwarded interfaces | 28 pass
Test Summary: dynamic function barrier | 7 pass
Test.detect_ambiguities(SciMLBase): ambiguities=0

Whole-repository Runic check, typos --diff, and git diff --check exit 0. Full group reruns will be restarted on this latest commit after the active earlier snapshot runs finish.

@ChrisRackauckas-Claude ChrisRackauckas-Claude changed the title Add dynamic parameter despecialization Add dynamic parameter despecialization for all SciML functions Aug 10, 2026
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Full Core exposed an OptimizationFunction remake regression in the type-trait expansion: the existing instance-level specialization(::OptimizationFunction) behavior is used internally to preserve its AD type. Commit ff9495abf restores that compatibility while retaining the new type-level fallback used by MTK. The exact failing operation now passes (OptimizationFunction remake: pass). Current-head QA passes 51/51, and the despecialization tests passed 39/39 in the Core run. A fresh full Core rerun is required because the first run had loaded the pre-fix source.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Fresh current-head validation is now green: GROUP=Core exits 0 with the despecialized-parameter tests 39/39, problem-building tests 125/125, and Remake 4430/4430; GROUP=QA exits 0 with 51/51. The prior OptimizationFunction remake regression is therefore cleared by ff9495abf in the full discriminator, not only the focused smoke.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Clean-base docs comparison is now complete.

The exact docs build on clean upstream/master also exits 1 solely at link checking: the pre-existing https://docs.sciml.ai/SciMLBase/stable/interfaces/Problem_Traits/ target returned HTTP 403 sixteen times after doctests/template expansion. This branch reaches the same boundary and introduces no new docs/reference error. A separate clean-master investigation is being queued per repository policy.

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Downstream AD validation is now green against the current feature stack:

despecialized parameter sensitivities | 2/2 | 5m37.1s
focused despecialized AD: pass

The test uses ForwardDiff, Zygote, SciMLSensitivity, SciMLStructures, and ModelingToolkitBase, and exercises the public unwrap_parameters reconstruction path.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

The new OrdinaryDiffEq Rosenbrock precompile workload exposed and now discriminates an AD-discovery ambiguity.

Failing before commit 3984a6491:

using OrdinaryDiffEqRosenbrock
ERROR: MethodError: anyeltypedual(::SciMLBase.DespecializedParameters, ::Type{Val{0}}) is ambiguous
Candidates:
  anyeltypedual(x::DespecializedParameters, counter)
  anyeltypedual(x, ::Type{Val{counter}}) where counter

Passing after adding the specific Type{Val{N}} forwarding method and regression assertion:

Val anyeltypedual forwarding: pass
OrdinaryDiffEqRosenbrock | precompiled in 42.8s
Rosenbrock despecialized precompile: pass

Despecialized parameters | 40/40
Remake | 4430/4430
Testing SciMLBase tests passed

QA | 51/51
Testing SciMLBase tests passed

Runic, diff check, and typos over the diff also exit 0. Commit: ChrisRackauckas-Claude@3984a6491

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

The dedicated clean-master docs audit is complete. Existing #1485 is the correct focused fix: clean current master failed with sixteen HTTP 403 link errors and [:linkcheck]; replaying that PR made the same strict docs command exit 0 through HTML rendering. The failure was bisected to 6807f7f. No duplicate issue or PR was opened.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member Author

Expanded the common barrier to DynamicalSDEFunction in commit ChrisRackauckas-Claude@215d13e2a.

Failing before:

MethodError: objects of type DynamicalSDEFunction{...} are not callable

Passing after:

f(u, p, 0.0) = ArrayPartition(([4.0], [2.0]))
DynamicalSDE despecialized call: pass

Final local validation after the change:

Despecialized parameters | 40 / 40
Problem building tests    | 125 / 125
Remake                    | 4430 / 4430
Testing SciMLBase tests passed

QA | 51 / 51
Testing SciMLBase tests passed

Runic, typos over the diff, and git diff --check pass.

@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review August 10, 2026 12:48
@ChrisRackauckas
ChrisRackauckas merged commit a932b02 into SciML:master Aug 10, 2026
27 of 48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants