Skip to content
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
af78d00
adding verbosity stuff
jClugstor Jul 10, 2025
2487de5
bring back compilation workload
jClugstor Jul 22, 2025
41cef88
add some toggles
jClugstor Jul 22, 2025
34d92ec
use scoped values
jClugstor Jul 22, 2025
19f097f
imports
jClugstor Jul 22, 2025
d257f9f
use SciMLMessage
jClugstor Jul 22, 2025
0fe5cc1
add more message
jClugstor Jul 23, 2025
9f57ae9
add defaults
jClugstor Jul 23, 2025
baf70db
use correct names
jClugstor Jul 23, 2025
8a36b05
fix type of scopedvalue
jClugstor Jul 23, 2025
3d8ec44
these don't need to be mutable
jClugstor Jul 24, 2025
1a9f8c5
fix kwargs
jClugstor Jul 24, 2025
98ad2ae
redundant linsolve kwargs
jClugstor Jul 24, 2025
50a771b
get rid of comments
jClugstor Jul 24, 2025
6884b04
resintate setup workload
jClugstor Jul 24, 2025
3ced4a9
get rid of ScopedValues experiment
jClugstor Jul 30, 2025
a6dabb9
add verbose to caches
jClugstor Jul 30, 2025
a506541
add verbosity messages, fix constructor
jClugstor Jul 30, 2025
4b0148d
imports, other preparations
jClugstor Jul 30, 2025
58e9ffa
make sure that LinearVerbosity is passed to linsolve
jClugstor Jul 31, 2025
a8e82c9
ensure that LinearVerbosity is passed on in more places
jClugstor Jul 31, 2025
fb74255
typo, struct should be mutable
jClugstor Jul 31, 2025
f4f1cf2
turn back messages that don't have access to verbose to warn
jClugstor Jul 31, 2025
14a1c17
make sure that verbosity is in polysolve cache
jClugstor Jul 31, 2025
5842272
add verbosity tests
jClugstor Jul 31, 2025
9f2b323
get rid of stale import, add compat bounds
jClugstor Jul 31, 2025
08e1bdd
ensure backwards compatibility
jClugstor Aug 1, 2025
8efdd22
import Verbosity for default verbosity
jClugstor Aug 1, 2025
5d24f65
make sure linear kwargs are passed
jClugstor Aug 1, 2025
ff1fb84
fix kwarg passing
jClugstor Aug 1, 2025
b6e667b
fix numerical verbosity
jClugstor Aug 1, 2025
61ff1e3
add backwards compat tests for Bool verbose
jClugstor Aug 1, 2025
33d5caa
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 @@ -24,6 +24,7 @@ SciMLJacobianOperators = "19f34311-ddf3-4b8b-af20-060888a46c0e"
SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961"
SciMLStructures = "53ae85a6-f571-4167-b2af-e1d143709226"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
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 @@ -87,6 +88,7 @@ SciMLJacobianOperators = "0.1.1"
SciMLOperators = "1.7"
SciMLStructures = "1.5"
Setfield = "1.1.2"
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 @@ -28,6 +28,7 @@ import SciMLBase: solve, init, __init, __solve, wrap_sol, get_root_indp, isinpla

using SciMLJacobianOperators: JacobianOperator, StatefulJacobianOperator
using SciMLOperators: AbstractSciMLOperator, IdentityOperator
using SciMLVerbosity: @match, @SciMLMessage, Verbosity, AbstractVerbositySpecifier
using SymbolicIndexingInterface: SymbolicIndexingInterface
import SciMLStructures
using Setfield: @set!
Expand All @@ -41,6 +42,7 @@ const SII = SymbolicIndexingInterface

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

include("abstract_types.jl")
include("common_defaults.jl")
Expand All @@ -54,6 +56,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 @@ -92,6 +95,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::IN = L2_NORM, alias_u0 = false, verbose = true,
internalnorm::IN = L2_NORM, alias_u0 = false, verbose = NonlinearVerbosity(),
initializealg = NonlinearSolveDefaultInit(), kwargs...
) where {IN}
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