Skip to content

Move DEVerbosity and default verbosity to DiffEqBase#3365

Closed
jClugstor wants to merge 8 commits into
SciML:masterfrom
jClugstor:move_verbosity
Closed

Move DEVerbosity and default verbosity to DiffEqBase#3365
jClugstor wants to merge 8 commits into
SciML:masterfrom
jClugstor:move_verbosity

Conversation

@jClugstor
Copy link
Copy Markdown
Member

Checklist

  • Appropriate tests were added
  • Any code changes were done in a way that does not break public API
  • All documentation related to code changes were updated
  • The new code follows the
    contributor guidelines, in particular the SciML Style Guide and
    COLPRAC.
  • Any new documentation only uses public API

Additional context

Add any other context about the problem here.

@ChrisRackauckas
Copy link
Copy Markdown
Member

This needs Project.toml bumps to be safe.

@jClugstor
Copy link
Copy Markdown
Member Author

Yes will do.

The idea here is to move DEVerbosity to DiffEqBase, so that solvers that depend on just DiffEqBase rather than OrdinaryDiffEqCore can use DEVerbosity. Also, by having the default verbose be SciMLLogging.Standard, we can make it so that packages that have their own verbosity specifiers can use those, e.g. BVPDiffEq. It just means that packages will have to do some processing of the verbose kwarg

I'm working on the Sundials and ODEInterfaceDiffEq PRs now.

@jClugstor jClugstor marked this pull request as ready for review April 10, 2026 13:16
@jClugstor
Copy link
Copy Markdown
Member Author

@jClugstor
Copy link
Copy Markdown
Member Author

@ChrisRackauckas this actually would break Sundials and ODEInterfaceDiffEq, since it changes the default verbose kwarg to be a SciMLLogging preset.

I can try to do something different or find a workaround, or we can just put this in the breaking release?

@devmotion
Copy link
Copy Markdown
Member

this actually would break Sundials and ODEInterfaceDiffEq

Aren't they already broken? The existing SciMLLogging changes already broke them for me: #3351 (comment)

@jClugstor
Copy link
Copy Markdown
Member Author

Sundials still works with a Bool verbose, right? There's no code that was working before that isn't working now, unless I misunderstood the issue.

I mean that releasing this under a nonbreaking change would make code that uses Sundials with the default verbosity setting break.

@devmotion
Copy link
Copy Markdown
Member

The current mix of SciMLogging changes and package releases makes it impossible to have a generic function call of solve with fixed verbose keyword argument that works with arbitrary ODE solvers - either type inference is broken when using (not officially but seemingly inofficially deprecated) verbose = false or the call errors completely for Sundials solvers when using verbose = SciMLLogging.None(). As the latter seems to be the future API, I attributed the breakage to Sundials, but clearly that's not completely correct - maybe it would be more accurate that the SciMLLogging/verbosity stack is broken.

Another question is also: will this be fixed in OrdinaryDiffEq < v7? Or will SciMLLogging continue to being broken on pre-v7 releases?

@ChrisRackauckas
Copy link
Copy Markdown
Member

All solvers will be supporting SciMLLogging and that should have perfectly fine inference, that's what this change is doing, and this either lands pre-v7 or gets backported. I'm hoping it just lands pre-v7 since backports will be a bit of a PITA

@ChrisRackauckas
Copy link
Copy Markdown
Member

Explicit Imports Tests: Error During Test at /home/runner/work/OrdinaryDiffEq.jl/OrdinaryDiffEq.jl/lib/DelayDiffEq/test/qa/qa_tests.jl:37
  Test threw exception
  Expression: check_all_qualified_accesses_via_owners(DelayDiffEq) === nothing
  QualifiedAccessesFromNonOwnerException
  Module `DelayDiffEq` has qualified accesses to names via modules other than their owner as determined via `Base.which`:
  - `DEVerbosity` has owner `DiffEqBase` but it was accessed from `OrdinaryDiffEqCore` at `/home/runner/work/OrdinaryDiffEq.jl/OrdinaryDiffEq.jl/lib/DelayDiffEq/src/solve.jl:282:32`
  
  Stacktrace:
   [1] check_all_qualified_accesses_via_owners(mod::Module, file::String; ignore::Tuple{}, skip::Tuple{Pair{Module, Module}, Pair{Module, Module}, Pair{Module, Module}}, require_submodule_access::Bool, allow_internal_accesses::Bool, throw::Bool, file_analysis::Dict{Any, Any})
     @ ExplicitImports ~/.julia/packages/ExplicitImports/sATsO/src/checks.jl:380
   [2] check_all_qualified_accesses_via_owners(mod::Module, file::String)
     @ ExplicitImports ~/.julia/packages/ExplicitImports/sATsO/src/checks.jl:345
   [3] top-level scope
     @ ~/work/OrdinaryDiffEq.jl/OrdinaryDiffEq.jl/lib/DelayDiffEq/test/qa/qa_tests.jl:32
   [4] macro expansion
     @ /opt/hostedtoolcache/julia/1.12.6/x64/share/julia/stdlib/v1.12/Test/src/Test.jl:1777 [inlined]
   [5] macro expansion
     @ ~/work/OrdinaryDiffEq.jl/OrdinaryDiffEq.jl/lib/DelayDiffEq/test/qa/qa_tests.jl:37 [inlined]
   [6] macro expansion
     @ /opt/hostedtoolcache/julia/1.12.6/x64/share/julia/stdlib/v1.12/Test/src/Test.jl:677 [inlined]
