Skip to content

Resize the member caches of a CompositeCache in a DDEIntegrator - #4958

Open
singhharsh1708 wants to merge 4 commits into
SciML:masterfrom
singhharsh1708:fix-4952
Open

singhharsh1708 wants to merge 4 commits into
SciML:masterfrom
singhharsh1708:fix-4952

Conversation

@singhharsh1708

@singhharsh1708 singhharsh1708 commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

DelayDiffEq only resized the Jacobian config of a RosenbrockMutableCache and fell through to a no-op for anything else, so a Rosenbrock member of a CompositeCache kept its old config. A DDEIntegrator method for CompositeCache now forwards to each member, as OrdinaryDiffEqCore does for ODEIntegrator.

Resizing a composite whose members use different AD backends then threw Cannot convert ... JacobianPrep, in ODE as well as DDE and already on master: resize_jac_config!, resize_grad_config! and resize_J_W! took the backend from alg_autodiff(integrator.alg), which for a composite is the last member's. They now take an alg argument (defaulting to integrator.alg) and the Rosenbrock and DDE resize methods pass each member's cache.alg. Fixing it in alg_autodiff(::CompositeAlgorithm) instead would change other consumers such as DAE initialization.

The repro in #4952 (MethodOfSteps(AutoTsit5(Rosenbrock23())), resized while on the stiff member) threw a DimensionMismatch and now returns Success at [0.5, 0.5]. New ODE and DDE testsets cover a FiniteDiff and a ForwardDiff Rosenbrock23, dense and with KrylovJL_GMRES, in both orders; they error without the src change and pass with it.

Not covered here: growing a composite with SDIRK members fails on master in resize_nlsolver!, and its Newton path still resizes with integrator.alg.

Fixes #4952

AI Disclosure: Claude assisted with this change.

@ChrisRackauckas

Copy link
Copy Markdown
Member

🤖 Automated comment from an AI agent running as @ChrisRackauckas — not written or reviewed by Chris.

PR: #4958

Reviewed head: d436d9c
Raw SHA-256: 73724c22dc6a78522de8c1ff56cbd22801ea276f44b60c04119db99932277541
Source SHA-256: 681965a75349d469ba5ce5146b7de0322b07ddc6f8b9c0fdbe25720fbe51c0d9
Source: standard-review-v1 (harness-log)
Reviewer session: 01a1d257-7f93-74e1-a6be-c01a65be15a9
Slot: 1
Confidence: unknown
Own risk fixed before author rating/discussion: yes

Risk assessment

  • Risk: medium (M1)
  • Verdict: CHANGES
  • Reviewed head: d436d9c

Review report

VERDICT: CHANGES
Round: 1
Head: d436d9c
Slot: 1
CI: CI is not green (regress:SciMLSensitivity.jl/Core4/1 / Downstream Tests - Core4)
Session: 01a1d257-7f93-74e1-a6be-c01a65be15a9

Risk

medium (M1: a new specialization of DiffEqBase.resize_non_user_cache! changes dispatch for existing composite DDE integrators).

Blocking findings

  • Verdict: CHANGES
  • Round: 1
  • Blocking priorities: P2
  • Deferred P2 issues: None.

[P2] Preserve each member's AD backend when resizing its cache — lib/DelayDiffEq/src/integrators/interface.jl:290. Confirmed by running: a composite containing finite-difference and ForwardDiff Rosenbrock23 members throws on even a same-size resize!(integ, 1), in either member order. The exception is MethodError: Cannot convert between ForwardDiffTwoArgJacobianPrep and FiniteDiffTwoArgJacobianPrep. With only the added method deleted at runtime, both otherwise identical cases finish with Success and state [0.49999999954711405].

The new loop passes the whole composite integrator to each cache's resize helper. Reading lib/OrdinaryDiffEqDifferentiation/src/derivative_wrappers.jl:337 and lib/OrdinaryDiffEqDifferentiation/src/alg_utils.jl:7 explains the observed failure: the helper selects the final algorithm's backend for every member. Rebuild configurations with the corresponding member's backend, and add a regression covering heterogeneous backends and same-size resizing.

Runnable reproduction in the resolved test environment:

