From 51faba41dceac353bdeb89e33f922db42be2cbd9 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sun, 17 May 2026 19:38:19 -0400 Subject: [PATCH 1/3] Fix downstream test breakages exposed by OrdinaryDiffEq 7 bump The compat bump in the previous commit gets `activate_downstream_env` past `Pkg.develop`, but the downstream test sources still don't run because the OrdinaryDiffEq 7 resolution was previously masking three issues: - `Rosenbrock23(autodiff = false)` is no longer supported; OrdinaryDiffEq 7 rejects the `Bool` form and asks for an `ADType`. Use `AutoFiniteDiff()` (already reachable through `using OrdinaryDiffEq`). - `Rodas5` is no longer re-exported from `OrdinaryDiffEq`; pull it in via `using OrdinaryDiffEqRosenbrock` and add the package as a dep. - `AP[...]` shorthand requires `RecursiveArrayToolsShorthandConstructors` in scope; runtests.jl `Pkg.develop`s the package but never `using`-s it, so the downstream test files silently never had it. - `SciMLBase.successful_retcode(...)` requires `SciMLBase` as a bare binding, which `using OrdinaryDiffEq` doesn't provide. Switch to the unqualified `successful_retcode` (also already exported through OrdinaryDiffEq), avoiding the need to add SciMLBase as a direct dep. Verified locally that the ODE Solve / Events / Measurements and Units / TrackerExt safetestsets all run to completion after the fix. Co-Authored-By: Chris Rackauckas --- test/downstream/Project.toml | 3 +++ test/downstream/downstream_events.jl | 2 +- test/downstream/odesolve.jl | 7 ++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/test/downstream/Project.toml b/test/downstream/Project.toml index 3ed72f06..ad7277e8 100644 --- a/test/downstream/Project.toml +++ b/test/downstream/Project.toml @@ -4,7 +4,9 @@ ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +OrdinaryDiffEqRosenbrock = "43230ef6-c299-4910-a778-202eb28ce4ce" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" +RecursiveArrayToolsShorthandConstructors = "39fb7555-b4ad-4efd-8abe-30331df017d3" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" SymbolicIndexingInterface = "2efcf032-c050-4f8e-a9bb-153293bab1f5" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" @@ -18,6 +20,7 @@ ModelingToolkit = "8.33, 9, 10, 11" MonteCarloMeasurements = "1.1" NLsolve = "4" OrdinaryDiffEq = "6.31, 7" +OrdinaryDiffEqRosenbrock = "1, 2" StaticArrays = "1" SymbolicIndexingInterface = "0.3" Tables = "1" diff --git a/test/downstream/downstream_events.jl b/test/downstream/downstream_events.jl index 230dcbb0..2118cbc7 100644 --- a/test/downstream/downstream_events.jl +++ b/test/downstream/downstream_events.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, StaticArrays, RecursiveArrayTools +using OrdinaryDiffEq, StaticArrays, RecursiveArrayTools, RecursiveArrayToolsShorthandConstructors u0 = AP[SVector{1}(50.0), SVector{1}(0.0)] tspan = (0.0, 15.0) diff --git a/test/downstream/odesolve.jl b/test/downstream/odesolve.jl index 2ca163ab..5fe162d8 100644 --- a/test/downstream/odesolve.jl +++ b/test/downstream/odesolve.jl @@ -1,4 +1,5 @@ -using OrdinaryDiffEq, NLsolve, RecursiveArrayTools, Test, ArrayInterface, StaticArrays +using OrdinaryDiffEq, OrdinaryDiffEqRosenbrock, NLsolve, RecursiveArrayTools, + RecursiveArrayToolsShorthandConstructors, Test, ArrayInterface, StaticArrays function lorenz(du, u, p, t) du[1] = 10.0 * (u[2] - u[1]) du[2] = u[1] * (28.0 - u[3]) - u[2] @@ -9,7 +10,7 @@ u0 = AP[[1.0, 0.0], [0.0]] tspan = (0.0, 100.0) prob = ODEProblem(lorenz, u0, tspan) sol = solve(prob, Tsit5()) -sol = solve(prob, AutoTsit5(Rosenbrock23(autodiff = false))) +sol = solve(prob, AutoTsit5(Rosenbrock23(autodiff = AutoFiniteDiff()))) sol = solve(prob, AutoTsit5(Rosenbrock23())) @test all(Array(sol) .== sol) @@ -72,4 +73,4 @@ end u = fill(SVector{2}(ones(2)), 2, 3) ode = ODEProblem(rhs!, VectorOfArray(u), (0.0, 1.0)) sol = solve(ode, Tsit5()) -@test SciMLBase.successful_retcode(sol) +@test successful_retcode(sol) From 2c2e5ec93d42cba074ec053a54104a98a8c0a68e Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sun, 17 May 2026 20:30:40 -0400 Subject: [PATCH 2/3] Use unknowns(lv) to derive Tables interface names in symbol_indexing test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MTK 11 reorders ODESystem unknowns ([y, x] in this case, not [x, y]), so the hardcoded propertynames in the test/downstream/symbol_indexing.jl Tables interface check no longer match what `propertynames(row)` and `Tables.columnnames(row)` return on the solution rows. The data columns in `Array(sol_ts)'` already follow MTK's unknowns ordering, so deriving the names list from `unknowns(lv)` keeps names and data in sync and is robust to future MTK reorderings. Restores 357/358 assertions in the `DiffEqArray Indexing Tests` testset on Julia 1/lts/pre. The remaining 1-test error is in the array-symbolic indexing test at line 103 (`sol[x .+ [y, 2y, 3y]] ≈ ...`) — passes standalone, errors only inside `@safetestset`'s isolated module; this looks like a separate Symbolics/SII module-isolation interaction that needs its own investigation. Co-Authored-By: Chris Rackauckas --- test/downstream/symbol_indexing.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/downstream/symbol_indexing.jl b/test/downstream/symbol_indexing.jl index b420d80c..3cbae750 100644 --- a/test/downstream/symbol_indexing.jl +++ b/test/downstream/symbol_indexing.jl @@ -77,7 +77,7 @@ ts = 0:0.5:10 sol_ts = sol(ts) @assert sol_ts isa DiffEqArray test_tables_interface( - sol_ts, [:timestamp, Symbol("x(t)"), Symbol("y(t)")], + sol_ts, [:timestamp; Symbol.(string.(unknowns(lv)))], hcat(ts, Array(sol_ts)') ) From 39c37089ca3f97c9e6746e4a8fc0f4a0f81d00cb Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sun, 17 May 2026 21:20:07 -0400 Subject: [PATCH 3/3] Route `A[sym, :]` through `A[sym]` for symbolic indices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `sol[arr_sym, :]` should be equivalent to `sol[arr_sym]` — both ask for the full timeseries of the symbolic indices. Currently the `:`-suffixed form errors with a broadcast shape mismatch inside SII's `GetStateIndex` when the underlying index resolves to a `Vector{Int}` (i.e. when the symbol is array-valued like `x(t)[1:3]`): DimensionMismatch: arrays could not be broadcast to a common size: a has axes Base.OneTo(N) and b has axes Base.OneTo(K) (SII's `(gsi::GetStateIndex)(::Timeseries, prob, i)` broadcasts `gsi.idx` against `state_values(prob, i)` without wrapping it in a 1-tuple, so a length-N timeseries broadcast against a length-K idx vector errors. A companion fix is being submitted upstream.) Short-circuiting `A[sym, :]` to `A[sym]` here both restores the intended semantics and avoids the broken SII codepath. Co-Authored-By: Chris Rackauckas --- src/vector_of_array.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index 191a5eb2..3db5b8ca 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -797,6 +797,15 @@ Base.@propagate_inbounds function Base.getindex(A::AbstractVectorOfArray, _arg, end symtype = symbolic_type(_arg) elsymtype = symbolic_type(eltype(_arg)) + # For symbolic indices, `A[sym, :]` is semantically equivalent to `A[sym]` + # (the no-args symbolic getindex already returns the full timeseries). + # Routing through the no-args path here also avoids a broadcast shape bug + # in SymbolicIndexingInterface's `GetStateIndex` when the underlying index + # is a `Vector{Int}` (array-symbolic) combined with a `Colon` time index. + if (symtype != NotSymbolic() || elsymtype != NotSymbolic()) && + length(args) == 1 && args[1] === Colon() + return A[_arg] + end return if symtype == NotSymbolic() && elsymtype == NotSymbolic() if _arg isa Union{Tuple, AbstractArray} &&