Skip to content

Draft: use SciMLVerbosity verbosity system #647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6b3f882
adding verbosity stuff
jClugstor Jul 10, 2025
7a935d1
bring back compilation workload
jClugstor Jul 22, 2025
fdcea3a
add some toggles
jClugstor Jul 22, 2025
9423b59
use scoped values
jClugstor Jul 22, 2025
8a1b979
imports
jClugstor Jul 22, 2025
40b3752
use SciMLMessage
jClugstor Jul 22, 2025
1ac8e53
add more message
jClugstor Jul 23, 2025
184c8a4
add defaults
jClugstor Jul 23, 2025
19d5345
use correct names
jClugstor Jul 23, 2025
8208de3
fix type of scopedvalue
jClugstor Jul 23, 2025
37dc0e2
these don't need to be mutable
jClugstor Jul 24, 2025
7f3a56c
fix kwargs
jClugstor Jul 24, 2025
cfa9724
redundant linsolve kwargs
jClugstor Jul 24, 2025
a635087
get rid of comments
jClugstor Jul 24, 2025
b6bd0c3
resintate setup workload
jClugstor Jul 24, 2025
1540aa9
get rid of ScopedValues experiment
jClugstor Jul 30, 2025
9685a7b
add verbose to caches
jClugstor Jul 30, 2025
9c180e3
add verbosity messages, fix constructor
jClugstor Jul 30, 2025
ecebd41
imports, other preparations
jClugstor Jul 30, 2025
f412780
make sure that LinearVerbosity is passed to linsolve
jClugstor Jul 31, 2025
1c48001
ensure that LinearVerbosity is passed on in more places
jClugstor Jul 31, 2025
0b6fe58
typo, struct should be mutable
jClugstor Jul 31, 2025
0993281
turn back messages that don't have access to verbose to warn
jClugstor Jul 31, 2025
88b27ac
make sure that verbosity is in polysolve cache
jClugstor Jul 31, 2025
94a7554
add verbosity tests
jClugstor Jul 31, 2025
20d80ab
get rid of stale import, add compat bounds
jClugstor Jul 31, 2025
e361da5
ensure backwards compatibility
jClugstor Aug 1, 2025
85faf9c
import Verbosity for default verbosity
jClugstor Aug 1, 2025
d134d67
make sure linear kwargs are passed
jClugstor Aug 1, 2025
7de61c1
fix kwarg passing
jClugstor Aug 1, 2025
bf8e8b6
fix numerical verbosity
jClugstor Aug 1, 2025
dec345e
add backwards compat tests for Bool verbose
jClugstor Aug 1, 2025
fd6bc30
change constructors to use kwargs
jClugstor Aug 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using PrecompileTools: @compile_workload, @setup_workload
using Reexport: @reexport

using CommonSolve: CommonSolve, solve
using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm
using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, Verbosity
using SciMLBase: SciMLBase, IntervalNonlinearProblem, ReturnCode

abstract type AbstractBracketingAlgorithm <: AbstractNonlinearSolveAlgorithm end
Expand Down
8 changes: 4 additions & 4 deletions lib/BracketingNonlinearSolve/src/bisection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end

function SciMLBase.__solve(
prob::IntervalNonlinearProblem, alg::Bisection, args...;
maxiters = 1000, abstol = nothing, verbose::Bool = true, kwargs...
maxiters = 1000, abstol = nothing, verbose::NonlinearVerbosity = NonlinearVerbosity(), kwargs...
)
@assert !SciMLBase.isinplace(prob) "`Bisection` only supports out-of-place problems."