Failed to precompile Sundials [c3572dad-4567-51f8-b174-8c6c989267f4] to "/home/chrisrackauckas/github-runners/deepsea3-3/.julia/compiled/v1.12/Sundials/jl_C5LRGR".
ERROR: LoadError: TypeError: non-boolean (SciMLLogging.Standard) used in boolean context
Stacktrace:

These needs to get addressed before merging.

@ChrisRackauckas
Copy link
Copy Markdown
Member

@jClugstor you forgot DASSL.jl, IRKGaussLegendre.jl, DASKR.jl, ...

Comment thread lib/DelayDiffEq/src/solve.jl
@jClugstor
Copy link
Copy Markdown
Member Author

IKRGaussLegendre:
SciML/IRKGaussLegendre.jl#110

DASSL:
SciML/DASSL.jl#84

DASKR:
SciML/DASKR.jl#88

@ChrisRackauckas
Copy link
Copy Markdown
Member

Failed to precompile Sundials [c3572dad-4567-51f8-b174-8c6c989267f4] to "/home/chrisrackauckas/github-runners/deepsea3-61/.julia/compiled/v1.12/Sundials/jl_Z6TWEf".
ERROR: LoadError: TypeError: non-boolean (SciMLLogging.Standard) used in boolean context
Stacktrace:
  [1] __init(prob::SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, SciMLBase.NullParameters, Float64}}}, FunctionWrappersWrappers.AllowNonIsBits, FunctionWrappersWrappers.SingleCacheStorage}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing, Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardODEProblem}, alg::Sundials.ARKODE{:Newton, :Dense, :Dense, Sundials.Implicit, Nothing, Nothing, Nothing, Nothing}, timeseries::Vector{Any}, ts::Vector{Any}, ks::Vector{Any}; verbose::SciMLLogging.Standard, callback::Nothing, abstol::Float64, reltol::Float64, saveat::Vector{Float64}, tstops::Vector{Float64}, d_discontinuities::Vector{Float64}, maxiters::Int64, dt::Nothing, dtmin::Float64, dtmax::Float64, timeseries_errors::Bool, dense_errors::Bool, save_everystep::Bool, save_idxs::Nothing, dense::Bool, save_on::Bool, save_start::Bool, save_end::Bool, save_timeseries::Nothing, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), progress_id::Symbol, advance_to_tstop::Bool, stop_at_next_tstop::Bool, userdata::Nothing, alias_u0::Bool, initializealg::DiffEqBase.DefaultInit, kwargs::@Kwargs{})
    @ Sundials ~/github-runners/deepsea3-61/.julia/packages/Sundials/i6ZUz/src/common_interface/solve.jl:518

@jClugstor
Copy link
Copy Markdown
Member Author

Right that's the breaking part from changing the default.
I can keep backwards compatibility by keeping the default verbose in DiffEqBase solve as true.
I tested that a call to solve with the default verbose kwarg still be inferred if I change it back.

That should fix the backwards compatibility. I'll also try to see if I can fix the inference for explicit Bool verbose, since I'm pretty sure that was working at some point.

ChrisRackauckas-Claude pushed a commit to ChrisRackauckas-Claude/OrdinaryDiffEq.jl that referenced this pull request Apr 15, 2026
`DEFAULT_VERBOSE` and `NONE_VERBOSE` are different concrete
parameterizations of `DEVerbosity{...}`, so the ternary
`verbose ? DEFAULT_VERBOSE : NONE_VERBOSE` returns a `Union{...}` whenever
`verbose::Bool` isn't a compile-time constant. That `Union` propagates
into solver caches (e.g. baked into `LinearCache` via `LinearVerbosity`)
and breaks return-type inference of `solve`.

Annotate the `Bool` method with `Base.@constprop :aggressive` so the
literal `solve(...; verbose=true/false)` path collapses to a single
concrete type. Add `Val{true}`/`Val{false}` overloads as an explicit
type-stable entry point for callers that want to force inference
without relying on constprop.

Also add `[sources.DiffEqBase]` to `OrdinaryDiffEqMultirate/Project.toml`
so Pkg can pin the local `DiffEqBase 6.217` alongside the other sublibs
during its tests — otherwise the resolver only sees the registered
`6.216` which violates `OrdinaryDiffEqCore 3.32`'s new `DiffEqBase ≥
6.217` compat and the test environment fails to instantiate.

Note: the deeper inference fix (Bool default flowing through multi-layer
kwargs splatting) is not solved here; `@inferred solve(...)` still fails
for the same reason it fails on SciML#3365's base. Changing the default to
`verbose = DEFAULT_VERBOSE` would fix it but breaks downstream solvers
like Sundials that still expect a `Bool`.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas
Copy link
Copy Markdown
Member

Merged in a version with a constant prop fix. Downstream handling so everything uses the same DEVerbosity should all be merging ASAP as well. @devmotion just let me know if there's anything not handled here in the pre v7 DiffEqBase bump.

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.

3 participants