using DelayDiffEq, OrdinaryDiffEqRosenbrock
using OrdinaryDiffEqCore: CompositeAlgorithm
using ADTypes: AutoFiniteDiff
f!(du, u, h, p, t) = (du .= -1000 .* (u .- 0.5); nothing)
prob = DDEProblem(f!, [1.0], (p, t) -> [0.5], (0.0, 0.1);
    constant_lags = [1.0])
alg = CompositeAlgorithm((Rosenbrock23(autodiff = AutoFiniteDiff()),
    Rosenbrock23()), _ -> 1)
integ = init(prob, MethodOfSteps(alg))
step!(integ)
resize!(integ, 1) # MethodError on this head

Non-blocking findings

None established.

What I ran

  • AI reviewer: codex-cli 0.164.0, model gpt-6.1-sol; session identified above. Blind code review; no PR body, comments, reviews, or author risk rating read.
  • git diff origin/master...HEAD, git diff --check origin/master...HEAD, repository instruction discovery, public cache API and resize-helper inspection. Diff check passed; no root AGENTS.md or CLAUDE.md was present. The newest commit has neither Agent-Harness nor Agent-Model trailers.
  • julia --version: 1.13.2. Scratch test environment uses the package's declared dependencies, extras, compat bounds and local monorepo sources; original layered JULIA_DEPOT_PATH preserved. Resolved DelayDiffEq 6.4.7, OrdinaryDiffEqCore 4.20.0, OrdinaryDiffEqDifferentiation 3.13.0, DiffEqBase 7.21.5, SciMLBase 3.58.0, LinearSolve 5.18.3, ForwardDiff 1.4.7.
  • julia --startup-file=no setup.jl: dependency resolution passed. Targeted Pkg.precompile(...): 27 dependencies successfully precompiled; 231 already precompiled.
  • Fresh-process julia --startup-file=no --check-bounds=yes --project=testenv mixed_regression.jl: two same-size head cases failed as described; removing only the new method made both controls succeed. No source file was changed for this control.
  • julia --startup-file=no --check-bounds=yes --project=testenv run_review.jl: the official GROUP=Integrators entrypoint passed 383 assertions, with 36 existing broken assertions (SDIRK); no failures or errors in that group. The added regression passed 2/2. Deleting only the added method made that same regression error with DimensionMismatch: ... OneTo(1) and ... OneTo(2).
  • Initial adversarial batch: 66 passed, 2 failed, 6 errored. Two errors reproduce the blocking mixed-backend bug. Four errors concern ForwardDiff chunk size 3 after shrinking to 2; their baseline status was not verified. The two failed assertions assumed AutoSwitch would remain on member 2; that probe assumption was invalid, and both analytic-solution checks passed. The optional deterministic-member follow-up was not run.
  • Isolated main-case probe passed: the stiff member was reached after 21 steps at t=0.05768237953913356; growth to 2 followed by solve! returned Success, t=3.0, state [0.5000000000000001, 0.5].
  • Final git status --short and git diff --exit-code: checkout unchanged. No commits, pushes, or GitHub posts.
  • uv run --locked python --version: Python 3.15.0; uv warned that --locked has no effect outside a project. This Julia checkout has no supplied Python project/uv lock environment. No tracked Julia interpreter/Manifest lock was present either; the scratch environment was resolved from the package constraints.

What I did not verify

  • Whether the four shrinking/deletion errors with ForwardDiff chunk size 3 are pre-existing; direct-solver/baseline controls were not run. The optional deterministic-member delayed-solution follow-up also did not start: its idle resource queue was interrupted after the required suite and probes completed. These are not additional confirmed PR regressions.
  • Supplied SciMLSensitivity/Core4 CI failure, other Julia versions, full monorepo/downstream suites, QA and documentation builds.

AUTHOR_GRADE: {"task": "bugfix", "score": 3, "difficulty": 2, "rounds": 1, "author_harness": "unknown", "author_model": "unknown", "note": "The original bug has failing-before/passing-after evidence and the affected group passes. A targeted head/control comparison confirms a newly introduced mixed-AD-backend regression even for same-size resizing."}

Head link: d436d9c


🤖 Posted by an AI agent — harness: codex-cli 0.164.0 · model: gpt-6.1-sol
Conversation: local session 01a1d257-7f93-74e1-a6be-c01a65be15a9 (no session URL)

This branch has not been deployed

No deployments
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.

DelayDiffEq resize! does not resize the Rosenbrock Jacobian config inside a CompositeAlgorithm

2 participants