Expand All @@ -45,9 +45,9 @@ function SciMLBase.__solve(
end

if sign(fl) == sign(fr)
verbose &&
@warn "The interval is not an enclosing interval, opposite signs at the \
boundaries are required."
@SciMLMessage("The interval is not an enclosing interval, opposite signs at the \
boundaries are required.",
verbose, :non_enclosing_interval, :error_control)
return SciMLBase.build_solution(
prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right
)
Expand Down
18 changes: 14 additions & 4 deletions lib/BracketingNonlinearSolve/src/brent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ struct Brent <: AbstractBracketingAlgorithm end

function SciMLBase.__solve(
prob::IntervalNonlinearProblem, alg::Brent, args...;
maxiters = 1000, abstol = nothing, verbose::Bool = true, kwargs...
maxiters = 1000, abstol = nothing, verbose = NonlinearVerbosity(), kwargs...
)
@assert !SciMLBase.isinplace(prob) "`Brent` only supports out-of-place problems."

if verbose isa Bool
if verbose
verbose = NonlinearVerbosity()
else
verbose = NonlinearVerbosity(Verbosity.None())
end
elseif verbose isa Verbosity.Type
verbose = NonlinearVerbosity(verbose)
end

f = Base.Fix2(prob.f, prob.p)
left, right = prob.tspan
fl, fr = f(left), f(right)
Expand All @@ -33,9 +43,9 @@ function SciMLBase.__solve(
end

if sign(fl) == sign(fr)
verbose &&
@warn "The interval is not an enclosing interval, opposite signs at the \
boundaries are required."
@SciMLMessage("The interval is not an enclosing interval, opposite signs at the \
boundaries are required.",
verbose, :non_enclosing_interval, :error_control)
return SciMLBase.build_solution(
prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right
)
Expand Down
18 changes: 14 additions & 4 deletions lib/BracketingNonlinearSolve/src/falsi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ struct Falsi <: AbstractBracketingAlgorithm end

function SciMLBase.__solve(
prob::IntervalNonlinearProblem, alg::Falsi, args...;
maxiters = 1000, abstol = nothing, verbose::Bool = true, kwargs...
maxiters = 1000, abstol = nothing, verbose = NonlinearVerbosity(), kwargs...
)
@assert !SciMLBase.isinplace(prob) "`False` only supports out-of-place problems."

if verbose isa Bool
if verbose
verbose = NonlinearVerbosity()
else
verbose = NonlinearVerbosity(Verbosity.None())
end
elseif verbose isa Verbosity.Type
verbose = NonlinearVerbosity(verbose)
end

f = Base.Fix2(prob.f, prob.p)
l, r = prob.tspan # don't reuse these variables
left, right = prob.tspan
Expand All @@ -32,9 +42,9 @@ function SciMLBase.__solve(
end

if sign(fl) == sign(fr)
verbose &&
@warn "The interval is not an enclosing interval, opposite signs at the \
boundaries are required."
@SciMLMessage("The interval is not an enclosing interval, opposite signs at the \
boundaries are required.",
verbose, :non_enclosing_interval, :error_control)
return SciMLBase.build_solution(
prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right
)
Expand Down
8 changes: 4 additions & 4 deletions lib/BracketingNonlinearSolve/src/itp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ end

function SciMLBase.__solve(
prob::IntervalNonlinearProblem, alg::ITP, args...;
maxiters = 1000, abstol = nothing, verbose::Bool = true, kwargs...
maxiters = 1000, abstol = nothing, verbose::NonlinearVerbosity = NonlinearVerbosity(), kwargs...
)
@assert !SciMLBase.isinplace(prob) "`ITP` only supports out-of-place problems."

Expand All @@ -83,9 +83,9 @@ function SciMLBase.__solve(
end

if sign(fl) == sign(fr)
verbose &&
@warn "The interval is not an enclosing interval, opposite signs at the \
boundaries are required."
@SciMLMessage("The interval is not an enclosing interval, opposite signs at the \
boundaries are required.",
verbose, :non_enclosing_interval, :error_control)
return SciMLBase.build_solution(
prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right
)
Expand Down
8 changes: 4 additions & 4 deletions lib/BracketingNonlinearSolve/src/ridder.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ struct Ridder <: AbstractBracketingAlgorithm end

function SciMLBase.__solve(
prob::IntervalNonlinearProblem, alg::Ridder, args...;
maxiters = 1000, abstol = nothing, verbose::Bool = true, kwargs...
maxiters = 1000, abstol = nothing, verbose::NonlinearVerbosity = NonlinearVerbosity(), kwargs...
)
@assert !SciMLBase.isinplace(prob) "`Ridder` only supports out-of-place problems."

Expand All @@ -32,9 +32,9 @@ function SciMLBase.__solve(
end

if sign(fl) == sign(fr)
verbose &&
@warn "The interval is not an enclosing interval, opposite signs at the \
boundaries are required."
@SciMLMessage("The interval is not an enclosing interval, opposite signs at the \
boundaries are required.",
verbose, :non_enclosing_interval, :error_control)
return SciMLBase.build_solution(
prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right
)
Expand Down
2 changes: 2 additions & 0 deletions lib/NonlinearSolveBase/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
SciMLJacobianOperators = "19f34311-ddf3-4b8b-af20-060888a46c0e"
SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961"
SciMLVerbosity = "a05b3ec9-34a1-438a-b0a1-c0adb433119f"
StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
SymbolicIndexingInterface = "2efcf032-c050-4f8e-a9bb-153293bab1f5"
TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
Expand Down Expand Up @@ -71,6 +72,7 @@ RecursiveArrayTools = "3"
SciMLBase = "2.92"
SciMLJacobianOperators = "0.1.1"
SciMLOperators = "0.4, 1.0"
SciMLVerbosity = "1.2.0"
SparseArrays = "1.10"
SparseMatrixColorings = "0.4.5"
StaticArraysCore = "1.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ using ArrayInterface: ArrayInterface
using CommonSolve: CommonSolve, init, solve!
using LinearSolve: LinearSolve, QRFactorization, SciMLLinearSolveAlgorithm
using SciMLBase: ReturnCode, LinearProblem, LinearAliasSpecifier
using SciMLVerbosity: @SciMLMessage

using LinearAlgebra: ColumnNorm

using NonlinearSolveBase: NonlinearSolveBase, LinearSolveJLCache, LinearSolveResult, Utils
using NonlinearSolveBase: NonlinearSolveBase, LinearSolveJLCache, LinearSolveResult, Utils, NonlinearVerbosity

function (cache::LinearSolveJLCache)(;
A = nothing, b = nothing, linu = nothing,
reuse_A_if_factorization = false, verbose = true, kwargs...
reuse_A_if_factorization = false, kwargs...
)
cache.stats.nsolve += 1

update_A!(cache, A, reuse_A_if_factorization)
b !== nothing && setproperty!(cache.lincache, :b, b)
linu !== nothing && NonlinearSolveBase.set_lincache_u!(cache, linu)

linres = solve!(cache.lincache)
if linres.retcode === ReturnCode.Failure
return LinearSolveResult(; linres.u, success = false)
Expand Down
5 changes: 5 additions & 0 deletions lib/NonlinearSolveBase/src/NonlinearSolveBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ using SciMLBase: SciMLBase, ReturnCode, AbstractODEIntegrator, AbstractNonlinear
LinearAliasSpecifier, ImmutableNonlinearProblem
using SciMLJacobianOperators: JacobianOperator, StatefulJacobianOperator
using SciMLOperators: AbstractSciMLOperator, IdentityOperator
using SciMLVerbosity: @match, @SciMLMessage, Verbosity, AbstractVerbositySpecifier
using SymbolicIndexingInterface: SymbolicIndexingInterface

using LinearAlgebra: LinearAlgebra, Diagonal, norm, ldiv!, diagind, mul!
Expand All @@ -34,6 +35,7 @@ const SII = SymbolicIndexingInterface

include("public.jl")
include("utils.jl")
include("verbosity.jl")

include("abstract_types.jl")
include("common_defaults.jl")
Expand All @@ -47,6 +49,7 @@ include("tracing.jl")
include("wrappers.jl")
include("polyalg.jl")


include("descent/common.jl")
include("descent/newton.jl")
include("descent/steepest.jl")
Expand Down Expand Up @@ -85,6 +88,8 @@ export DescentResult, SteepestDescent, NewtonDescent, DampedNewtonDescent, Dogle

export NonlinearSolvePolyAlgorithm

export NonlinearVerbosity, NonlinearPerformanceVerbosity, NonlinearErrorControlVerbosity, NonlinearNumericalVerbosity

export pickchunksize

end
1 change: 1 addition & 0 deletions lib/NonlinearSolveBase/src/abstract_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ the cache:
- `maxtime`: the maximum time limit for the solver. (Optional)
- `timer`: the timer for the solver. (Optional)
- `total_time`: the total time taken by the solver. (Optional)
- `verbose`: a verbosity object that contains options determining what log messages are emitted.
"""
abstract type AbstractNonlinearSolveCache <: AbstractNonlinearSolveBaseAPI end

Expand Down
19 changes: 11 additions & 8 deletions lib/NonlinearSolveBase/src/autodiff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ function select_forward_mode_autodiff(
if warn_check_mode && !(ADTypes.mode(ad) isa ADTypes.ForwardMode) &&
!(ADTypes.mode(ad) isa ADTypes.ForwardOrReverseMode) &&
!is_finite_differences_backend(ad)
@warn "The chosen AD backend $(ad) is not a forward mode AD. Use with caution."

@warn "The chosen AD backend $(ad) is not a forward mode AD. Use with caution."

end
if incompatible_backend_and_problem(prob, ad)
adₙ = select_forward_mode_autodiff(prob, nothing; warn_check_mode)

@warn "The chosen AD backend `$(ad)` does not support the chosen problem. This \
could be because the backend package for the chosen AD isn't loaded. After \
running autodiff selection detected `$(adₙ)` as a potential forward mode \
Expand All @@ -50,14 +53,14 @@ function select_reverse_mode_autodiff(
if warn_check_mode && !(ADTypes.mode(ad) isa ADTypes.ReverseMode) &&
!(ADTypes.mode(ad) isa ADTypes.ForwardOrReverseMode) &&
!is_finite_differences_backend(ad)
@warn "The chosen AD backend $(ad) is not a reverse mode AD. Use with caution."
@warn "The chosen AD backend $(ad) is not a forward mode AD. Use with caution."
end
if incompatible_backend_and_problem(prob, ad)
adₙ = select_reverse_mode_autodiff(prob, nothing; warn_check_mode)
@warn "The chosen AD backend `$(ad)` does not support the chosen problem. This \
could be because the backend package for the chosen AD isn't loaded. After \
running autodiff selection detected `$(adₙ)` as a potential reverse mode \
backend."
could be because the backend package for the chosen AD isn't loaded. After \
running autodiff selection detected `$(adₙ)` as a potential forward mode \
backend."
return adₙ
end
return ad
Expand All @@ -76,9 +79,9 @@ function select_jacobian_autodiff(prob::AbstractNonlinearProblem, ad::AbstractAD
if incompatible_backend_and_problem(prob, ad)
adₙ = select_jacobian_autodiff(prob, nothing)
@warn "The chosen AD backend `$(ad)` does not support the chosen problem. This \
could be because the backend package for the chosen AD isn't loaded. After \
running autodiff selection detected `$(adₙ)` as a potential jacobian \
backend."
could be because the backend package for the chosen AD isn't loaded. After \
running autodiff selection detected `$(adₙ)` as a potential forward mode \
backend."
return adₙ
end
return ad
Expand Down
12 changes: 10 additions & 2 deletions lib/NonlinearSolveBase/src/descent/newton.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ function InternalAPI.init(
δus = Utils.unwrap_val(shared) ≤ 1 ? nothing : map(2:Utils.unwrap_val(shared)) do i
@bb δu_ = similar(u)
end

if Utils.unwrap_val(pre_inverted)
lincache = nothing
else
if haskey(kwargs, :verbose)
linsolve_kwargs = merge((verbose = kwargs[:verbose].linear_verbosity,), linsolve_kwargs)
end

lincache = construct_linear_solver(
alg, alg.linsolve, J, Utils.safe_vec(fu), Utils.safe_vec(u);
stats, abstol, reltol, linsolve_kwargs...
Expand All @@ -61,7 +66,6 @@ function InternalAPI.init(
δus = Utils.unwrap_val(shared) ≤ 1 ? nothing : map(2:N) do i
@bb δu_ = similar(u)
end

normal_form = needs_square_A(alg.linsolve, u)
if normal_form
JᵀJ = transpose(J) * J
Expand All @@ -72,6 +76,11 @@ function InternalAPI.init(
A, b = J, Utils.safe_vec(fu)
end

if haskey(kwargs, :verbose)
linsolve_kwargs = merge(
(verbose = kwargs[:verbose].linear_verbosity,), linsolve_kwargs)
end

lincache = construct_linear_solver(
alg, alg.linsolve, A, b, Utils.safe_vec(u);
stats, abstol, reltol, linsolve_kwargs...
Expand All @@ -88,7 +97,6 @@ function InternalAPI.solve!(
)
δu = SciMLBase.get_du(cache, idx)
skip_solve && return DescentResult(; δu)

if preinverted_jacobian(cache) && !normal_form(cache)
@assert J!==nothing "`J` must be provided when `preinverted_jacobian = Val(true)`."
@bb δu = J × vec(fu)
Expand Down
6 changes: 6 additions & 0 deletions lib/NonlinearSolveBase/src/descent/steepest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ function InternalAPI.init(
@bb δu_ = similar(u)
end
if Utils.unwrap_val(pre_inverted)

if haskey(kwargs, :verbose)
linsolve_kwargs = merge(
(verbose = kwargs[:verbose].linear_verbosity,), linsolve_kwargs)
end

lincache = construct_linear_solver(
alg, alg.linsolve, transpose(J), Utils.safe_vec(fu), Utils.safe_vec(u);
stats, abstol, reltol, linsolve_kwargs...
Expand Down
5 changes: 2 additions & 3 deletions lib/NonlinearSolveBase/src/linear_solve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,10 @@ function construct_linear_solver(alg, linsolve, A, b, u; stats, kwargs...)

u_fixed = fix_incompatible_linsolve_arguments(A, b, u)
@bb u_cache = copy(u_fixed)
linprob = LinearProblem(A, b; u0 = u_cache, kwargs...)

linprob = LinearProblem(A, b; u0 = u_cache)
# unlias here, we will later use these as caches
lincache = init(
linprob, linsolve; alias = LinearAliasSpecifier(alias_A = false, alias_b = false))
linprob, linsolve; alias = LinearAliasSpecifier(alias_A = false, alias_b = false), kwargs...)
return LinearSolveJLCache(lincache, linsolve, stats)
end

Expand Down
20 changes: 16 additions & 4 deletions lib/NonlinearSolveBase/src/polyalg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ end
alias_u0::Bool

initializealg

verbose
end

function update_initial_values!(cache::NonlinearSolvePolyAlgorithmCache, u0, p)
Expand Down Expand Up @@ -117,15 +119,25 @@ end
function SciMLBase.__init(
prob::AbstractNonlinearProblem, alg::NonlinearSolvePolyAlgorithm, args...;
stats = NLStats(0, 0, 0, 0, 0), maxtime = nothing, maxiters = 1000,
internalnorm = L2_NORM, alias_u0 = false, verbose = true,
internalnorm = L2_NORM, alias_u0 = false, verbose = NonlinearVerbosity(),
initializealg = NonlinearSolveDefaultInit(), kwargs...
)
if alias_u0 && !ArrayInterface.ismutable(prob.u0)
verbose && @warn "`alias_u0` has been set to `true`, but `u0` is \
immutable (checked using `ArrayInterface.ismutable`)."
@SciMLMessage("`alias_u0` has been set to `true`, but `u0` is
immutable (checked using `ArrayInterface.ismutable``).", verbose, :alias_u0_immutable, :error_control)
alias_u0 = false # If immutable don't care about aliasing
end

if verbose isa Bool
if verbose
verbose = NonlinearVerbosity()
else
verbose = NonlinearVerbosity(Verbosity.None())
end
elseif verbose isa Verbosity.Type
verbose = NonlinearVerbosity(verbose)
end

u0 = prob.u0
u0_aliased = alias_u0 ? copy(u0) : u0
alias_u0 && (prob = SciMLBase.remake(prob; u0 = u0_aliased))
Expand All @@ -141,7 +153,7 @@ function SciMLBase.__init(
end,
alg, -1, alg.start_index, 0, stats, 0.0, maxtime,
ReturnCode.Default, false, maxiters, internalnorm,
u0, u0_aliased, alias_u0, initializealg
u0, u0_aliased, alias_u0, initializealg, verbose
)
run_initialization!(cache)
return cache
Expand Down
Loading
Loading