From 2ce289806155d0d5b505f7ed7084b5f4d5ee83bb Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 10 Jul 2025 01:19:52 -0400 Subject: [PATCH 01/51] adding verbosity stuff --- .../src/BracketingNonlinearSolve.jl | 2 +- lib/BracketingNonlinearSolve/src/bisection.jl | 2 +- lib/BracketingNonlinearSolve/src/brent.jl | 2 +- lib/BracketingNonlinearSolve/src/falsi.jl | 2 +- lib/BracketingNonlinearSolve/src/itp.jl | 2 +- lib/BracketingNonlinearSolve/src/ridder.jl | 2 +- lib/NonlinearSolveBase/Project.toml | 1 + .../ext/NonlinearSolveBaseLinearSolveExt.jl | 6 +- .../src/NonlinearSolveBase.jl | 4 + .../src/descent/damped_newton.jl | 10 ++ lib/NonlinearSolveBase/src/descent/newton.jl | 26 ++- .../src/descent/steepest.jl | 11 ++ lib/NonlinearSolveBase/src/linear_solve.jl | 4 +- lib/NonlinearSolveBase/src/polyalg.jl | 2 +- lib/NonlinearSolveBase/src/solve.jl | 3 +- lib/NonlinearSolveBase/src/verbosity.jl | 158 ++++++++++++++++++ .../src/NonlinearSolveFirstOrder.jl | 34 ++-- lib/NonlinearSolveFirstOrder/src/solve.jl | 4 +- .../src/NonlinearSolveQuasiNewton.jl | 24 +-- .../src/NonlinearSolveSpectralMethods.jl | 2 +- .../src/SimpleNonlinearSolve.jl | 2 +- src/NonlinearSolve.jl | 64 +++---- test/core_tests.jl | 3 +- 23 files changed, 289 insertions(+), 81 deletions(-) create mode 100644 lib/NonlinearSolveBase/src/verbosity.jl diff --git a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl index b7c16fac3..c101f35db 100644 --- a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl +++ b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl @@ -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 using SciMLBase: SciMLBase, IntervalNonlinearProblem, ReturnCode abstract type AbstractBracketingAlgorithm <: AbstractNonlinearSolveAlgorithm end diff --git a/lib/BracketingNonlinearSolve/src/bisection.jl b/lib/BracketingNonlinearSolve/src/bisection.jl index 5af8f275b..abc647e95 100644 --- a/lib/BracketingNonlinearSolve/src/bisection.jl +++ b/lib/BracketingNonlinearSolve/src/bisection.jl @@ -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." diff --git a/lib/BracketingNonlinearSolve/src/brent.jl b/lib/BracketingNonlinearSolve/src/brent.jl index a1dbb9641..5b86a81ab 100644 --- a/lib/BracketingNonlinearSolve/src/brent.jl +++ b/lib/BracketingNonlinearSolve/src/brent.jl @@ -7,7 +7,7 @@ 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." diff --git a/lib/BracketingNonlinearSolve/src/falsi.jl b/lib/BracketingNonlinearSolve/src/falsi.jl index 557fc18fe..04e03b698 100644 --- a/lib/BracketingNonlinearSolve/src/falsi.jl +++ b/lib/BracketingNonlinearSolve/src/falsi.jl @@ -7,7 +7,7 @@ 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." diff --git a/lib/BracketingNonlinearSolve/src/itp.jl b/lib/BracketingNonlinearSolve/src/itp.jl index c733dc25f..fc1742942 100644 --- a/lib/BracketingNonlinearSolve/src/itp.jl +++ b/lib/BracketingNonlinearSolve/src/itp.jl @@ -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." diff --git a/lib/BracketingNonlinearSolve/src/ridder.jl b/lib/BracketingNonlinearSolve/src/ridder.jl index a647098ad..abb2ee9bb 100644 --- a/lib/BracketingNonlinearSolve/src/ridder.jl +++ b/lib/BracketingNonlinearSolve/src/ridder.jl @@ -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." diff --git a/lib/NonlinearSolveBase/Project.toml b/lib/NonlinearSolveBase/Project.toml index d58050004..6e56b4167 100644 --- a/lib/NonlinearSolveBase/Project.toml +++ b/lib/NonlinearSolveBase/Project.toml @@ -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" diff --git a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl index c6e88e3ab..feaa277bc 100644 --- a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl +++ b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl @@ -8,18 +8,18 @@ using SciMLBase: ReturnCode, LinearProblem, LinearAliasSpecifier 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, verbose = NonlinearVerbosity(), 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) diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index 4baef6c55..92a64c48e 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -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! @@ -53,6 +54,7 @@ include("timer_outputs.jl") include("tracing.jl") include("wrappers.jl") include("polyalg.jl") +include("verbosity.jl") include("descent/common.jl") include("descent/newton.jl") @@ -92,6 +94,8 @@ export DescentResult, SteepestDescent, NewtonDescent, DampedNewtonDescent, Dogle export NonlinearSolvePolyAlgorithm +export NonlinearVerbosity, NonlinearPerformanceVerbosity, NonlinearErrorControlVerbosity, NonlinearNumericalVerbosity + export pickchunksize end diff --git a/lib/NonlinearSolveBase/src/descent/damped_newton.jl b/lib/NonlinearSolveBase/src/descent/damped_newton.jl index 8058a48a5..2e0884acb 100644 --- a/lib/NonlinearSolveBase/src/descent/damped_newton.jl +++ b/lib/NonlinearSolveBase/src/descent/damped_newton.jl @@ -135,6 +135,16 @@ function InternalAPI.init( A, b = Utils.maybe_symmetric(J_damped), Utils.safe_vec(Jᵀfu) rhs_cache = nothing end + + if !haskey(linsolve_kwargs, :verbose) + if kwargs[:verbose].linear_verbosity isa Verbosity.Type + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose = LinearVerbosity(kwargs[:verbose]))) + else + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose = kwargs[:verbose].linear_verbosity)) + end + end lincache = construct_linear_solver( alg, alg.linsolve, A, b, Utils.safe_vec(u); diff --git a/lib/NonlinearSolveBase/src/descent/newton.jl b/lib/NonlinearSolveBase/src/descent/newton.jl index a0aaa91d3..f84529e83 100644 --- a/lib/NonlinearSolveBase/src/descent/newton.jl +++ b/lib/NonlinearSolveBase/src/descent/newton.jl @@ -31,10 +31,22 @@ function InternalAPI.init( abstol = nothing, reltol = nothing, timer = get_timer_output(), kwargs... ) + #Main.@infiltrate @bb δu = similar(u) δus = Utils.unwrap_val(shared) ≤ 1 ? nothing : map(2:Utils.unwrap_val(shared)) do i @bb δu_ = similar(u) end + + if !haskey(linsolve_kwargs, :verbose) + if kwargs[:verbose].linear_verbosity isa Verbosity.Type + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose = LinearVerbosity(kwargs[:verbose]))) + else + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose = kwargs[:verbose].linear_verbosity)) + end + end + if Utils.unwrap_val(pre_inverted) lincache = nothing else @@ -43,6 +55,7 @@ function InternalAPI.init( stats, abstol, reltol, linsolve_kwargs... ) end + #Main.@infiltrate return NewtonDescentCache( δu, δus, lincache, nothing, nothing, timer, pre_inverted, Val(false) ) @@ -54,6 +67,7 @@ function InternalAPI.init( abstol = nothing, reltol = nothing, timer = get_timer_output(), kwargs... ) + #Main.@infiltrate length(fu) != length(u) && @assert !Utils.unwrap_val(pre_inverted) "Precomputed Inverse for Non-Square Jacobian doesn't make sense." @@ -61,7 +75,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 @@ -72,6 +85,16 @@ function InternalAPI.init( A, b = J, Utils.safe_vec(fu) end + if !haskey(linsolve_kwargs, :verbose) + if kwargs[:verbose].linear_verbosity isa Verbosity.Type + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose=LinearVerbosity(kwargs[:verbose]))) + else + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose=kwargs[:verbose].linear_verbosity)) + end + end + lincache = construct_linear_solver( alg, alg.linsolve, A, b, Utils.safe_vec(u); stats, abstol, reltol, linsolve_kwargs... @@ -88,7 +111,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) diff --git a/lib/NonlinearSolveBase/src/descent/steepest.jl b/lib/NonlinearSolveBase/src/descent/steepest.jl index 247490957..aee6582dc 100644 --- a/lib/NonlinearSolveBase/src/descent/steepest.jl +++ b/lib/NonlinearSolveBase/src/descent/steepest.jl @@ -37,6 +37,17 @@ function InternalAPI.init( @bb δu_ = similar(u) end if Utils.unwrap_val(pre_inverted) + + if !haskey(linsolve_kwargs, :verbose) + if kwargs[:verbose].linear_verbosity isa Verbosity.Type + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose = LinearVerbosity(kwargs[:verbose]))) + else + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose = kwargs[:verbose].linear_verbosity)) + end + end + lincache = construct_linear_solver( alg, alg.linsolve, transpose(J), Utils.safe_vec(fu), Utils.safe_vec(u); stats, abstol, reltol, linsolve_kwargs... diff --git a/lib/NonlinearSolveBase/src/linear_solve.jl b/lib/NonlinearSolveBase/src/linear_solve.jl index 667564255..5fa7b98d4 100644 --- a/lib/NonlinearSolveBase/src/linear_solve.jl +++ b/lib/NonlinearSolveBase/src/linear_solve.jl @@ -70,8 +70,8 @@ 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) + #Main.@infiltrate # unlias here, we will later use these as caches lincache = init( linprob, linsolve; alias = LinearAliasSpecifier(alias_A = false, alias_b = false)) diff --git a/lib/NonlinearSolveBase/src/polyalg.jl b/lib/NonlinearSolveBase/src/polyalg.jl index 90ca2ca2e..74fc2df1f 100644 --- a/lib/NonlinearSolveBase/src/polyalg.jl +++ b/lib/NonlinearSolveBase/src/polyalg.jl @@ -117,7 +117,7 @@ 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) diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index 0fe813dbd..0f10606ce 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -224,6 +224,7 @@ function SciMLBase.__solve( prob::AbstractNonlinearProblem, alg::AbstractNonlinearSolveAlgorithm, args...; kwargs... ) + #Main.@infiltrate cache = SciMLBase.__init(prob, alg, args...; kwargs...) return CommonSolve.solve!(cache) end @@ -375,7 +376,7 @@ end @generated function __generated_polysolve( prob::AbstractNonlinearProblem, alg::NonlinearSolvePolyAlgorithm{Val{N}}, args...; - stats = NLStats(0, 0, 0, 0, 0), alias_u0 = false, verbose = true, + stats = NLStats(0, 0, 0, 0, 0), alias_u0 = false, verbose = NonlinearVerbosity(), initializealg = NonlinearSolveDefaultInit(), kwargs... ) where {N} sol_syms = [gensym("sol") for _ in 1:N] diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl new file mode 100644 index 000000000..fff4d5a65 --- /dev/null +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -0,0 +1,158 @@ +mutable struct NonlinearErrorControlVerbosity + function NonlinearErrorControlVerbosity() + new() + end +end + +function NonlinearErrorControlVerbosity(verbose::Verbosity.Type) + @match verbose begin + Verbosity.None() => NonlinearErrorControlVerbosity(fill( + Verbosity.None(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + + Verbosity.Info() => NonlinearErrorControlVerbosity(fill( + Verbosity.Info(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + + Verbosity.Warn() => NonlinearErrorControlVerbosity(fill( + Verbosity.Warn(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + + Verbosity.Error() => NonlinearNumericalVerbosity(fill( + Verbosity.Error(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + + Verbosity.Default() => NonlinearErrorControlVerbosity() + + Verbosity.Edge() => NonlinearErrorControlVerbosity() + + _ => @error "Not a valid choice for verbosity." + end +end + +mutable struct NonlinearPerformanceVerbosity + function NonlinearPerformanceVerbosity() + new() + end +end + +function NonlinearPerformanceVerbosity(verbose::Verbosity.Type) + @match verbose begin + Verbosity.None() => NonlinearPerformanceVerbosity(fill( + Verbosity.None(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Info() => NonlinearPerformanceVerbosity(fill( + Verbosity.Info(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Warn() => NonlinPerformanceVerbosity(fill( + Verbosity.Warn(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Error() => NonlinearPerformanceVerbosity(fill( + Verbosity.Error(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Default() => NonlinearPerformanceVerbosity() + + Verbosity.Edge() => NonlinearPerformanceVerbosity() + + _ => @error "Not a valid choice for verbosity." + end +end + +mutable struct NonlinearNumericalVerbosity + function NonlinearNumericalVerbosity() + new() + end +end + +function NonlinearNumericalVerbosity(verbose::Verbosity.Type) + @match verbose begin + Verbosity.None() => NonlinearNumericalVerbosity(fill( + Verbosity.None(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Info() => NonlinearNumericalVerbosity(fill( + Verbosity.Info(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Warn() => NonlinearNumericalVerbosity(fill( + Verbosity.Warn(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Error() => NonlinearNumericalVerbosity(fill( + Verbosity.Error(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + + Verbosity.Default() => NonlinearNumericalVerbosity() + + Verbosity.Edge() => NonlinearNumericalVerbosity() + + _ => @error "Not a valid choice for verbosity." + end +end + +struct NonlinearVerbosity{T} <: AbstractVerbositySpecifier{T} + linear_verbosity + + error_control::NonlinearErrorControlVerbosity + performance::NonlinearPerformanceVerbosity + numerical::NonlinearNumericalVerbosity +end + +function NonlinearVerbosity(verbose::Verbosity.Type) + @match verbose begin + Verbosity.Default() => NonlinearVerbosity{true}( + Verbosity.Default(), + NonlinearErrorControlVerbosity(Verbosity.Default()), + NonlinearPerformanceVerbosity(Verbosity.Default()), + NonlinearNumericalVerbosity(Verbosity.Default()) + ) + + Verbosity.None() => NonlinearVerbosity{false}( + Verbosity.None(), + NonlinearErrorControlVerbosity(Verbosity.None()), + NonlinearPerformanceVerbosity(Verbosity.None()), + NonlinearNumericalVerbosity(Verbosity.None())) + + Verbosity.All() => NonlinearVerbosity{true}( + Verbosity.All(), + NonlinearErrorControlVerbosity(Verbosity.Info()), + NonlinearPerformanceVerbosity(Verbosity.Info()), + NonlinearNumericalVerbosity(Verbosity.Info()) + ) + + _ => @error "Not a valid choice for verbosity." + end +end + +function NonlinearVerbosity(; + error_control=Verbosity.Default(), performance=Verbosity.Default(), + numerical=Verbosity.Default(), linear_verbosity = Verbosity.Default(), kwargs...) + + + if error_control isa Verbosity.Type + error_control_verbosity = NonlinearErrorControlVerbosity(error_control) + else + error_control_verbosity = error_control + end + + if performance isa Verbosity.Type + performance_verbosity = NonlinearPerformanceVerbosity(performance) + else + performance_verbosity = performance + end + + if numerical isa Verbosity.Type + numerical_verbosity = NonlinearNumericalVerbosity(numerical) + else + numerical_verbosity = numerical + end + + if !isempty(kwargs) + for (key, value) in pairs(kwargs) + if hasfield(NonlinearErrorControlVerbosity, key) + setproperty!(error_control_verbosity, key, value) + elseif hasfield(NonlinearPerformanceVerbosity, key) + setproperty!(performance_verbosity, key, value) + elseif hasfield(NonlinearNumericalVerbosity, key) + setproperty!(numerical_verbosity, key, value) + else + error("$key is not a recognized verbosity toggle.") + end + end + end + + NonlinearVerbosity{true}(linear_verbosity, error_control_verbosity, + performance_verbosity, numerical_verbosity) +end \ No newline at end of file diff --git a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl index dba01edfe..50a1f7e56 100644 --- a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl +++ b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl @@ -21,7 +21,7 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, Utils, InternalAPI, get_timer_output, @static_timeit, update_trace!, L2_NORM, NonlinearSolvePolyAlgorithm, NewtonDescent, DampedNewtonDescent, GeodesicAcceleration, - Dogleg, NonlinearSolveForwardDiffCache, reused_jacobian + Dogleg, NonlinearSolveForwardDiffCache, NonlinearVerbosity, reused_jacobian using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearFunction, NonlinearLeastSquaresProblem, NonlinearProblem, NoSpecialize @@ -39,17 +39,17 @@ include("pseudo_transient.jl") include("poly_algs.jl") include("forward_diff.jl") -@setup_workload begin - nonlinear_functions = ( - (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), - (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), - (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) - ) +# @setup_workload begin +# nonlinear_functions = ( +# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), +# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), +# (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) +# ) - nonlinear_problems = NonlinearProblem[] - for (fn, u0) in nonlinear_functions - push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) - end +# nonlinear_problems = NonlinearProblem[] +# for (fn, u0) in nonlinear_functions +# push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) +# end nonlinear_functions = ( (NonlinearFunction{false, NoSpecialize}((u, p) -> (u .^ 2 .- p)[1:1]), [0.1, 0.0]), @@ -72,13 +72,13 @@ include("forward_diff.jl") ) ) - nlls_problems = NonlinearLeastSquaresProblem[] - for (fn, u0) in nonlinear_functions - push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) - end +# nlls_problems = NonlinearLeastSquaresProblem[] +# for (fn, u0) in nonlinear_functions +# push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) +# end - nlp_algs = [NewtonRaphson(), TrustRegion(), LevenbergMarquardt()] - nlls_algs = [GaussNewton(), TrustRegion(), LevenbergMarquardt()] +# nlp_algs = [NewtonRaphson(), TrustRegion(), LevenbergMarquardt()] +# nlls_algs = [GaussNewton(), TrustRegion(), LevenbergMarquardt()] @compile_workload begin @sync begin diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index 874f5dbc4..f720092f7 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -130,7 +130,7 @@ function SciMLBase.__init( stats = NLStats(0, 0, 0, 0, 0), alias_u0 = false, maxiters = 1000, abstol = nothing, reltol = nothing, maxtime = nothing, termination_condition = nothing, internalnorm::IN = L2_NORM, - linsolve_kwargs = (;), initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), kwargs... + linsolve_kwargs = (;), initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), verbose = NonlinearVerbosity(), kwargs... ) where {IN} @set! alg.autodiff = NonlinearSolveBase.select_jacobian_autodiff(prob, alg.autodiff) provided_jvp_autodiff = alg.jvp_autodiff !== nothing @@ -174,7 +174,7 @@ function SciMLBase.__init( descent_cache = InternalAPI.init( prob, alg.descent, J, fu, u; stats, abstol, reltol, internalnorm, - linsolve_kwargs, timer + linsolve_kwargs, timer, verbose ) du = SciMLBase.get_du(descent_cache) diff --git a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl index 6bc55c48e..227dd4468 100644 --- a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl +++ b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl @@ -18,7 +18,7 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractApproximateJacobianUpdateRule, AbstractDescentDirection, AbstractApproximateJacobianUpdateRuleCache, Utils, InternalAPI, get_timer_output, @static_timeit, - update_trace!, L2_NORM, NewtonDescent, reused_jacobian + update_trace!, L2_NORM, NewtonDescent, NonlinearVerbosity, reused_jacobian using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize using SciMLOperators: AbstractSciMLOperator @@ -33,19 +33,19 @@ include("klement.jl") include("solve.jl") -@setup_workload begin - nonlinear_functions = ( - (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), - (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), - (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) - ) +# @setup_workload begin +# nonlinear_functions = ( +# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), +# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), +# (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) +# ) - nonlinear_problems = NonlinearProblem[] - for (fn, u0) in nonlinear_functions - push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) - end +# nonlinear_problems = NonlinearProblem[] +# for (fn, u0) in nonlinear_functions +# push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) +# end - algs = [Broyden(), Klement()] +# algs = [Broyden(), Klement()] @compile_workload begin @sync for prob in nonlinear_problems, alg in algs diff --git a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl index 2706d5670..803dd8ff9 100644 --- a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl +++ b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl @@ -9,7 +9,7 @@ using LineSearch: RobustNonMonotoneLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractNonlinearSolveCache, Utils, InternalAPI, get_timer_output, - @static_timeit, update_trace! + @static_timeit, update_trace!, NonlinearVerbosity using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize diff --git a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl index 782de6468..45fbcd237 100644 --- a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl +++ b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl @@ -12,7 +12,7 @@ using LineSearch: LiFukushimaLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, ImmutableNonlinearProblem, L2_NORM, nonlinearsolve_forwarddiff_solve, nonlinearsolve_dual_solution, - AbstractNonlinearSolveAlgorithm + AbstractNonlinearSolveAlgorithm, NonlinearVerbosity using SciMLBase: SciMLBase, NonlinearFunction, NonlinearProblem, NonlinearLeastSquaresProblem, ReturnCode, remake diff --git a/src/NonlinearSolve.jl b/src/NonlinearSolve.jl index d11f99749..d2390477d 100644 --- a/src/NonlinearSolve.jl +++ b/src/NonlinearSolve.jl @@ -47,17 +47,17 @@ include("default.jl") include("forward_diff.jl") -@setup_workload begin - nonlinear_functions = ( - (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), - (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), - (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) - ) - - nonlinear_problems = NonlinearProblem[] - for (fn, u0) in nonlinear_functions - push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) - end +# @setup_workload begin +# nonlinear_functions = ( +# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), +# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), +# (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) +# ) + +# nonlinear_problems = NonlinearProblem[] +# for (fn, u0) in nonlinear_functions +# push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) +# end nonlinear_functions = ( (NonlinearFunction{false, NoSpecialize}((u, p) -> (u .^ 2 .- p)[1:1]), [0.1, 0.0]), @@ -80,27 +80,27 @@ include("forward_diff.jl") ) ) - nlls_problems = NonlinearLeastSquaresProblem[] - for (fn, u0) in nonlinear_functions - push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) - end - - @compile_workload begin - @sync begin - for prob in nonlinear_problems - Threads.@spawn CommonSolve.solve( - prob, nothing; abstol = 1e-2, verbose = false - ) - end - - for prob in nlls_problems - Threads.@spawn CommonSolve.solve( - prob, nothing; abstol = 1e-2, verbose = false - ) - end - end - end -end +# nlls_problems = NonlinearLeastSquaresProblem[] +# for (fn, u0) in nonlinear_functions +# push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) +# end + +# @compile_workload begin +# @sync begin +# for prob in nonlinear_problems +# Threads.@spawn CommonSolve.solve( +# prob, nothing; abstol = 1e-2, verbose = true +# ) +# end + +# for prob in nlls_problems +# Threads.@spawn CommonSolve.solve( +# prob, nothing; abstol = 1e-2, verbose = true +# ) +# end +# end +# end +# end # Rexexports @reexport using SciMLBase, NonlinearSolveBase, LineSearch, ADTypes diff --git a/test/core_tests.jl b/test/core_tests.jl index 76a3a9187..c1f3a3b58 100644 --- a/test/core_tests.jl +++ b/test/core_tests.jl @@ -216,7 +216,8 @@ end function objective_function!(resid, u0, p) odeprob = ODEProblem{true}(ode_func!, u0, (0.0, 100.0), p) - sol = solve(odeprob, Tsit5(), abstol = 1e-9, reltol = 1e-9, verbose = false) + sol = solve( + odeprob, Tsit5(), abstol = 1e-9, reltol = 1e-9, verbose = true) resid[1] = sol(0.0)[1] resid[2] = sol(100.0)[1] - 1.0 return nothing From 736b90e27c3a4bef09aab93f7a713fb41c113823 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 22 Jul 2025 12:53:43 -0400 Subject: [PATCH 02/51] bring back compilation workload --- .../src/NonlinearSolveQuasiNewton.jl | 26 ++++---- src/NonlinearSolve.jl | 62 +++++++++---------- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl index 227dd4468..795858468 100644 --- a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl +++ b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl @@ -33,19 +33,19 @@ include("klement.jl") include("solve.jl") -# @setup_workload begin -# nonlinear_functions = ( -# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), -# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), -# (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) -# ) - -# nonlinear_problems = NonlinearProblem[] -# for (fn, u0) in nonlinear_functions -# push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) -# end - -# algs = [Broyden(), Klement()] +@setup_workload begin + nonlinear_functions = ( + (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), + (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), + (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) + ) + + nonlinear_problems = NonlinearProblem[] + for (fn, u0) in nonlinear_functions + push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) + end + + algs = [Broyden(), Klement()] @compile_workload begin @sync for prob in nonlinear_problems, alg in algs diff --git a/src/NonlinearSolve.jl b/src/NonlinearSolve.jl index d2390477d..9857d87a5 100644 --- a/src/NonlinearSolve.jl +++ b/src/NonlinearSolve.jl @@ -47,17 +47,17 @@ include("default.jl") include("forward_diff.jl") -# @setup_workload begin -# nonlinear_functions = ( -# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), -# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), -# (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) -# ) - -# nonlinear_problems = NonlinearProblem[] -# for (fn, u0) in nonlinear_functions -# push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) -# end +@setup_workload begin + nonlinear_functions = ( + (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), + (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), + (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) + ) + + nonlinear_problems = NonlinearProblem[] + for (fn, u0) in nonlinear_functions + push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) + end nonlinear_functions = ( (NonlinearFunction{false, NoSpecialize}((u, p) -> (u .^ 2 .- p)[1:1]), [0.1, 0.0]), @@ -80,27 +80,25 @@ include("forward_diff.jl") ) ) -# nlls_problems = NonlinearLeastSquaresProblem[] -# for (fn, u0) in nonlinear_functions -# push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) -# end - -# @compile_workload begin -# @sync begin -# for prob in nonlinear_problems -# Threads.@spawn CommonSolve.solve( -# prob, nothing; abstol = 1e-2, verbose = true -# ) -# end - -# for prob in nlls_problems -# Threads.@spawn CommonSolve.solve( -# prob, nothing; abstol = 1e-2, verbose = true -# ) -# end -# end -# end -# end + nlls_problems = NonlinearLeastSquaresProblem[] + for (fn, u0) in nonlinear_functions + push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) + end + + @compile_workload begin + @sync begin + for prob in nonlinear_problems + Threads.@spawn CommonSolve.solve( + ) + end + + for prob in nlls_problems + Threads.@spawn CommonSolve.solve( + ) + end + end + end +end # Rexexports @reexport using SciMLBase, NonlinearSolveBase, LineSearch, ADTypes From ab22f799a2bb3d6a149b618858f77ef87275dbdd Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 22 Jul 2025 15:24:17 -0400 Subject: [PATCH 03/51] add some toggles --- lib/NonlinearSolveBase/src/verbosity.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index fff4d5a65..a3a248e1f 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -1,4 +1,10 @@ +using Base.ScopedValues +const non_linear_verbose = ScopedValue(NonlinearVerbosity()) + mutable struct NonlinearErrorControlVerbosity + immutable_u0::Verbosity.Type + non_enclosing_interval::Verbosity.Type + function NonlinearErrorControlVerbosity() new() end From 6b18880104f5e43139f482befcf8590a2204588b Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 22 Jul 2025 15:24:23 -0400 Subject: [PATCH 04/51] use scoped values --- lib/NonlinearSolveBase/src/NonlinearSolveBase.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index 92a64c48e..bf802404b 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -36,12 +36,16 @@ using Setfield: @set! using LinearAlgebra: LinearAlgebra, Diagonal, norm, ldiv!, diagind, mul! using Markdown: @doc_str using Printf: @printf +using Base.ScopedValues const DI = DifferentiationInterface const SII = SymbolicIndexingInterface include("public.jl") include("utils.jl") +include("verbosity.jl") + +const non_linear_verbose = ScopedValue(NonlinearVerbosity()) include("abstract_types.jl") include("common_defaults.jl") @@ -54,7 +58,7 @@ include("timer_outputs.jl") include("tracing.jl") include("wrappers.jl") include("polyalg.jl") -include("verbosity.jl") + include("descent/common.jl") include("descent/newton.jl") From 02a46d5fa17e2ea7f858a4629a2fe532a4e4f3f6 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 22 Jul 2025 17:03:44 -0400 Subject: [PATCH 05/51] imports --- .../src/BracketingNonlinearSolve.jl | 2 +- src/NonlinearSolve.jl | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl index c101f35db..3198e9b44 100644 --- a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl +++ b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl @@ -5,7 +5,7 @@ using PrecompileTools: @compile_workload, @setup_workload using Reexport: @reexport using CommonSolve: CommonSolve, solve -using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity +using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, Verbosity using SciMLBase: SciMLBase, IntervalNonlinearProblem, ReturnCode abstract type AbstractBracketingAlgorithm <: AbstractNonlinearSolveAlgorithm end diff --git a/src/NonlinearSolve.jl b/src/NonlinearSolve.jl index 9857d87a5..dc6a20507 100644 --- a/src/NonlinearSolve.jl +++ b/src/NonlinearSolve.jl @@ -11,7 +11,7 @@ using CommonSolve: CommonSolve, init, solve, solve! using LinearAlgebra: LinearAlgebra using LineSearch: BackTracking using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, - NonlinearSolvePolyAlgorithm, pickchunksize + NonlinearSolvePolyAlgorithm, pickchunksize, NonlinearVerbosity using SciMLBase: SciMLBase, ReturnCode, AbstractNonlinearProblem, NonlinearFunction, @@ -85,16 +85,17 @@ include("forward_diff.jl") push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) end + nlp_algs = [NewtonRaphson(), TrustRegion(), LevenbergMarquardt()] + nlls_algs = [GaussNewton(), TrustRegion(), LevenbergMarquardt()] + @compile_workload begin @sync begin - for prob in nonlinear_problems - Threads.@spawn CommonSolve.solve( - ) + for prob in nonlinear_problems, alg in nlp_algs + Threads.@spawn CommonSolve.solve(prob, alg; abstol = 1e-2, verbose = NonlinearVerbosity()) end - for prob in nlls_problems - Threads.@spawn CommonSolve.solve( - ) + for prob in nlls_problems, alg in nlls_algs + Threads.@spawn CommonSolve.solve(prob, alg; abstol = 1e-2, verbose = NonlinearVerbosity()) end end end From 4cc55609ee8a23e3d027ab6730384e45171010f9 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 22 Jul 2025 17:03:58 -0400 Subject: [PATCH 06/51] use SciMLMessage --- lib/BracketingNonlinearSolve/src/bisection.jl | 6 +++--- lib/BracketingNonlinearSolve/src/brent.jl | 6 +++--- lib/BracketingNonlinearSolve/src/falsi.jl | 6 +++--- lib/BracketingNonlinearSolve/src/itp.jl | 6 +++--- lib/BracketingNonlinearSolve/src/ridder.jl | 6 +++--- lib/NonlinearSolveBase/src/descent/newton.jl | 1 - lib/NonlinearSolveBase/src/solve.jl | 16 ++++++++++++---- lib/NonlinearSolveBase/src/verbosity.jl | 5 ++--- 8 files changed, 29 insertions(+), 23 deletions(-) diff --git a/lib/BracketingNonlinearSolve/src/bisection.jl b/lib/BracketingNonlinearSolve/src/bisection.jl index abc647e95..0bc6bbd17 100644 --- a/lib/BracketingNonlinearSolve/src/bisection.jl +++ b/lib/BracketingNonlinearSolve/src/bisection.jl @@ -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.", + nonlinear_verbose[], :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/brent.jl b/lib/BracketingNonlinearSolve/src/brent.jl index 5b86a81ab..5fca94d9e 100644 --- a/lib/BracketingNonlinearSolve/src/brent.jl +++ b/lib/BracketingNonlinearSolve/src/brent.jl @@ -33,9 +33,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.", + nonlinear_verbose[], :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/falsi.jl b/lib/BracketingNonlinearSolve/src/falsi.jl index 04e03b698..87ee76953 100644 --- a/lib/BracketingNonlinearSolve/src/falsi.jl +++ b/lib/BracketingNonlinearSolve/src/falsi.jl @@ -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.", + nonlinear_verbose[], :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/itp.jl b/lib/BracketingNonlinearSolve/src/itp.jl index fc1742942..beaad67de 100644 --- a/lib/BracketingNonlinearSolve/src/itp.jl +++ b/lib/BracketingNonlinearSolve/src/itp.jl @@ -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.", + nonlinear_verbose[], :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/ridder.jl b/lib/BracketingNonlinearSolve/src/ridder.jl index abb2ee9bb..fa28d8f35 100644 --- a/lib/BracketingNonlinearSolve/src/ridder.jl +++ b/lib/BracketingNonlinearSolve/src/ridder.jl @@ -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.", + nonlinear_verbose[], :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/NonlinearSolveBase/src/descent/newton.jl b/lib/NonlinearSolveBase/src/descent/newton.jl index f84529e83..54345234c 100644 --- a/lib/NonlinearSolveBase/src/descent/newton.jl +++ b/lib/NonlinearSolveBase/src/descent/newton.jl @@ -31,7 +31,6 @@ function InternalAPI.init( abstol = nothing, reltol = nothing, timer = get_timer_output(), kwargs... ) - #Main.@infiltrate @bb δu = similar(u) δus = Utils.unwrap_val(shared) ≤ 1 ? nothing : map(2:Utils.unwrap_val(shared)) do i @bb δu_ = similar(u) diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index 0f10606ce..f20d626b5 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -222,11 +222,19 @@ end function SciMLBase.__solve( prob::AbstractNonlinearProblem, alg::AbstractNonlinearSolveAlgorithm, args...; - kwargs... + verbose = NonlinearVerbosity(), linsolve_kwargs = (;), kwargs... ) - #Main.@infiltrate - cache = SciMLBase.__init(prob, alg, args...; kwargs...) - return CommonSolve.solve!(cache) + if !haskey(linsolve_kwargs, :verbose) + linsolve_kwargs = merge( + linsolve_kwargs, (; verbose = verbose.linear_verbosity)) + end + + @with non_linear_verbose => verbose begin + cache = SciMLBase.__init(prob, alg, args...; linsolve_kwargs, kwargs...) + sol = CommonSolve.solve!(cache) + end + + return sol end function CommonSolve.solve!(cache::AbstractNonlinearSolveCache) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index a3a248e1f..1eed71865 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -1,9 +1,8 @@ -using Base.ScopedValues -const non_linear_verbose = ScopedValue(NonlinearVerbosity()) - mutable struct NonlinearErrorControlVerbosity immutable_u0::Verbosity.Type non_enclosing_interval::Verbosity.Type + non_forward_mode::Verbosity.Type + ad_backend_incompatible::Verbosity.Type function NonlinearErrorControlVerbosity() new() From a62b9084012ad02b17ffcb5709535e2f058da619 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 11:43:31 -0400 Subject: [PATCH 07/51] add more message --- lib/NonlinearSolveBase/src/autodiff.jl | 26 +++++++++++++++---------- lib/NonlinearSolveBase/src/jacobian.jl | 20 +++++++++---------- lib/NonlinearSolveBase/src/verbosity.jl | 5 +++++ 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/lib/NonlinearSolveBase/src/autodiff.jl b/lib/NonlinearSolveBase/src/autodiff.jl index 4a9f2edbc..da40286cf 100644 --- a/lib/NonlinearSolveBase/src/autodiff.jl +++ b/lib/NonlinearSolveBase/src/autodiff.jl @@ -24,13 +24,18 @@ function select_forward_mode_autodiff( !(ADTypes.mode(ad) isa ADTypes.ForwardOrReverseMode) && !is_finite_differences_backend(ad) @warn lazy"The chosen AD backend $(ad) is not a forward mode AD. Use with caution." + + @SciMLMessage("The chosen AD backend $(ad) is not a forward mode AD. Use with caution.", + nonlinear_verbosity[], :fd_ad_caution, :error_control) + end if incompatible_backend_and_problem(prob, ad) adₙ = select_forward_mode_autodiff(prob, nothing; warn_check_mode) @warn lazy"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 \ - backend." + backend.", nonlinear_verbosity[], :ad_backend_incompatible, :error_control) + return adₙ end return ad @@ -50,14 +55,15 @@ 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 lazy"The chosen AD backend $(ad) is not a reverse mode AD. Use with caution." + @SciMLMessage("The chosen AD backend $(ad) is not a forward mode AD. Use with caution.", + nonlinear_verbosity[], :fd_ad_caution, :error_control) end if incompatible_backend_and_problem(prob, ad) adₙ = select_reverse_mode_autodiff(prob, nothing; warn_check_mode) - @warn lazy"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." + @SciMLMessage("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 \ + backend.", nonlinear_verbosity[], :ad_backend_incompatible, :error_control) return adₙ end return ad @@ -75,10 +81,10 @@ end function select_jacobian_autodiff(prob::AbstractNonlinearProblem, ad::AbstractADType) if incompatible_backend_and_problem(prob, ad) adₙ = select_jacobian_autodiff(prob, nothing) - @warn lazy"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." + @SciMLMessage("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 \ + backend.", nonlinear_verbosity[], :ad_backend_incompatible, :error_control) return adₙ end return ad diff --git a/lib/NonlinearSolveBase/src/jacobian.jl b/lib/NonlinearSolveBase/src/jacobian.jl index acc727432..63c324644 100644 --- a/lib/NonlinearSolveBase/src/jacobian.jl +++ b/lib/NonlinearSolveBase/src/jacobian.jl @@ -182,15 +182,15 @@ function construct_concrete_adtype(f::NonlinearFunction, ad::AbstractADType) if f.sparsity === nothing if f.jac_prototype === nothing if SciMLBase.has_colorvec(f) - @warn "`colorvec` is provided but `sparsity` and `jac_prototype` is not \ - specified. `colorvec` will be ignored." + @SciMLMessage("`colorvec` is provided but `sparsity` and `jac_prototype` is not \ + specified. `colorvec` will be ignored.", nonlinear_verbosity[], :colorvec_no_prototype, :performance ) end return ad # No sparse AD else if !sparse_or_structured_prototype(f.jac_prototype) if SciMLBase.has_colorvec(f) - @warn "`colorvec` is provided but `jac_prototype` is not a sparse \ - or structured matrix. `colorvec` will be ignored." + @SciMLMessage("`colorvec` is provided but `jac_prototype` is not a sparse \ + or structured matrix. `colorvec` will be ignored.", nonlinear_verbosity[], :colorvec_non_sparse, :performance) end return ad end @@ -225,8 +225,8 @@ function construct_concrete_adtype(f::NonlinearFunction, ad::AbstractADType) sparsity_detector = f.sparsity if f.jac_prototype === nothing if SciMLBase.has_colorvec(f) - @warn "`colorvec` is provided but `jac_prototype` is not specified. \ - `colorvec` will be ignored." + @SciMLMessage("`colorvec` is provided but `jac_prototype` is not specified. \ + `colorvec` will be ignored.", nonlinear_verbose[], :colorvec_no_prototype, :performance) end coloring_algorithm = select_fastest_coloring_algorithm(nothing, f, ad) coloring_algorithm === nothing && return ad @@ -234,9 +234,9 @@ function construct_concrete_adtype(f::NonlinearFunction, ad::AbstractADType) else if sparse_or_structured_prototype(f.jac_prototype) if !(sparsity_detector isa NoSparsityDetector) - @warn lazy"`jac_prototype` is a sparse matrix but sparsity = $(f.sparsity) \ + @SciMLMessage("`jac_prototype` is a sparse matrix but sparsity = $(f.sparsity) \ has also been specified. Ignoring sparsity field and using \ - `jac_prototype` sparsity." + `jac_prototype` sparsity.", nonlinear_verbose[], :sparsity_using_jac_prototype, :performance) end sparsity_detector = KnownJacobianSparsityDetector(f.jac_prototype) end @@ -257,8 +257,8 @@ end function select_fastest_coloring_algorithm( prototype, f::NonlinearFunction, ad::AbstractADType) if !Utils.is_extension_loaded(Val(:SparseMatrixColorings)) - @warn "`SparseMatrixColorings` must be explicitly imported for sparse automatic \ - differentiation to work. Proceeding with Dense Automatic Differentiation." + @SciMLMessage("`SparseMatrixColorings` must be explicitly imported for sparse automatic \ + differentiation to work. Proceeding with Dense Automatic Differentiation.", :sparse_matrix_colorings_not_loaded, :performance) return nothing end return select_fastest_coloring_algorithm(Val(:SparseMatrixColorings), prototype, f, ad) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index 1eed71865..a179a5f8f 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -2,6 +2,7 @@ mutable struct NonlinearErrorControlVerbosity immutable_u0::Verbosity.Type non_enclosing_interval::Verbosity.Type non_forward_mode::Verbosity.Type + fd_ad_caution::Verbosity.Type ad_backend_incompatible::Verbosity.Type function NonlinearErrorControlVerbosity() @@ -32,6 +33,10 @@ function NonlinearErrorControlVerbosity(verbose::Verbosity.Type) end mutable struct NonlinearPerformanceVerbosity + colorvec_non_sparse::Verbosity.Type + colorvec_no_prototype::Verbosity.Type + sparsity_using_jac_prototype::Verbosity.Type + sparse_matrixcolorings_not_loaded::Verbosity.Type function NonlinearPerformanceVerbosity() new() end From f3d8e4b274e0033105f90ba5660b021963f0e67b Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 13:29:34 -0400 Subject: [PATCH 08/51] add defaults --- lib/NonlinearSolveBase/src/verbosity.jl | 31 +++++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index a179a5f8f..dfbfaa944 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -1,3 +1,16 @@ +nonlinear_verbosity_defaults = Dict( + :immutable_u0 => Verbosity.Warn(), + :non_enclosing_interval => Verbosity.Warn(), + :non_forward_mode => Verbosity.Warn(), + :fd_ad_caution => Verbosity.Warn(), + :ad_backend_incompatible => Verbosity.Warn(), + :colorvec_non_sparse => Verbosity.Warn(), + :colorvec_no_prototype => Verbosity.Warn(), + :sparsity_using_jac_prototype => Verbosity.Warn(), + :sparse_matrixcolorings_not_loaded => Verbosity.Warn() +) + + mutable struct NonlinearErrorControlVerbosity immutable_u0::Verbosity.Type non_enclosing_interval::Verbosity.Type @@ -5,8 +18,12 @@ mutable struct NonlinearErrorControlVerbosity fd_ad_caution::Verbosity.Type ad_backend_incompatible::Verbosity.Type - function NonlinearErrorControlVerbosity() - new() + function NonlinearErrorControlVerbosity(immutable_u0 = nonlinear_verbosity_defaults[:immutable_u0], + non_enclosing_interval = nonlinear_verbosity_defaults[:non_enclosing_interval], + non_forward_mode = nonlinear_verbosity_defaults[:non_forward_mode], + fd_ad_caution = nonlinear_verbosity_defaults[:fd_ad_caution], + ad_backend_incompatible = nonlinear_verbosity_defaults[:ad_backend_incompatible]) + new(immutable_u0, non_enclosing_interval, non_forward_mode, fd_ad_caution, ad_backend_incompatible) end end @@ -37,8 +54,12 @@ mutable struct NonlinearPerformanceVerbosity colorvec_no_prototype::Verbosity.Type sparsity_using_jac_prototype::Verbosity.Type sparse_matrixcolorings_not_loaded::Verbosity.Type - function NonlinearPerformanceVerbosity() - new() + + function NonlinearPerformanceVerbosity(colorvec_non_sparse = nonlinear_verbosity_defaults[:colorvec_non_sparse], + colorvec_no_prototype = nonlinear_verbosity_defaults[:colorvec_no_prototype], + sparsity_using_jac_prototype = nonlinear_verbosity_defaults[:sparsity_using_jac_prototype], + sparse_matrixcolorings_not_loaded = nonlinear_verbosity_defaults[:sparse_matrixcolorings_not_loaded]) + new(colorvec_non_sparse, colorvec_no_prototype, sparsity_using_jac_prototype, sparse_matrixcolorings_not_loaded) end end @@ -50,7 +71,7 @@ function NonlinearPerformanceVerbosity(verbose::Verbosity.Type) Verbosity.Info() => NonlinearPerformanceVerbosity(fill( Verbosity.Info(), length(fieldnames(NonlinearPerformanceVerbosity)))...) - Verbosity.Warn() => NonlinPerformanceVerbosity(fill( + Verbosity.Warn() => NonlinearPerformanceVerbosity(fill( Verbosity.Warn(), length(fieldnames(NonlinearPerformanceVerbosity)))...) Verbosity.Error() => NonlinearPerformanceVerbosity(fill( From 33b89975b4f30b1bfb0aa36de93c71ff1fd2fbb3 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 13:29:41 -0400 Subject: [PATCH 09/51] use correct names --- lib/NonlinearSolveBase/src/NonlinearSolveBase.jl | 2 +- lib/NonlinearSolveBase/src/autodiff.jl | 10 +++++----- lib/NonlinearSolveBase/src/jacobian.jl | 6 +++--- lib/NonlinearSolveBase/src/solve.jl | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index bf802404b..21f59e378 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -45,7 +45,7 @@ include("public.jl") include("utils.jl") include("verbosity.jl") -const non_linear_verbose = ScopedValue(NonlinearVerbosity()) +const nonlinear_verbose = ScopedValue(NonlinearVerbosity()) include("abstract_types.jl") include("common_defaults.jl") diff --git a/lib/NonlinearSolveBase/src/autodiff.jl b/lib/NonlinearSolveBase/src/autodiff.jl index da40286cf..63ea1f40a 100644 --- a/lib/NonlinearSolveBase/src/autodiff.jl +++ b/lib/NonlinearSolveBase/src/autodiff.jl @@ -26,7 +26,7 @@ function select_forward_mode_autodiff( @warn lazy"The chosen AD backend $(ad) is not a forward mode AD. Use with caution." @SciMLMessage("The chosen AD backend $(ad) is not a forward mode AD. Use with caution.", - nonlinear_verbosity[], :fd_ad_caution, :error_control) + nonlinear_verbose[], :fd_ad_caution, :error_control) end if incompatible_backend_and_problem(prob, ad) @@ -34,7 +34,7 @@ function select_forward_mode_autodiff( @warn lazy"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 \ - backend.", nonlinear_verbosity[], :ad_backend_incompatible, :error_control) + backend.", nonlinear_verbose[], :ad_backend_incompatible, :error_control) return adₙ end @@ -56,14 +56,14 @@ function select_reverse_mode_autodiff( !(ADTypes.mode(ad) isa ADTypes.ForwardOrReverseMode) && !is_finite_differences_backend(ad) @SciMLMessage("The chosen AD backend $(ad) is not a forward mode AD. Use with caution.", - nonlinear_verbosity[], :fd_ad_caution, :error_control) + nonlinear_verbose[], :fd_ad_caution, :error_control) end if incompatible_backend_and_problem(prob, ad) adₙ = select_reverse_mode_autodiff(prob, nothing; warn_check_mode) @SciMLMessage("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 \ - backend.", nonlinear_verbosity[], :ad_backend_incompatible, :error_control) + backend.", nonlinear_verbose[], :ad_backend_incompatible, :error_control) return adₙ end return ad @@ -84,7 +84,7 @@ function select_jacobian_autodiff(prob::AbstractNonlinearProblem, ad::AbstractAD @SciMLMessage("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 \ - backend.", nonlinear_verbosity[], :ad_backend_incompatible, :error_control) + backend.", nonlinear_verbose[], :ad_backend_incompatible, :error_control) return adₙ end return ad diff --git a/lib/NonlinearSolveBase/src/jacobian.jl b/lib/NonlinearSolveBase/src/jacobian.jl index 63c324644..d7d86ba05 100644 --- a/lib/NonlinearSolveBase/src/jacobian.jl +++ b/lib/NonlinearSolveBase/src/jacobian.jl @@ -183,14 +183,14 @@ function construct_concrete_adtype(f::NonlinearFunction, ad::AbstractADType) if f.jac_prototype === nothing if SciMLBase.has_colorvec(f) @SciMLMessage("`colorvec` is provided but `sparsity` and `jac_prototype` is not \ - specified. `colorvec` will be ignored.", nonlinear_verbosity[], :colorvec_no_prototype, :performance ) + specified. `colorvec` will be ignored.", nonlinear_verbose[], :colorvec_no_prototype, :performance ) end return ad # No sparse AD else if !sparse_or_structured_prototype(f.jac_prototype) if SciMLBase.has_colorvec(f) @SciMLMessage("`colorvec` is provided but `jac_prototype` is not a sparse \ - or structured matrix. `colorvec` will be ignored.", nonlinear_verbosity[], :colorvec_non_sparse, :performance) + or structured matrix. `colorvec` will be ignored.", nonlinear_verbose[], :colorvec_non_sparse, :performance) end return ad end @@ -258,7 +258,7 @@ function select_fastest_coloring_algorithm( prototype, f::NonlinearFunction, ad::AbstractADType) if !Utils.is_extension_loaded(Val(:SparseMatrixColorings)) @SciMLMessage("`SparseMatrixColorings` must be explicitly imported for sparse automatic \ - differentiation to work. Proceeding with Dense Automatic Differentiation.", :sparse_matrix_colorings_not_loaded, :performance) + differentiation to work. Proceeding with Dense Automatic Differentiation.", nonlinear_verbose[], :sparse_matrix_colorings_not_loaded, :performance) return nothing end return select_fastest_coloring_algorithm(Val(:SparseMatrixColorings), prototype, f, ad) diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index f20d626b5..12da943c4 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -229,7 +229,7 @@ function SciMLBase.__solve( linsolve_kwargs, (; verbose = verbose.linear_verbosity)) end - @with non_linear_verbose => verbose begin + @with nonlinear_verbose => verbose begin cache = SciMLBase.__init(prob, alg, args...; linsolve_kwargs, kwargs...) sol = CommonSolve.solve!(cache) end From 1b77ca0012e2be57cf3bda4fde4130ad931f7a69 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 15:04:48 -0400 Subject: [PATCH 10/51] fix type of scopedvalue --- lib/NonlinearSolveBase/src/NonlinearSolveBase.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index 21f59e378..f8527d39e 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -45,7 +45,7 @@ include("public.jl") include("utils.jl") include("verbosity.jl") -const nonlinear_verbose = ScopedValue(NonlinearVerbosity()) +const nonlinear_verbose = ScopedValue{Union{NonlinearVerbosity{true}, NonlinearVerbosity{false}}}() include("abstract_types.jl") include("common_defaults.jl") From c1230351d29b169a2c43122271e15c3f4826ff05 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 21:21:44 -0400 Subject: [PATCH 11/51] these don't need to be mutable --- lib/NonlinearSolveBase/src/verbosity.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index dfbfaa944..db76ffc59 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -11,7 +11,7 @@ nonlinear_verbosity_defaults = Dict( ) -mutable struct NonlinearErrorControlVerbosity +struct NonlinearErrorControlVerbosity immutable_u0::Verbosity.Type non_enclosing_interval::Verbosity.Type non_forward_mode::Verbosity.Type @@ -49,7 +49,7 @@ function NonlinearErrorControlVerbosity(verbose::Verbosity.Type) end end -mutable struct NonlinearPerformanceVerbosity +struct NonlinearPerformanceVerbosity colorvec_non_sparse::Verbosity.Type colorvec_no_prototype::Verbosity.Type sparsity_using_jac_prototype::Verbosity.Type @@ -94,16 +94,16 @@ end function NonlinearNumericalVerbosity(verbose::Verbosity.Type) @match verbose begin Verbosity.None() => NonlinearNumericalVerbosity(fill( - Verbosity.None(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.None(), length(fieldnames(NonlinearNumericalVerbosity)))...) Verbosity.Info() => NonlinearNumericalVerbosity(fill( - Verbosity.Info(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.Info(), length(fieldnames(NonlinearNumericalVerbosity)))...) Verbosity.Warn() => NonlinearNumericalVerbosity(fill( - Verbosity.Warn(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.Warn(), length(fieldnames(NonlinearNumericalVerbosity)))...) Verbosity.Error() => NonlinearNumericalVerbosity(fill( - Verbosity.Error(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.Error(), length(fieldnames(NonlinearNumericalVerbosity)))...) Verbosity.Default() => NonlinearNumericalVerbosity() From 6dcc91fe166f6c62e3159f6b24186cf7ae20ac8a Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 21:22:24 -0400 Subject: [PATCH 12/51] fix kwargs --- .../ext/NonlinearSolveBaseLinearSolveExt.jl | 2 +- lib/NonlinearSolveFirstOrder/src/solve.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl index feaa277bc..ad35df6c2 100644 --- a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl +++ b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl @@ -12,7 +12,7 @@ using NonlinearSolveBase: NonlinearSolveBase, LinearSolveJLCache, LinearSolveRes function (cache::LinearSolveJLCache)(; A = nothing, b = nothing, linu = nothing, - reuse_A_if_factorization = false, verbose = NonlinearVerbosity(), kwargs... + reuse_A_if_factorization = false, kwargs... ) cache.stats.nsolve += 1 diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index f720092f7..874f5dbc4 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -130,7 +130,7 @@ function SciMLBase.__init( stats = NLStats(0, 0, 0, 0, 0), alias_u0 = false, maxiters = 1000, abstol = nothing, reltol = nothing, maxtime = nothing, termination_condition = nothing, internalnorm::IN = L2_NORM, - linsolve_kwargs = (;), initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), verbose = NonlinearVerbosity(), kwargs... + linsolve_kwargs = (;), initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), kwargs... ) where {IN} @set! alg.autodiff = NonlinearSolveBase.select_jacobian_autodiff(prob, alg.autodiff) provided_jvp_autodiff = alg.jvp_autodiff !== nothing @@ -174,7 +174,7 @@ function SciMLBase.__init( descent_cache = InternalAPI.init( prob, alg.descent, J, fu, u; stats, abstol, reltol, internalnorm, - linsolve_kwargs, timer, verbose + linsolve_kwargs, timer ) du = SciMLBase.get_du(descent_cache) From 48bd8e6fc5aa111f5d5efd297aa46558fa7e8aff Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 21:55:29 -0400 Subject: [PATCH 13/51] redundant linsolve kwargs --- .../src/descent/damped_newton.jl | 10 --------- lib/NonlinearSolveBase/src/descent/newton.jl | 21 ------------------- .../src/descent/steepest.jl | 11 ---------- 3 files changed, 42 deletions(-) diff --git a/lib/NonlinearSolveBase/src/descent/damped_newton.jl b/lib/NonlinearSolveBase/src/descent/damped_newton.jl index 2e0884acb..8058a48a5 100644 --- a/lib/NonlinearSolveBase/src/descent/damped_newton.jl +++ b/lib/NonlinearSolveBase/src/descent/damped_newton.jl @@ -135,16 +135,6 @@ function InternalAPI.init( A, b = Utils.maybe_symmetric(J_damped), Utils.safe_vec(Jᵀfu) rhs_cache = nothing end - - if !haskey(linsolve_kwargs, :verbose) - if kwargs[:verbose].linear_verbosity isa Verbosity.Type - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose = LinearVerbosity(kwargs[:verbose]))) - else - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose = kwargs[:verbose].linear_verbosity)) - end - end lincache = construct_linear_solver( alg, alg.linsolve, A, b, Utils.safe_vec(u); diff --git a/lib/NonlinearSolveBase/src/descent/newton.jl b/lib/NonlinearSolveBase/src/descent/newton.jl index 54345234c..01fdf643c 100644 --- a/lib/NonlinearSolveBase/src/descent/newton.jl +++ b/lib/NonlinearSolveBase/src/descent/newton.jl @@ -36,16 +36,6 @@ function InternalAPI.init( @bb δu_ = similar(u) end - if !haskey(linsolve_kwargs, :verbose) - if kwargs[:verbose].linear_verbosity isa Verbosity.Type - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose = LinearVerbosity(kwargs[:verbose]))) - else - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose = kwargs[:verbose].linear_verbosity)) - end - end - if Utils.unwrap_val(pre_inverted) lincache = nothing else @@ -54,7 +44,6 @@ function InternalAPI.init( stats, abstol, reltol, linsolve_kwargs... ) end - #Main.@infiltrate return NewtonDescentCache( δu, δus, lincache, nothing, nothing, timer, pre_inverted, Val(false) ) @@ -84,16 +73,6 @@ function InternalAPI.init( A, b = J, Utils.safe_vec(fu) end - if !haskey(linsolve_kwargs, :verbose) - if kwargs[:verbose].linear_verbosity isa Verbosity.Type - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose=LinearVerbosity(kwargs[:verbose]))) - else - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose=kwargs[:verbose].linear_verbosity)) - end - end - lincache = construct_linear_solver( alg, alg.linsolve, A, b, Utils.safe_vec(u); stats, abstol, reltol, linsolve_kwargs... diff --git a/lib/NonlinearSolveBase/src/descent/steepest.jl b/lib/NonlinearSolveBase/src/descent/steepest.jl index aee6582dc..247490957 100644 --- a/lib/NonlinearSolveBase/src/descent/steepest.jl +++ b/lib/NonlinearSolveBase/src/descent/steepest.jl @@ -37,17 +37,6 @@ function InternalAPI.init( @bb δu_ = similar(u) end if Utils.unwrap_val(pre_inverted) - - if !haskey(linsolve_kwargs, :verbose) - if kwargs[:verbose].linear_verbosity isa Verbosity.Type - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose = LinearVerbosity(kwargs[:verbose]))) - else - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose = kwargs[:verbose].linear_verbosity)) - end - end - lincache = construct_linear_solver( alg, alg.linsolve, transpose(J), Utils.safe_vec(fu), Utils.safe_vec(u); stats, abstol, reltol, linsolve_kwargs... From c772d3cf0bdd7fe9bda7998513699128b270bf39 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 22:40:07 -0400 Subject: [PATCH 14/51] get rid of comments --- lib/NonlinearSolveBase/src/descent/newton.jl | 1 - lib/NonlinearSolveBase/src/linear_solve.jl | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/NonlinearSolveBase/src/descent/newton.jl b/lib/NonlinearSolveBase/src/descent/newton.jl index 01fdf643c..4dc347b7c 100644 --- a/lib/NonlinearSolveBase/src/descent/newton.jl +++ b/lib/NonlinearSolveBase/src/descent/newton.jl @@ -55,7 +55,6 @@ function InternalAPI.init( abstol = nothing, reltol = nothing, timer = get_timer_output(), kwargs... ) - #Main.@infiltrate length(fu) != length(u) && @assert !Utils.unwrap_val(pre_inverted) "Precomputed Inverse for Non-Square Jacobian doesn't make sense." diff --git a/lib/NonlinearSolveBase/src/linear_solve.jl b/lib/NonlinearSolveBase/src/linear_solve.jl index 5fa7b98d4..bec3134d3 100644 --- a/lib/NonlinearSolveBase/src/linear_solve.jl +++ b/lib/NonlinearSolveBase/src/linear_solve.jl @@ -71,7 +71,6 @@ 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) - #Main.@infiltrate # unlias here, we will later use these as caches lincache = init( linprob, linsolve; alias = LinearAliasSpecifier(alias_A = false, alias_b = false)) From 5d899876af09fcab60b3a553eeca9df06743b8cd Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 23 Jul 2025 22:40:25 -0400 Subject: [PATCH 15/51] resintate setup workload --- .../src/NonlinearSolveFirstOrder.jl | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl index 50a1f7e56..1193f112a 100644 --- a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl +++ b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl @@ -39,17 +39,17 @@ include("pseudo_transient.jl") include("poly_algs.jl") include("forward_diff.jl") -# @setup_workload begin -# nonlinear_functions = ( -# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), -# (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), -# (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) -# ) - -# nonlinear_problems = NonlinearProblem[] -# for (fn, u0) in nonlinear_functions -# push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) -# end +@setup_workload begin + nonlinear_functions = ( + (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1), + (NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]), + (NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]) + ) + + nonlinear_problems = NonlinearProblem[] + for (fn, u0) in nonlinear_functions + push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0)) + end nonlinear_functions = ( (NonlinearFunction{false, NoSpecialize}((u, p) -> (u .^ 2 .- p)[1:1]), [0.1, 0.0]), @@ -72,13 +72,13 @@ include("forward_diff.jl") ) ) -# nlls_problems = NonlinearLeastSquaresProblem[] -# for (fn, u0) in nonlinear_functions -# push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) -# end + nlls_problems = NonlinearLeastSquaresProblem[] + for (fn, u0) in nonlinear_functions + push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0)) + end -# nlp_algs = [NewtonRaphson(), TrustRegion(), LevenbergMarquardt()] -# nlls_algs = [GaussNewton(), TrustRegion(), LevenbergMarquardt()] + nlp_algs = [NewtonRaphson(), TrustRegion(), LevenbergMarquardt()] + nlls_algs = [GaussNewton(), TrustRegion(), LevenbergMarquardt()] @compile_workload begin @sync begin From e809f9d6f9609e3becb5e49cada1b5e0ce9a60f2 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 30 Jul 2025 11:38:37 -0400 Subject: [PATCH 16/51] get rid of ScopedValues experiment --- lib/NonlinearSolveBase/src/NonlinearSolveBase.jl | 3 --- lib/NonlinearSolveBase/src/solve.jl | 11 +++-------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index f8527d39e..246693ee6 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -36,7 +36,6 @@ using Setfield: @set! using LinearAlgebra: LinearAlgebra, Diagonal, norm, ldiv!, diagind, mul! using Markdown: @doc_str using Printf: @printf -using Base.ScopedValues const DI = DifferentiationInterface const SII = SymbolicIndexingInterface @@ -45,8 +44,6 @@ include("public.jl") include("utils.jl") include("verbosity.jl") -const nonlinear_verbose = ScopedValue{Union{NonlinearVerbosity{true}, NonlinearVerbosity{false}}}() - include("abstract_types.jl") include("common_defaults.jl") include("termination_conditions.jl") diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index 12da943c4..14dd58656 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -224,15 +224,8 @@ function SciMLBase.__solve( prob::AbstractNonlinearProblem, alg::AbstractNonlinearSolveAlgorithm, args...; verbose = NonlinearVerbosity(), linsolve_kwargs = (;), kwargs... ) - if !haskey(linsolve_kwargs, :verbose) - linsolve_kwargs = merge( - linsolve_kwargs, (; verbose = verbose.linear_verbosity)) - end - - @with nonlinear_verbose => verbose begin - cache = SciMLBase.__init(prob, alg, args...; linsolve_kwargs, kwargs...) + cache = SciMLBase.__init(prob, alg, args...; kwargs...) sol = CommonSolve.solve!(cache) - end return sol end @@ -538,6 +531,8 @@ end initializealg retcode::ReturnCode.T + + verbose end function get_abstol(cache::NonlinearSolveNoInitCache) From ff7cea2e52c33239c2c07945a65d64e1e6514d47 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 30 Jul 2025 11:38:48 -0400 Subject: [PATCH 17/51] add verbose to caches --- lib/NonlinearSolveBase/src/polyalg.jl | 2 ++ lib/NonlinearSolveFirstOrder/src/solve.jl | 2 ++ lib/NonlinearSolveQuasiNewton/src/solve.jl | 2 ++ lib/NonlinearSolveSpectralMethods/src/solve.jl | 2 ++ 4 files changed, 8 insertions(+) diff --git a/lib/NonlinearSolveBase/src/polyalg.jl b/lib/NonlinearSolveBase/src/polyalg.jl index 74fc2df1f..2ae7e5521 100644 --- a/lib/NonlinearSolveBase/src/polyalg.jl +++ b/lib/NonlinearSolveBase/src/polyalg.jl @@ -61,6 +61,8 @@ end alias_u0::Bool initializealg + + verbose end function update_initial_values!(cache::NonlinearSolvePolyAlgorithmCache, u0, p) diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index 874f5dbc4..ed738f272 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -87,6 +87,8 @@ end kwargs initializealg + + verbose end function SciMLBase.get_du(cache::GeneralizedFirstOrderAlgorithmCache) diff --git a/lib/NonlinearSolveQuasiNewton/src/solve.jl b/lib/NonlinearSolveQuasiNewton/src/solve.jl index e24c6f45e..e57046244 100644 --- a/lib/NonlinearSolveQuasiNewton/src/solve.jl +++ b/lib/NonlinearSolveQuasiNewton/src/solve.jl @@ -95,6 +95,8 @@ end # Initialization initializealg + + verbose end function SciMLBase.get_du(cache::QuasiNewtonCache) diff --git a/lib/NonlinearSolveSpectralMethods/src/solve.jl b/lib/NonlinearSolveSpectralMethods/src/solve.jl index 9bfd5709c..53b43c0d4 100644 --- a/lib/NonlinearSolveSpectralMethods/src/solve.jl +++ b/lib/NonlinearSolveSpectralMethods/src/solve.jl @@ -70,6 +70,8 @@ end kwargs initializealg + + verbose end function SciMLBase.get_du(cache::GeneralizedDFSaneCache) From cdbba29010a17ec9ca13603416a0fcb1583e77c3 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 30 Jul 2025 16:53:03 -0400 Subject: [PATCH 18/51] add verbosity messages, fix constructor --- lib/NonlinearSolveBase/src/verbosity.jl | 31 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index db76ffc59..91585e498 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -7,7 +7,13 @@ nonlinear_verbosity_defaults = Dict( :colorvec_non_sparse => Verbosity.Warn(), :colorvec_no_prototype => Verbosity.Warn(), :sparsity_using_jac_prototype => Verbosity.Warn(), - :sparse_matrixcolorings_not_loaded => Verbosity.Warn() + :sparse_matrixcolorings_not_loaded => Verbosity.Warn(), + :alias_u0_immutable => Verbosity.Warn(), + :linsovle_failed_noncurrent => Verbosity.Warn(), + :jacobian_free => Verbosity.Warn(), + :termination_condition => Verbosity.Warn(), + :threshold_state => Verbosity.Warn(), + :pinv_undefined => Verbosity.Warn() ) @@ -17,13 +23,22 @@ struct NonlinearErrorControlVerbosity non_forward_mode::Verbosity.Type fd_ad_caution::Verbosity.Type ad_backend_incompatible::Verbosity.Type + alias_u0_immutable::Verbosity.Type + linsolve_failed_noncurrent::Verbosity.Type + jacobian_free::Verbosity.Type + termination_condition::Verbosity.Type function NonlinearErrorControlVerbosity(immutable_u0 = nonlinear_verbosity_defaults[:immutable_u0], non_enclosing_interval = nonlinear_verbosity_defaults[:non_enclosing_interval], non_forward_mode = nonlinear_verbosity_defaults[:non_forward_mode], fd_ad_caution = nonlinear_verbosity_defaults[:fd_ad_caution], - ad_backend_incompatible = nonlinear_verbosity_defaults[:ad_backend_incompatible]) - new(immutable_u0, non_enclosing_interval, non_forward_mode, fd_ad_caution, ad_backend_incompatible) + ad_backend_incompatible = nonlinear_verbosity_defaults[:ad_backend_incompatible], + alias_u0_immutable = nonlinear_verbosity_defaults[:alias_u0_immutable], + linsolve_failed_noncurrent = nonlinear_verbosity_defaults[:linsolve_failed_noncurrent], + jacobian_free = nonlinear_verbosity_defaults[:jacobian_free], + termination_condition = nonlinear_verbosity_defaults[:termination_condition]) + new(immutable_u0, non_enclosing_interval, non_forward_mode, fd_ad_caution, ad_backend_incompatible, + alias_u0_immutable, linsolve_failed_noncurrent, jacobian_free, termination_condition) end end @@ -38,7 +53,7 @@ function NonlinearErrorControlVerbosity(verbose::Verbosity.Type) Verbosity.Warn() => NonlinearErrorControlVerbosity(fill( Verbosity.Warn(), length(fieldnames(NonlinearErrorControlVerbosity)))...) - Verbosity.Error() => NonlinearNumericalVerbosity(fill( + Verbosity.Error() => NonlinearErrorControlVerbosity(fill( Verbosity.Error(), length(fieldnames(NonlinearErrorControlVerbosity)))...) Verbosity.Default() => NonlinearErrorControlVerbosity() @@ -86,8 +101,12 @@ function NonlinearPerformanceVerbosity(verbose::Verbosity.Type) end mutable struct NonlinearNumericalVerbosity - function NonlinearNumericalVerbosity() - new() + threshold_state::Verbosity.Type + pinv_undefined::Verbosity.Type + function NonlinearNumericalVerbosity(; + threshold_state = nonlinear_verbosity_defaults[:threshold_state], + pinv_undefined = nonlinear_verbosity_defaults[:pinv_undefined]) + new(threshold_state, pinv_undefined) end end From 5452f62cc0bf7f91b08012ed9082f9c3ff989264 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 30 Jul 2025 16:53:23 -0400 Subject: [PATCH 19/51] imports, other preparations --- lib/BracketingNonlinearSolve/src/bisection.jl | 2 +- lib/BracketingNonlinearSolve/src/brent.jl | 2 +- lib/BracketingNonlinearSolve/src/falsi.jl | 2 +- lib/BracketingNonlinearSolve/src/itp.jl | 2 +- lib/BracketingNonlinearSolve/src/ridder.jl | 2 +- .../ext/NonlinearSolveBaseLinearSolveExt.jl | 1 + lib/NonlinearSolveBase/src/abstract_types.jl | 1 + lib/NonlinearSolveBase/src/descent/newton.jl | 9 +++++++++ lib/NonlinearSolveBase/src/descent/steepest.jl | 6 ++++++ lib/NonlinearSolveBase/src/jacobian.jl | 8 ++++---- lib/NonlinearSolveBase/src/polyalg.jl | 4 ++-- lib/NonlinearSolveBase/src/solve.jl | 16 +++++++--------- .../src/NonlinearSolveFirstOrder.jl | 3 ++- lib/NonlinearSolveFirstOrder/src/solve.jl | 10 ++++------ .../src/NonlinearSolveQuasiNewton.jl | 3 ++- .../src/initialization.jl | 6 +++--- lib/NonlinearSolveQuasiNewton/src/solve.jl | 11 ++++++----- .../src/NonlinearSolveSpectralMethods.jl | 2 +- lib/NonlinearSolveSpectralMethods/src/solve.jl | 9 +++++---- .../src/SimpleNonlinearSolve.jl | 2 +- lib/SimpleNonlinearSolve/src/lbroyden.jl | 6 +++--- 21 files changed, 62 insertions(+), 45 deletions(-) diff --git a/lib/BracketingNonlinearSolve/src/bisection.jl b/lib/BracketingNonlinearSolve/src/bisection.jl index 0bc6bbd17..95ed2fe07 100644 --- a/lib/BracketingNonlinearSolve/src/bisection.jl +++ b/lib/BracketingNonlinearSolve/src/bisection.jl @@ -47,7 +47,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - nonlinear_verbose[], :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/brent.jl b/lib/BracketingNonlinearSolve/src/brent.jl index 5fca94d9e..cb880b54d 100644 --- a/lib/BracketingNonlinearSolve/src/brent.jl +++ b/lib/BracketingNonlinearSolve/src/brent.jl @@ -35,7 +35,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - nonlinear_verbose[], :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/falsi.jl b/lib/BracketingNonlinearSolve/src/falsi.jl index 87ee76953..22ba29a88 100644 --- a/lib/BracketingNonlinearSolve/src/falsi.jl +++ b/lib/BracketingNonlinearSolve/src/falsi.jl @@ -34,7 +34,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - nonlinear_verbose[], :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/itp.jl b/lib/BracketingNonlinearSolve/src/itp.jl index beaad67de..f9791bddf 100644 --- a/lib/BracketingNonlinearSolve/src/itp.jl +++ b/lib/BracketingNonlinearSolve/src/itp.jl @@ -85,7 +85,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - nonlinear_verbose[], :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/ridder.jl b/lib/BracketingNonlinearSolve/src/ridder.jl index fa28d8f35..62207f510 100644 --- a/lib/BracketingNonlinearSolve/src/ridder.jl +++ b/lib/BracketingNonlinearSolve/src/ridder.jl @@ -34,7 +34,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - nonlinear_verbose[], :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval, :error_control) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl index ad35df6c2..6ccc2b1d6 100644 --- a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl +++ b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl @@ -5,6 +5,7 @@ using ArrayInterface: ArrayInterface using CommonSolve: CommonSolve, init, solve! using LinearSolve: LinearSolve, QRFactorization, SciMLLinearSolveAlgorithm using SciMLBase: ReturnCode, LinearProblem, LinearAliasSpecifier +using SciMLVerbosity: @SciMLMessage using LinearAlgebra: ColumnNorm diff --git a/lib/NonlinearSolveBase/src/abstract_types.jl b/lib/NonlinearSolveBase/src/abstract_types.jl index 6b78940f5..a6bfdef7d 100644 --- a/lib/NonlinearSolveBase/src/abstract_types.jl +++ b/lib/NonlinearSolveBase/src/abstract_types.jl @@ -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 diff --git a/lib/NonlinearSolveBase/src/descent/newton.jl b/lib/NonlinearSolveBase/src/descent/newton.jl index 4dc347b7c..8a968d58f 100644 --- a/lib/NonlinearSolveBase/src/descent/newton.jl +++ b/lib/NonlinearSolveBase/src/descent/newton.jl @@ -39,6 +39,10 @@ function InternalAPI.init( 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... @@ -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... diff --git a/lib/NonlinearSolveBase/src/descent/steepest.jl b/lib/NonlinearSolveBase/src/descent/steepest.jl index 247490957..8ca7d35f6 100644 --- a/lib/NonlinearSolveBase/src/descent/steepest.jl +++ b/lib/NonlinearSolveBase/src/descent/steepest.jl @@ -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... diff --git a/lib/NonlinearSolveBase/src/jacobian.jl b/lib/NonlinearSolveBase/src/jacobian.jl index d7d86ba05..7cf106409 100644 --- a/lib/NonlinearSolveBase/src/jacobian.jl +++ b/lib/NonlinearSolveBase/src/jacobian.jl @@ -182,15 +182,15 @@ function construct_concrete_adtype(f::NonlinearFunction, ad::AbstractADType) if f.sparsity === nothing if f.jac_prototype === nothing if SciMLBase.has_colorvec(f) - @SciMLMessage("`colorvec` is provided but `sparsity` and `jac_prototype` is not \ - specified. `colorvec` will be ignored.", nonlinear_verbose[], :colorvec_no_prototype, :performance ) + @warn "`colorvec` is provided but `sparsity` and `jac_prototype` is not \ + specified. `colorvec` will be ignored." end return ad # No sparse AD else if !sparse_or_structured_prototype(f.jac_prototype) if SciMLBase.has_colorvec(f) - @SciMLMessage("`colorvec` is provided but `jac_prototype` is not a sparse \ - or structured matrix. `colorvec` will be ignored.", nonlinear_verbose[], :colorvec_non_sparse, :performance) + @warn "`colorvec` is provided but `jac_prototype` is not a sparse \ + or structured matrix. `colorvec` will be ignored." end return ad end diff --git a/lib/NonlinearSolveBase/src/polyalg.jl b/lib/NonlinearSolveBase/src/polyalg.jl index 2ae7e5521..5c1e0041a 100644 --- a/lib/NonlinearSolveBase/src/polyalg.jl +++ b/lib/NonlinearSolveBase/src/polyalg.jl @@ -123,8 +123,8 @@ function SciMLBase.__init( 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 diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index 14dd58656..d8de61254 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -221,11 +221,9 @@ function init_call(_prob, args...; merge_callbacks=true, kwargshandle=nothing, end function SciMLBase.__solve( - prob::AbstractNonlinearProblem, alg::AbstractNonlinearSolveAlgorithm, args...; - verbose = NonlinearVerbosity(), linsolve_kwargs = (;), kwargs... -) - cache = SciMLBase.__init(prob, alg, args...; kwargs...) - sol = CommonSolve.solve!(cache) + prob::AbstractNonlinearProblem, alg::AbstractNonlinearSolveAlgorithm, args...; kwargs...) + cache = SciMLBase.__init(prob, alg, args...; kwargs...) + sol = CommonSolve.solve!(cache) return sol end @@ -386,8 +384,8 @@ end calls = [quote current = alg.start_index 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 end] @@ -565,11 +563,11 @@ end function SciMLBase.__init( prob::AbstractNonlinearProblem, alg::AbstractNonlinearSolveAlgorithm, args...; - initializealg = NonlinearSolveDefaultInit(), + initializealg = NonlinearSolveDefaultInit(), verbose = NonlinearVerbosity(), kwargs... ) cache = NonlinearSolveNoInitCache( - prob, alg, args, kwargs, initializealg, ReturnCode.Default) + prob, alg, args, kwargs, initializealg, ReturnCode.Default, verbose) run_initialization!(cache) return cache end diff --git a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl index 1193f112a..57f94212f 100644 --- a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl +++ b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl @@ -21,7 +21,8 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, Utils, InternalAPI, get_timer_output, @static_timeit, update_trace!, L2_NORM, NonlinearSolvePolyAlgorithm, NewtonDescent, DampedNewtonDescent, GeodesicAcceleration, - Dogleg, NonlinearSolveForwardDiffCache, NonlinearVerbosity, reused_jacobian + Dogleg, NonlinearSolveForwardDiffCache, NonlinearVerbosity, + @SciMLMessage, reused_jacobian using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearFunction, NonlinearLeastSquaresProblem, NonlinearProblem, NoSpecialize diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index ed738f272..da4fda0b3 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -131,7 +131,7 @@ function SciMLBase.__init( prob::AbstractNonlinearProblem, alg::GeneralizedFirstOrderAlgorithm, args...; stats = NLStats(0, 0, 0, 0, 0), alias_u0 = false, maxiters = 1000, abstol = nothing, reltol = nothing, maxtime = nothing, - termination_condition = nothing, internalnorm::IN = L2_NORM, + termination_condition = nothing, internalnorm::IN = L2_NORM, verbose = NonlinearVerbosity(), linsolve_kwargs = (;), initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), kwargs... ) where {IN} @set! alg.autodiff = NonlinearSolveBase.select_jacobian_autodiff(prob, alg.autodiff) @@ -223,7 +223,7 @@ function SciMLBase.__init( jac_cache, descent_cache, linesearch_cache, trustregion_cache, stats, 0, maxiters, maxtime, alg.max_shrink_times, timer, 0.0, true, termination_cache, trace, ReturnCode.Default, false, kwargs, - initializealg + initializealg, verbose ) NonlinearSolveBase.run_initialization!(cache) end @@ -267,10 +267,8 @@ function InternalAPI.step!( return else # Jacobian Information is not current and linear solve failed, recompute it - if !haskey(cache.kwargs, :verbose) || cache.kwargs[:verbose] - @warn "Linear Solve Failed but Jacobian Information is not current. \ - Retrying with updated Jacobian." - end + @SciMLMessage("Linear Solve Failed but Jacobian information is not current. Retrying with updated Jacobian. \ + Retrying with updated Jacobian.", cache.verbose, :linsolve_failed_noncurrent, :error_control) # In the 2nd call the `new_jacobian` is guaranteed to be `true`. cache.make_new_jacobian = true InternalAPI.step!(cache; recompute_jacobian = true, cache.kwargs...) diff --git a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl index 795858468..1114eaa8c 100644 --- a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl +++ b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl @@ -18,7 +18,8 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractApproximateJacobianUpdateRule, AbstractDescentDirection, AbstractApproximateJacobianUpdateRuleCache, Utils, InternalAPI, get_timer_output, @static_timeit, - update_trace!, L2_NORM, NewtonDescent, NonlinearVerbosity, reused_jacobian + update_trace!, L2_NORM, NewtonDescent, NonlinearVerbosity, + @SciMLMessage, reused_jacobian using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize using SciMLOperators: AbstractSciMLOperator diff --git a/lib/NonlinearSolveQuasiNewton/src/initialization.jl b/lib/NonlinearSolveQuasiNewton/src/initialization.jl index 413cd0896..3af660c0e 100644 --- a/lib/NonlinearSolveQuasiNewton/src/initialization.jl +++ b/lib/NonlinearSolveQuasiNewton/src/initialization.jl @@ -153,7 +153,7 @@ NonlinearSolveBase.jacobian_initialized_preinverted(::BroydenLowRankInitializati function InternalAPI.init( prob::AbstractNonlinearProblem, alg::BroydenLowRankInitialization, solver, f::F, fu, u, p; - internalnorm::IN = L2_NORM, maxiters = 1000, kwargs... + internalnorm::IN = L2_NORM, maxiters = 1000, verbose = NonlinearVerbosity(), kwargs... ) where {F, IN} if u isa Number # Use the standard broyden return InternalAPI.init( @@ -168,8 +168,8 @@ function InternalAPI.init( else threshold = min(Utils.unwrap_val(alg.threshold), maxiters) if threshold > length(u) - @warn "`threshold` is larger than the size of the state, which may cause \ - numerical instability. Consider reducing `threshold`." + @SciMLMessage("`threshold` is larger than the size of the state, which may cause \ + numerical instability. Consider reducing `threshold`.", verbose, :threshold_state, :numerical) end J = BroydenLowRankJacobian(fu, u; threshold, alpha = α) end diff --git a/lib/NonlinearSolveQuasiNewton/src/solve.jl b/lib/NonlinearSolveQuasiNewton/src/solve.jl index e57046244..a44439a9f 100644 --- a/lib/NonlinearSolveQuasiNewton/src/solve.jl +++ b/lib/NonlinearSolveQuasiNewton/src/solve.jl @@ -151,6 +151,7 @@ function SciMLBase.__init( maxiters = 1000, abstol = nothing, reltol = nothing, linsolve_kwargs = (;), termination_condition = nothing, internalnorm::F = L2_NORM, initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), + verbose = NonlinearVerbosity(), kwargs... ) where {F} timer = get_timer_output() @@ -233,7 +234,7 @@ function SciMLBase.__init( trustregion_cache, update_rule_cache, reinit_rule_cache, inv_workspace, stats, 0, 0, alg.max_resets, maxiters, maxtime, alg.max_shrink_times, 0, timer, 0.0, termination_cache, trace, - ReturnCode.Default, false, false, kwargs, initializealg + ReturnCode.Default, false, false, kwargs, initializealg, verbose ) NonlinearSolveBase.run_initialization!(cache) end @@ -335,10 +336,10 @@ function InternalAPI.step!( return else # Force a reinit because the problem is currently un-solvable - if !haskey(cache.kwargs, :verbose) || cache.kwargs[:verbose] - @warn "Linear Solve Failed but Jacobian Information is not current. \ - Retrying with reinitialized Approximate Jacobian." - end + + @SciMLMessage("Linear Solve Failed but Jacobian information is not current. Retrying with updated Jacobian. \ + Retrying with updated Jacobian.", cache.verbose, :linsolve_failed_noncurrent, :error_control) + cache.force_reinit = true InternalAPI.step!(cache; recompute_jacobian = true) return diff --git a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl index 803dd8ff9..ab4ec2443 100644 --- a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl +++ b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl @@ -9,7 +9,7 @@ using LineSearch: RobustNonMonotoneLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractNonlinearSolveCache, Utils, InternalAPI, get_timer_output, - @static_timeit, update_trace!, NonlinearVerbosity + @static_timeit, update_trace!, NonlinearVerbosity, @SciMLMessage using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize diff --git a/lib/NonlinearSolveSpectralMethods/src/solve.jl b/lib/NonlinearSolveSpectralMethods/src/solve.jl index 53b43c0d4..6b532a35a 100644 --- a/lib/NonlinearSolveSpectralMethods/src/solve.jl +++ b/lib/NonlinearSolveSpectralMethods/src/solve.jl @@ -126,7 +126,8 @@ function SciMLBase.__init( prob::AbstractNonlinearProblem, alg::GeneralizedDFSane, args...; stats = NLStats(0, 0, 0, 0, 0), alias_u0 = false, maxiters = 1000, abstol = nothing, reltol = nothing, termination_condition = nothing, - maxtime = nothing, initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), kwargs... + maxtime = nothing, verbose = NonlinearVerbosity(), + initializealg = NonlinearSolveBase.NonlinearSolveDefaultInit(), kwargs... ) timer = get_timer_output() @@ -164,7 +165,7 @@ function SciMLBase.__init( fu, fu_cache, u, u_cache, prob.p, du, alg, prob, σ_n, T(alg.σ_min), T(alg.σ_max), linesearch_cache, stats, 0, maxiters, maxtime, timer, 0.0, - tc_cache, trace, ReturnCode.Default, false, kwargs, initializealg + tc_cache, trace, ReturnCode.Default, false, kwargs, initializealg, verbose ) NonlinearSolveBase.run_initialization!(cache) end @@ -177,8 +178,8 @@ function InternalAPI.step!( kwargs... ) if recompute_jacobian !== nothing - @warn "GeneralizedDFSane is a Jacobian-Free Algorithm. Ignoring \ - `recompute_jacobian`" maxlog=1 + @SciMLMessage("GeneralizedDFSane is a Jacobian-Free Algorithm. Ignoring \ + `recompute_jacobian`", cache.verbose, :jacobian_free, :error_control) end @static_timeit cache.timer "descent" begin diff --git a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl index 45fbcd237..42be539ec 100644 --- a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl +++ b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl @@ -12,7 +12,7 @@ using LineSearch: LiFukushimaLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, ImmutableNonlinearProblem, L2_NORM, nonlinearsolve_forwarddiff_solve, nonlinearsolve_dual_solution, - AbstractNonlinearSolveAlgorithm, NonlinearVerbosity + AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage using SciMLBase: SciMLBase, NonlinearFunction, NonlinearProblem, NonlinearLeastSquaresProblem, ReturnCode, remake diff --git a/lib/SimpleNonlinearSolve/src/lbroyden.jl b/lib/SimpleNonlinearSolve/src/lbroyden.jl index 979b244f8..24ffc2cfa 100644 --- a/lib/SimpleNonlinearSolve/src/lbroyden.jl +++ b/lib/SimpleNonlinearSolve/src/lbroyden.jl @@ -36,7 +36,7 @@ end function SciMLBase.__solve( prob::ImmutableNonlinearProblem, alg::SimpleLimitedMemoryBroyden, - args...; termination_condition = nothing, kwargs...) + args...; termination_condition = nothing, verbose = NonlinearVerbosity(), kwargs...) if prob.u0 isa SArray if termination_condition === nothing || termination_condition isa NonlinearSolveBase.AbsNormTerminationMode @@ -44,10 +44,10 @@ function SciMLBase.__solve( prob, alg, args...; termination_condition, kwargs... ) end - @warn "Specifying `termination_condition = $(termination_condition)` for \ + @SciMLMessage("Specifying `termination_condition = $(termination_condition)` for \ `SimpleLimitedMemoryBroyden` with `SArray` is not non-allocating. Use \ either `termination_condition = AbsNormTerminationMode(Base.Fix2(norm, Inf))` \ - or `termination_condition = nothing`." maxlog=1 + or `termination_condition = nothing`.", verbose, :termination_condition, :error_control) end return internal_generic_solve(prob, alg, args...; termination_condition, kwargs...) end From e312c2ce3bf7e05acfa9102caebd1081049d511e Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 12:10:09 -0400 Subject: [PATCH 20/51] make sure that LinearVerbosity is passed to linsolve --- lib/NonlinearSolveFirstOrder/src/solve.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index da4fda0b3..44095fc56 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -166,7 +166,7 @@ function SciMLBase.__init( termination_cache = NonlinearSolveBase.init_termination_cache( prob, abstol, reltol, fu, u, termination_condition, Val(:regular) ) - linsolve_kwargs = merge((; abstol, reltol), linsolve_kwargs) + linsolve_kwargs = merge((; verbose = verbose.linear_verbosity, abstol, reltol), linsolve_kwargs) jac_cache = NonlinearSolveBase.construct_jacobian_cache( prob, alg, prob.f, fu, u, prob.p; From c7070bf5abf66489941d2d2a5e7fc722ac8942d5 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 12:11:42 -0400 Subject: [PATCH 21/51] ensure that LinearVerbosity is passed on in more places --- lib/NonlinearSolveQuasiNewton/src/solve.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveQuasiNewton/src/solve.jl b/lib/NonlinearSolveQuasiNewton/src/solve.jl index a44439a9f..e74cdc925 100644 --- a/lib/NonlinearSolveQuasiNewton/src/solve.jl +++ b/lib/NonlinearSolveQuasiNewton/src/solve.jl @@ -173,7 +173,7 @@ function SciMLBase.__init( termination_cache = NonlinearSolveBase.init_termination_cache( prob, abstol, reltol, fu, u, termination_condition, Val(:regular) ) - linsolve_kwargs = merge((; abstol, reltol), linsolve_kwargs) + linsolve_kwargs = merge((;verbose = verbose.linear_verbosity, abstol, reltol), linsolve_kwargs) J = initialization_cache(nothing) From a3703e15c18305d99ceea72e555cd3f27213a09d Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 13:21:34 -0400 Subject: [PATCH 22/51] typo, struct should be mutable --- lib/NonlinearSolveBase/src/verbosity.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index 91585e498..2be39584f 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -9,7 +9,7 @@ nonlinear_verbosity_defaults = Dict( :sparsity_using_jac_prototype => Verbosity.Warn(), :sparse_matrixcolorings_not_loaded => Verbosity.Warn(), :alias_u0_immutable => Verbosity.Warn(), - :linsovle_failed_noncurrent => Verbosity.Warn(), + :linsolve_failed_noncurrent => Verbosity.Warn(), :jacobian_free => Verbosity.Warn(), :termination_condition => Verbosity.Warn(), :threshold_state => Verbosity.Warn(), @@ -17,7 +17,7 @@ nonlinear_verbosity_defaults = Dict( ) -struct NonlinearErrorControlVerbosity +mutable struct NonlinearErrorControlVerbosity immutable_u0::Verbosity.Type non_enclosing_interval::Verbosity.Type non_forward_mode::Verbosity.Type @@ -64,7 +64,7 @@ function NonlinearErrorControlVerbosity(verbose::Verbosity.Type) end end -struct NonlinearPerformanceVerbosity +mutable struct NonlinearPerformanceVerbosity colorvec_non_sparse::Verbosity.Type colorvec_no_prototype::Verbosity.Type sparsity_using_jac_prototype::Verbosity.Type From 89e1a08b50c791a9ee762a4777dd7b06e0bdeabc Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 13:49:59 -0400 Subject: [PATCH 23/51] turn back messages that don't have access to verbose to warn --- lib/NonlinearSolveBase/src/autodiff.jl | 20 +++++++++----------- lib/NonlinearSolveBase/src/jacobian.jl | 12 ++++++------ 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/lib/NonlinearSolveBase/src/autodiff.jl b/lib/NonlinearSolveBase/src/autodiff.jl index 63ea1f40a..857e64509 100644 --- a/lib/NonlinearSolveBase/src/autodiff.jl +++ b/lib/NonlinearSolveBase/src/autodiff.jl @@ -25,17 +25,16 @@ function select_forward_mode_autodiff( !is_finite_differences_backend(ad) @warn lazy"The chosen AD backend $(ad) is not a forward mode AD. Use with caution." - @SciMLMessage("The chosen AD backend $(ad) is not a forward mode AD. Use with caution.", - nonlinear_verbose[], :fd_ad_caution, :error_control) + @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 lazy"The chosen AD backend `$(ad)` does not support the chosen problem. This \ + + @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 \ - backend.", nonlinear_verbose[], :ad_backend_incompatible, :error_control) - + backend." return adₙ end return ad @@ -55,15 +54,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) - @SciMLMessage("The chosen AD backend $(ad) is not a forward mode AD. Use with caution.", - nonlinear_verbose[], :fd_ad_caution, :error_control) + @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) - @SciMLMessage("The chosen AD backend `$(ad)` does not support the chosen problem. This \ + @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 \ - backend.", nonlinear_verbose[], :ad_backend_incompatible, :error_control) + backend." return adₙ end return ad @@ -81,10 +79,10 @@ end function select_jacobian_autodiff(prob::AbstractNonlinearProblem, ad::AbstractADType) if incompatible_backend_and_problem(prob, ad) adₙ = select_jacobian_autodiff(prob, nothing) - @SciMLMessage("The chosen AD backend `$(ad)` does not support the chosen problem. This \ + @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 \ - backend.", nonlinear_verbose[], :ad_backend_incompatible, :error_control) + backend." return adₙ end return ad diff --git a/lib/NonlinearSolveBase/src/jacobian.jl b/lib/NonlinearSolveBase/src/jacobian.jl index 7cf106409..e5889036b 100644 --- a/lib/NonlinearSolveBase/src/jacobian.jl +++ b/lib/NonlinearSolveBase/src/jacobian.jl @@ -225,8 +225,8 @@ function construct_concrete_adtype(f::NonlinearFunction, ad::AbstractADType) sparsity_detector = f.sparsity if f.jac_prototype === nothing if SciMLBase.has_colorvec(f) - @SciMLMessage("`colorvec` is provided but `jac_prototype` is not specified. \ - `colorvec` will be ignored.", nonlinear_verbose[], :colorvec_no_prototype, :performance) + @warn "`colorvec` is provided but `jac_prototype` is not specified. \ + `colorvec` will be ignored." end coloring_algorithm = select_fastest_coloring_algorithm(nothing, f, ad) coloring_algorithm === nothing && return ad @@ -234,9 +234,9 @@ function construct_concrete_adtype(f::NonlinearFunction, ad::AbstractADType) else if sparse_or_structured_prototype(f.jac_prototype) if !(sparsity_detector isa NoSparsityDetector) - @SciMLMessage("`jac_prototype` is a sparse matrix but sparsity = $(f.sparsity) \ + @warn "`jac_prototype` is a sparse matrix but sparsity = $(f.sparsity) \ has also been specified. Ignoring sparsity field and using \ - `jac_prototype` sparsity.", nonlinear_verbose[], :sparsity_using_jac_prototype, :performance) + `jac_prototype` sparsity." end sparsity_detector = KnownJacobianSparsityDetector(f.jac_prototype) end @@ -257,8 +257,8 @@ end function select_fastest_coloring_algorithm( prototype, f::NonlinearFunction, ad::AbstractADType) if !Utils.is_extension_loaded(Val(:SparseMatrixColorings)) - @SciMLMessage("`SparseMatrixColorings` must be explicitly imported for sparse automatic \ - differentiation to work. Proceeding with Dense Automatic Differentiation.", nonlinear_verbose[], :sparse_matrix_colorings_not_loaded, :performance) + @warn "`SparseMatrixColorings` must be explicitly imported for sparse automatic \ + differentiation to work. Proceeding with Dense Automatic Differentiation." return nothing end return select_fastest_coloring_algorithm(Val(:SparseMatrixColorings), prototype, f, ad) From edee93c402ce576d82b1651a3b9e563b62273184 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 13:50:31 -0400 Subject: [PATCH 24/51] make sure that verbosity is in polysolve cache --- lib/NonlinearSolveBase/src/polyalg.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/src/polyalg.jl b/lib/NonlinearSolveBase/src/polyalg.jl index 5c1e0041a..4105f94d1 100644 --- a/lib/NonlinearSolveBase/src/polyalg.jl +++ b/lib/NonlinearSolveBase/src/polyalg.jl @@ -143,7 +143,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 From 45edae400c209b0c3bebb5df7da3952349b0847e Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 13:50:38 -0400 Subject: [PATCH 25/51] add verbosity tests --- test/verbosity.jl | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/verbosity.jl diff --git a/test/verbosity.jl b/test/verbosity.jl new file mode 100644 index 000000000..176d439a2 --- /dev/null +++ b/test/verbosity.jl @@ -0,0 +1,42 @@ +@testitem "Nonlinear Verbosity" tags=[:misc] begin + using IntervalNonlinearSolve + using NonlinearSolve + using NonlinearSolve: NonlinearVerbosity + using LinearSolve: LinearVerbosity + using SciMLVerbosity: SciMLVerbosity, Verbosity + using Test + using Logging + + g(u, p) = u^2 - 4 + + int_prob = IntervalNonlinearProblem(g, (3.0, 5.0)) + + @test_logs (:info, + "The interval is not an enclosing interval, opposite signs at the boundaries are required.") solve( + int_prob, + ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = Verbosity.Info())) + + @test_logs (:error, + "The interval is not an enclosing interval, opposite signs at the boundaries are required.") solve( + int_prob, + ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = Verbosity.Error())) + + # Test that the linear verbosity is passed to the linear solve + f(u, p) = [u[1]^2 - 2u[1] + 1, sum(u)] + prob = NonlinearProblem(f, [1.0, 1.0]) + + @test_logs (:warn, + "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( + prob, + verbose = NonlinearVerbosity()) + + @test_logs (:info, + "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( + prob, + verbose = NonlinearVerbosity(linear_verbosity = LinearVerbosity(default_lu_fallback = Verbosity.Info()))) + + # Test that caches get correct verbosities + cache = init(prob, verbose = NonlinearVerbosity(threshold_state = Verbosity.Info())) + + @test cache.verbose.numerical.threshold_state == Verbosity.Info() +end From a549ddf0c240ed28ea7e929c6e799cac08b294dc Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 14:26:02 -0400 Subject: [PATCH 26/51] get rid of stale import, add compat bounds --- lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl | 2 +- lib/NonlinearSolveBase/Project.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl index 3198e9b44..0dae68c11 100644 --- a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl +++ b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl @@ -5,7 +5,7 @@ using PrecompileTools: @compile_workload, @setup_workload using Reexport: @reexport using CommonSolve: CommonSolve, solve -using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, Verbosity +using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage using SciMLBase: SciMLBase, IntervalNonlinearProblem, ReturnCode abstract type AbstractBracketingAlgorithm <: AbstractNonlinearSolveAlgorithm end diff --git a/lib/NonlinearSolveBase/Project.toml b/lib/NonlinearSolveBase/Project.toml index 6e56b4167..498b8036c 100644 --- a/lib/NonlinearSolveBase/Project.toml +++ b/lib/NonlinearSolveBase/Project.toml @@ -88,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" From d293b8afd022971af8862ff98773f4d7f449df0a Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 22:44:49 -0400 Subject: [PATCH 27/51] ensure backwards compatibility --- lib/BracketingNonlinearSolve/src/brent.jl | 10 ++++++++++ lib/BracketingNonlinearSolve/src/falsi.jl | 10 ++++++++++ lib/NonlinearSolveBase/src/polyalg.jl | 10 ++++++++++ lib/NonlinearSolveBase/src/solve.jl | 11 +++++++++++ lib/NonlinearSolveFirstOrder/src/solve.jl | 10 ++++++++++ lib/NonlinearSolveQuasiNewton/src/initialization.jl | 11 +++++++++++ lib/NonlinearSolveQuasiNewton/src/solve.jl | 11 +++++++++++ lib/NonlinearSolveSpectralMethods/src/solve.jl | 10 ++++++++++ lib/SimpleNonlinearSolve/src/lbroyden.jl | 11 +++++++++++ 9 files changed, 94 insertions(+) diff --git a/lib/BracketingNonlinearSolve/src/brent.jl b/lib/BracketingNonlinearSolve/src/brent.jl index cb880b54d..b4936ddb6 100644 --- a/lib/BracketingNonlinearSolve/src/brent.jl +++ b/lib/BracketingNonlinearSolve/src/brent.jl @@ -11,6 +11,16 @@ function SciMLBase.__solve( ) @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) diff --git a/lib/BracketingNonlinearSolve/src/falsi.jl b/lib/BracketingNonlinearSolve/src/falsi.jl index 22ba29a88..e529798ac 100644 --- a/lib/BracketingNonlinearSolve/src/falsi.jl +++ b/lib/BracketingNonlinearSolve/src/falsi.jl @@ -11,6 +11,16 @@ function SciMLBase.__solve( ) @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 diff --git a/lib/NonlinearSolveBase/src/polyalg.jl b/lib/NonlinearSolveBase/src/polyalg.jl index 4105f94d1..1b3420d8a 100644 --- a/lib/NonlinearSolveBase/src/polyalg.jl +++ b/lib/NonlinearSolveBase/src/polyalg.jl @@ -128,6 +128,16 @@ function SciMLBase.__init( 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)) diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index d8de61254..b7898d547 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -378,6 +378,17 @@ end stats = NLStats(0, 0, 0, 0, 0), alias_u0 = false, verbose = NonlinearVerbosity(), initializealg = NonlinearSolveDefaultInit(), kwargs... ) where {N} + + if verbose isa Bool + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(Verbosity.None()) + end + elseif verbose isa Verbosity.Type + verbose = NonlinearVerbosity(verbose) + end + sol_syms = [gensym("sol") for _ in 1:N] prob_syms = [gensym("prob") for _ in 1:N] u_result_syms = [gensym("u_result") for _ in 1:N] diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index 44095fc56..d7c718f6c 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -154,6 +154,16 @@ function SciMLBase.__init( NonlinearSolveBase.select_reverse_mode_autodiff(prob, alg.vjp_autodiff) end + if verbose isa Bool + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(Verbosity.None()) + end + elseif verbose isa Verbosity.Type + verbose = NonlinearVerbosity(verbose) + end + timer = get_timer_output() @static_timeit timer "cache construction" begin u = Utils.maybe_unaliased(prob.u0, alias_u0) diff --git a/lib/NonlinearSolveQuasiNewton/src/initialization.jl b/lib/NonlinearSolveQuasiNewton/src/initialization.jl index 3af660c0e..34844adba 100644 --- a/lib/NonlinearSolveQuasiNewton/src/initialization.jl +++ b/lib/NonlinearSolveQuasiNewton/src/initialization.jl @@ -161,6 +161,17 @@ function InternalAPI.init( solver, f, fu, u, p; internalnorm, maxiters, kwargs... ) end + + if verbose isa Bool + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(Verbosity.None()) + end + elseif verbose isa Verbosity.Type + verbose = NonlinearVerbosity(verbose) + end + # Pay to cost of slightly more allocations to prevent type-instability for StaticArrays α = inv(Utils.initial_jacobian_scaling_alpha(alg.alpha, u, fu, internalnorm)) if u isa StaticArray diff --git a/lib/NonlinearSolveQuasiNewton/src/solve.jl b/lib/NonlinearSolveQuasiNewton/src/solve.jl index e74cdc925..f8ffffdc4 100644 --- a/lib/NonlinearSolveQuasiNewton/src/solve.jl +++ b/lib/NonlinearSolveQuasiNewton/src/solve.jl @@ -156,6 +156,17 @@ function SciMLBase.__init( ) where {F} timer = get_timer_output() @static_timeit timer "cache construction" begin + + if verbose isa Bool + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(Verbosity.None()) + end + elseif verbose isa Verbosity.Type + verbose = NonlinearVerbosity(verbose) + end + u = Utils.maybe_unaliased(prob.u0, alias_u0) fu = Utils.evaluate_f(prob, u) @bb u_cache = copy(u) diff --git a/lib/NonlinearSolveSpectralMethods/src/solve.jl b/lib/NonlinearSolveSpectralMethods/src/solve.jl index 6b532a35a..038acde08 100644 --- a/lib/NonlinearSolveSpectralMethods/src/solve.jl +++ b/lib/NonlinearSolveSpectralMethods/src/solve.jl @@ -161,6 +161,16 @@ function SciMLBase.__init( σ_n = T(alg.σ_1) end + if verbose isa Bool + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(Verbosity.None()) + end + elseif verbose isa Verbosity.Type + verbose = NonlinearVerbosity(verbose) + end + cache = GeneralizedDFSaneCache( fu, fu_cache, u, u_cache, prob.p, du, alg, prob, σ_n, T(alg.σ_min), T(alg.σ_max), diff --git a/lib/SimpleNonlinearSolve/src/lbroyden.jl b/lib/SimpleNonlinearSolve/src/lbroyden.jl index 24ffc2cfa..d5a2ea425 100644 --- a/lib/SimpleNonlinearSolve/src/lbroyden.jl +++ b/lib/SimpleNonlinearSolve/src/lbroyden.jl @@ -44,6 +44,17 @@ function SciMLBase.__solve( prob, alg, args...; termination_condition, kwargs... ) end + + if verbose isa Bool + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(Verbosity.None()) + end + elseif verbose isa Verbosity.Type + verbose = NonlinearVerbosity(verbose) + end + @SciMLMessage("Specifying `termination_condition = $(termination_condition)` for \ `SimpleLimitedMemoryBroyden` with `SArray` is not non-allocating. Use \ either `termination_condition = AbsNormTerminationMode(Base.Fix2(norm, Inf))` \ From 817f3abfdc3dae348e61520a0edef8b565662f7d Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 23:40:11 -0400 Subject: [PATCH 28/51] import Verbosity for default verbosity --- lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl | 2 +- lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl | 2 +- lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl | 2 +- .../src/NonlinearSolveSpectralMethods.jl | 2 +- lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl index 0dae68c11..3198e9b44 100644 --- a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl +++ b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl @@ -5,7 +5,7 @@ using PrecompileTools: @compile_workload, @setup_workload using Reexport: @reexport using CommonSolve: CommonSolve, solve -using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage +using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, Verbosity using SciMLBase: SciMLBase, IntervalNonlinearProblem, ReturnCode abstract type AbstractBracketingAlgorithm <: AbstractNonlinearSolveAlgorithm end diff --git a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl index 57f94212f..5b29a2a82 100644 --- a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl +++ b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl @@ -22,7 +22,7 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, update_trace!, L2_NORM, NonlinearSolvePolyAlgorithm, NewtonDescent, DampedNewtonDescent, GeodesicAcceleration, Dogleg, NonlinearSolveForwardDiffCache, NonlinearVerbosity, - @SciMLMessage, reused_jacobian + @SciMLMessage, Verbosity, reused_jacobian using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearFunction, NonlinearLeastSquaresProblem, NonlinearProblem, NoSpecialize diff --git a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl index 1114eaa8c..73d85b8a0 100644 --- a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl +++ b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl @@ -19,7 +19,7 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractApproximateJacobianUpdateRuleCache, Utils, InternalAPI, get_timer_output, @static_timeit, update_trace!, L2_NORM, NewtonDescent, NonlinearVerbosity, - @SciMLMessage, reused_jacobian + @SciMLMessage, Verbosity, reused_jacobian using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize using SciMLOperators: AbstractSciMLOperator diff --git a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl index ab4ec2443..161c6e5da 100644 --- a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl +++ b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl @@ -9,7 +9,7 @@ using LineSearch: RobustNonMonotoneLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractNonlinearSolveCache, Utils, InternalAPI, get_timer_output, - @static_timeit, update_trace!, NonlinearVerbosity, @SciMLMessage + @static_timeit, update_trace!, NonlinearVerbosity, @SciMLMessage, Verbosity using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize diff --git a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl index 42be539ec..0d218561d 100644 --- a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl +++ b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl @@ -12,7 +12,7 @@ using LineSearch: LiFukushimaLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, ImmutableNonlinearProblem, L2_NORM, nonlinearsolve_forwarddiff_solve, nonlinearsolve_dual_solution, - AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage + AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, Verbosity using SciMLBase: SciMLBase, NonlinearFunction, NonlinearProblem, NonlinearLeastSquaresProblem, ReturnCode, remake From 184c02f3dce18fbb63d67a531e8bbe323d158d60 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 31 Jul 2025 23:58:27 -0400 Subject: [PATCH 29/51] make sure linear kwargs are passed --- lib/NonlinearSolveBase/src/linear_solve.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/src/linear_solve.jl b/lib/NonlinearSolveBase/src/linear_solve.jl index bec3134d3..90c04d210 100644 --- a/lib/NonlinearSolveBase/src/linear_solve.jl +++ b/lib/NonlinearSolveBase/src/linear_solve.jl @@ -70,7 +70,7 @@ 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) + linprob = LinearProblem(A, b; u0 = u_cache, kwargs...) # unlias here, we will later use these as caches lincache = init( linprob, linsolve; alias = LinearAliasSpecifier(alias_A = false, alias_b = false)) From 1bf1d3ef6ce518c2657f0b4296289daac83b15fe Mon Sep 17 00:00:00 2001 From: jClugstor Date: Fri, 1 Aug 2025 00:00:23 -0400 Subject: [PATCH 30/51] fix kwarg passing --- lib/NonlinearSolveBase/src/linear_solve.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/NonlinearSolveBase/src/linear_solve.jl b/lib/NonlinearSolveBase/src/linear_solve.jl index 90c04d210..cf4b14415 100644 --- a/lib/NonlinearSolveBase/src/linear_solve.jl +++ b/lib/NonlinearSolveBase/src/linear_solve.jl @@ -70,10 +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 From 5e5351c287ad662ac9fc0b3d969bd5e708ef8e92 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Fri, 1 Aug 2025 00:11:25 -0400 Subject: [PATCH 31/51] fix numerical verbosity --- lib/NonlinearSolveBase/src/verbosity.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index 2be39584f..c4f9aec0a 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -103,7 +103,7 @@ end mutable struct NonlinearNumericalVerbosity threshold_state::Verbosity.Type pinv_undefined::Verbosity.Type - function NonlinearNumericalVerbosity(; + function NonlinearNumericalVerbosity( threshold_state = nonlinear_verbosity_defaults[:threshold_state], pinv_undefined = nonlinear_verbosity_defaults[:pinv_undefined]) new(threshold_state, pinv_undefined) From e8d1449449b4d013937d8761c497cec14b9768e7 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Fri, 1 Aug 2025 00:11:55 -0400 Subject: [PATCH 32/51] add backwards compat tests for Bool verbose --- test/verbosity.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/verbosity.jl b/test/verbosity.jl index 176d439a2..062d3baae 100644 --- a/test/verbosity.jl +++ b/test/verbosity.jl @@ -35,6 +35,17 @@ prob, verbose = NonlinearVerbosity(linear_verbosity = LinearVerbosity(default_lu_fallback = Verbosity.Info()))) + @test_logs (:warn, + "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( + prob, + verbose = true) + + @test_logs min_level=Logging.Info solve(prob, + verbose = NonlinearVerbosity(Verbosity.None())) + + @test_logs min_level=Logging.Info solve(prob, + verbose = false) + # Test that caches get correct verbosities cache = init(prob, verbose = NonlinearVerbosity(threshold_state = Verbosity.Info())) From cd80d8699799c3ea8101be0799d611e903182174 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Fri, 1 Aug 2025 14:45:25 -0400 Subject: [PATCH 33/51] change constructors to use kwargs --- lib/NonlinearSolveBase/src/verbosity.jl | 73 +++++++++++++++---------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index c4f9aec0a..1dfa012b9 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -28,7 +28,7 @@ mutable struct NonlinearErrorControlVerbosity jacobian_free::Verbosity.Type termination_condition::Verbosity.Type - function NonlinearErrorControlVerbosity(immutable_u0 = nonlinear_verbosity_defaults[:immutable_u0], + function NonlinearErrorControlVerbosity(;immutable_u0 = nonlinear_verbosity_defaults[:immutable_u0], non_enclosing_interval = nonlinear_verbosity_defaults[:non_enclosing_interval], non_forward_mode = nonlinear_verbosity_defaults[:non_forward_mode], fd_ad_caution = nonlinear_verbosity_defaults[:fd_ad_caution], @@ -40,21 +40,26 @@ mutable struct NonlinearErrorControlVerbosity new(immutable_u0, non_enclosing_interval, non_forward_mode, fd_ad_caution, ad_backend_incompatible, alias_u0_immutable, linsolve_failed_noncurrent, jacobian_free, termination_condition) end + end function NonlinearErrorControlVerbosity(verbose::Verbosity.Type) @match verbose begin - Verbosity.None() => NonlinearErrorControlVerbosity(fill( - Verbosity.None(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + Verbosity.None() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( + Verbosity.None(), + length(fieldnames(NonlinearErrorControlVerbosity))))...) - Verbosity.Info() => NonlinearErrorControlVerbosity(fill( - Verbosity.Info(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + Verbosity.Info() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( + Verbosity.Info(), + length(fieldnames(NonlinearErrorControlVerbosity))))...) - Verbosity.Warn() => NonlinearErrorControlVerbosity(fill( - Verbosity.Warn(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + Verbosity.Warn() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( + Verbosity.Warn(), + length(fieldnames(NonlinearErrorControlVerbosity))))...) - Verbosity.Error() => NonlinearErrorControlVerbosity(fill( - Verbosity.Error(), length(fieldnames(NonlinearErrorControlVerbosity)))...) + Verbosity.Error() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( + Verbosity.Error(), + length(fieldnames(NonlinearErrorControlVerbosity))))...) Verbosity.Default() => NonlinearErrorControlVerbosity() @@ -70,27 +75,31 @@ mutable struct NonlinearPerformanceVerbosity sparsity_using_jac_prototype::Verbosity.Type sparse_matrixcolorings_not_loaded::Verbosity.Type - function NonlinearPerformanceVerbosity(colorvec_non_sparse = nonlinear_verbosity_defaults[:colorvec_non_sparse], - colorvec_no_prototype = nonlinear_verbosity_defaults[:colorvec_no_prototype], - sparsity_using_jac_prototype = nonlinear_verbosity_defaults[:sparsity_using_jac_prototype], - sparse_matrixcolorings_not_loaded = nonlinear_verbosity_defaults[:sparse_matrixcolorings_not_loaded]) + function NonlinearPerformanceVerbosity(; colorvec_non_sparse=nonlinear_verbosity_defaults[:colorvec_non_sparse], + colorvec_no_prototype=nonlinear_verbosity_defaults[:colorvec_no_prototype], + sparsity_using_jac_prototype=nonlinear_verbosity_defaults[:sparsity_using_jac_prototype], + sparse_matrixcolorings_not_loaded=nonlinear_verbosity_defaults[:sparse_matrixcolorings_not_loaded]) new(colorvec_non_sparse, colorvec_no_prototype, sparsity_using_jac_prototype, sparse_matrixcolorings_not_loaded) end end function NonlinearPerformanceVerbosity(verbose::Verbosity.Type) @match verbose begin - Verbosity.None() => NonlinearPerformanceVerbosity(fill( - Verbosity.None(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.None() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( + Verbosity.None(), + length(fieldnames(NonlinearPerformanceVerbosity))))...) - Verbosity.Info() => NonlinearPerformanceVerbosity(fill( - Verbosity.Info(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.Info() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( + Verbosity.Info(), + length(fieldnames(NonlinearPerformanceVerbosity))))...) - Verbosity.Warn() => NonlinearPerformanceVerbosity(fill( - Verbosity.Warn(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.Warn() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( + Verbosity.Warn(), + length(fieldnames(NonlinearPerformanceVerbosity))))...) - Verbosity.Error() => NonlinearPerformanceVerbosity(fill( - Verbosity.Error(), length(fieldnames(NonlinearPerformanceVerbosity)))...) + Verbosity.Error() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( + Verbosity.Error(), + length(fieldnames(NonlinearPerformanceVerbosity))))...) Verbosity.Default() => NonlinearPerformanceVerbosity() @@ -103,7 +112,7 @@ end mutable struct NonlinearNumericalVerbosity threshold_state::Verbosity.Type pinv_undefined::Verbosity.Type - function NonlinearNumericalVerbosity( + function NonlinearNumericalVerbosity(; threshold_state = nonlinear_verbosity_defaults[:threshold_state], pinv_undefined = nonlinear_verbosity_defaults[:pinv_undefined]) new(threshold_state, pinv_undefined) @@ -112,17 +121,21 @@ end function NonlinearNumericalVerbosity(verbose::Verbosity.Type) @match verbose begin - Verbosity.None() => NonlinearNumericalVerbosity(fill( - Verbosity.None(), length(fieldnames(NonlinearNumericalVerbosity)))...) + Verbosity.None() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill(Verbosity.None(), + length(fieldnames(NonlinearNumericalVerbosity))))...) + - Verbosity.Info() => NonlinearNumericalVerbosity(fill( - Verbosity.Info(), length(fieldnames(NonlinearNumericalVerbosity)))...) + Verbosity.Info() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill( + Verbosity.Info(), + length(fieldnames(NonlinearNumericalVerbosity))))...) - Verbosity.Warn() => NonlinearNumericalVerbosity(fill( - Verbosity.Warn(), length(fieldnames(NonlinearNumericalVerbosity)))...) + Verbosity.Warn() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill( + Verbosity.Warn(), + length(fieldnames(NonlinearNumericalVerbosity))))...) - Verbosity.Error() => NonlinearNumericalVerbosity(fill( - Verbosity.Error(), length(fieldnames(NonlinearNumericalVerbosity)))...) + Verbosity.Error() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill( + Verbosity.Error(), + length(fieldnames(NonlinearNumericalVerbosity))))...) Verbosity.Default() => NonlinearNumericalVerbosity() From 474d0fae864dcdd89db93b0c1a5c774d850610ad Mon Sep 17 00:00:00 2001 From: jClugstor Date: Mon, 20 Oct 2025 11:13:54 -0400 Subject: [PATCH 34/51] completely refactor verbosity specifier --- lib/NonlinearSolveBase/src/verbosity.jl | 461 ++++++++++++++---------- 1 file changed, 280 insertions(+), 181 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index 1dfa012b9..87ae07edc 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -1,221 +1,320 @@ -nonlinear_verbosity_defaults = Dict( - :immutable_u0 => Verbosity.Warn(), - :non_enclosing_interval => Verbosity.Warn(), - :non_forward_mode => Verbosity.Warn(), - :fd_ad_caution => Verbosity.Warn(), - :ad_backend_incompatible => Verbosity.Warn(), - :colorvec_non_sparse => Verbosity.Warn(), - :colorvec_no_prototype => Verbosity.Warn(), - :sparsity_using_jac_prototype => Verbosity.Warn(), - :sparse_matrixcolorings_not_loaded => Verbosity.Warn(), - :alias_u0_immutable => Verbosity.Warn(), - :linsolve_failed_noncurrent => Verbosity.Warn(), - :jacobian_free => Verbosity.Warn(), - :termination_condition => Verbosity.Warn(), - :threshold_state => Verbosity.Warn(), - :pinv_undefined => Verbosity.Warn() +# Group classifications +const error_control_options = ( + :immutable_u0, :non_enclosing_interval, :non_forward_mode, :fd_ad_caution, + :ad_backend_incompatible, :alias_u0_immutable, :linsolve_failed_noncurrent, + :jacobian_free, :termination_condition ) - - -mutable struct NonlinearErrorControlVerbosity - immutable_u0::Verbosity.Type - non_enclosing_interval::Verbosity.Type - non_forward_mode::Verbosity.Type - fd_ad_caution::Verbosity.Type - ad_backend_incompatible::Verbosity.Type - alias_u0_immutable::Verbosity.Type - linsolve_failed_noncurrent::Verbosity.Type - jacobian_free::Verbosity.Type - termination_condition::Verbosity.Type - - function NonlinearErrorControlVerbosity(;immutable_u0 = nonlinear_verbosity_defaults[:immutable_u0], - non_enclosing_interval = nonlinear_verbosity_defaults[:non_enclosing_interval], - non_forward_mode = nonlinear_verbosity_defaults[:non_forward_mode], - fd_ad_caution = nonlinear_verbosity_defaults[:fd_ad_caution], - ad_backend_incompatible = nonlinear_verbosity_defaults[:ad_backend_incompatible], - alias_u0_immutable = nonlinear_verbosity_defaults[:alias_u0_immutable], - linsolve_failed_noncurrent = nonlinear_verbosity_defaults[:linsolve_failed_noncurrent], - jacobian_free = nonlinear_verbosity_defaults[:jacobian_free], - termination_condition = nonlinear_verbosity_defaults[:termination_condition]) - new(immutable_u0, non_enclosing_interval, non_forward_mode, fd_ad_caution, ad_backend_incompatible, - alias_u0_immutable, linsolve_failed_noncurrent, jacobian_free, termination_condition) +const performance_options = ( + :colorvec_non_sparse, :colorvec_no_prototype, :sparsity_using_jac_prototype, + :sparse_matrixcolorings_not_loaded +) +const numerical_options = (:threshold_state, :pinv_undefined) + +function option_group(option::Symbol) + if option in error_control_options + return :error_control + elseif option in performance_options + return :performance + elseif option in numerical_options + return :numerical + else + error("Unknown verbosity option: $option") end - end -function NonlinearErrorControlVerbosity(verbose::Verbosity.Type) - @match verbose begin - Verbosity.None() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( - Verbosity.None(), - length(fieldnames(NonlinearErrorControlVerbosity))))...) - - Verbosity.Info() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( - Verbosity.Info(), - length(fieldnames(NonlinearErrorControlVerbosity))))...) - - Verbosity.Warn() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( - Verbosity.Warn(), - length(fieldnames(NonlinearErrorControlVerbosity))))...) +# Get all options in a group +function group_options(verbosity::NonlinearVerbosity, group::Symbol) + if group === :error_control + return NamedTuple{error_control_options}(getproperty(verbosity, opt) + for opt in error_control_options) + elseif group === :performance + return NamedTuple{performance_options}(getproperty(verbosity, opt) + for opt in performance_options) + elseif group === :numerical + return NamedTuple{numerical_options}(getproperty(verbosity, opt) + for opt in numerical_options) + else + error("Unknown group: $group") + end +end - Verbosity.Error() => NonlinearErrorControlVerbosity(;NamedTuple{fieldnames(NonlinearErrorControlVerbosity)}(fill( - Verbosity.Error(), - length(fieldnames(NonlinearErrorControlVerbosity))))...) +""" + NonlinearVerbosity <: AbstractVerbositySpecifier - Verbosity.Default() => NonlinearErrorControlVerbosity() +Verbosity configuration for NonlinearSolve.jl solvers, providing fine-grained control over +diagnostic messages, warnings, and errors during nonlinear system solution. - Verbosity.Edge() => NonlinearErrorControlVerbosity() +# Fields - _ => @error "Not a valid choice for verbosity." - end -end +## Error Control Group +- `immutable_u0`: Messages when u0 is immutable +- `non_enclosing_interval`: Messages when interval doesn't enclose root +- `non_forward_mode`: Messages when forward mode AD is not used +- `fd_ad_caution`: Messages about finite differencing cautions +- `ad_backend_incompatible`: Messages when AD backend is incompatible +- `alias_u0_immutable`: Messages when aliasing u0 with immutable array +- `linsolve_failed_noncurrent`: Messages when linear solve fails on non-current iteration +- `jacobian_free`: Messages about jacobian-free methods +- `termination_condition`: Messages about termination conditions -mutable struct NonlinearPerformanceVerbosity - colorvec_non_sparse::Verbosity.Type - colorvec_no_prototype::Verbosity.Type - sparsity_using_jac_prototype::Verbosity.Type - sparse_matrixcolorings_not_loaded::Verbosity.Type - - function NonlinearPerformanceVerbosity(; colorvec_non_sparse=nonlinear_verbosity_defaults[:colorvec_non_sparse], - colorvec_no_prototype=nonlinear_verbosity_defaults[:colorvec_no_prototype], - sparsity_using_jac_prototype=nonlinear_verbosity_defaults[:sparsity_using_jac_prototype], - sparse_matrixcolorings_not_loaded=nonlinear_verbosity_defaults[:sparse_matrixcolorings_not_loaded]) - new(colorvec_non_sparse, colorvec_no_prototype, sparsity_using_jac_prototype, sparse_matrixcolorings_not_loaded) - end -end +## Performance Group +- `colorvec_non_sparse`: Messages when color vector is used with non-sparse matrix +- `colorvec_no_prototype`: Messages when color vector has no prototype +- `sparsity_using_jac_prototype`: Messages when using jacobian prototype for sparsity +- `sparse_matrixcolorings_not_loaded`: Messages when SparseMatrixColorings not loaded -function NonlinearPerformanceVerbosity(verbose::Verbosity.Type) - @match verbose begin - Verbosity.None() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( - Verbosity.None(), - length(fieldnames(NonlinearPerformanceVerbosity))))...) +## Numerical Group +- `threshold_state`: Messages about threshold state +- `pinv_undefined`: Messages when pseudoinverse is undefined - Verbosity.Info() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( - Verbosity.Info(), - length(fieldnames(NonlinearPerformanceVerbosity))))...) +## Linear Solver Group +- `linear_verbosity`: Verbosity configuration for linear solvers - Verbosity.Warn() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( - Verbosity.Warn(), - length(fieldnames(NonlinearPerformanceVerbosity))))...) +# Constructors - Verbosity.Error() => NonlinearPerformanceVerbosity(;NamedTuple{fieldnames(NonlinearPerformanceVerbosity)}(fill( - Verbosity.Error(), - length(fieldnames(NonlinearPerformanceVerbosity))))...) + NonlinearVerbosity(preset::AbstractVerbosityPreset) - Verbosity.Default() => NonlinearPerformanceVerbosity() +Create a `NonlinearVerbosity` using a preset configuration: +- `SciMLLogging.None()`: All messages disabled +- `SciMLLogging.Minimal()`: Only critical errors and fatal issues +- `SciMLLogging.Standard()`: Balanced verbosity (default) +- `SciMLLogging.Detailed()`: Comprehensive debugging information +- `SciMLLogging.All()`: Maximum verbosity - Verbosity.Edge() => NonlinearPerformanceVerbosity() + NonlinearVerbosity(; error_control=nothing, performance=nothing, numerical=nothing, linear_verbosity=nothing, kwargs...) - _ => @error "Not a valid choice for verbosity." - end -end +Create a `NonlinearVerbosity` with group-level or individual field control. -mutable struct NonlinearNumericalVerbosity - threshold_state::Verbosity.Type - pinv_undefined::Verbosity.Type - function NonlinearNumericalVerbosity(; - threshold_state = nonlinear_verbosity_defaults[:threshold_state], - pinv_undefined = nonlinear_verbosity_defaults[:pinv_undefined]) - new(threshold_state, pinv_undefined) - end -end +# Examples -function NonlinearNumericalVerbosity(verbose::Verbosity.Type) - @match verbose begin - Verbosity.None() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill(Verbosity.None(), - length(fieldnames(NonlinearNumericalVerbosity))))...) - +```julia +# Use a preset +verbose = NonlinearVerbosity(SciMLLogging.Standard()) - Verbosity.Info() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill( - Verbosity.Info(), - length(fieldnames(NonlinearNumericalVerbosity))))...) +# Set entire groups +verbose = NonlinearVerbosity( + error_control = SciMLLogging.WarnLevel(), + numerical = SciMLLogging.InfoLevel() +) - Verbosity.Warn() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill( - Verbosity.Warn(), - length(fieldnames(NonlinearNumericalVerbosity))))...) +# Set individual fields +verbose = NonlinearVerbosity( + immutable_u0 = SciMLLogging.WarnLevel(), + threshold_state = SciMLLogging.InfoLevel() +) - Verbosity.Error() => NonlinearNumericalVerbosity(;NamedTuple{fieldnames(NonlinearNumericalVerbosity)}(fill( - Verbosity.Error(), - length(fieldnames(NonlinearNumericalVerbosity))))...) +# Mix group and individual settings +verbose = NonlinearVerbosity( + numerical = SciMLLogging.InfoLevel(), # Set all numerical to InfoLevel + pinv_undefined = SciMLLogging.ErrorLevel() # Override specific field +) +``` +""" +@concrete struct NonlinearVerbosity <: AbstractVerbositySpecifier + # Linear verbosity + linear_verbosity + # Error control + immutable_u0 + non_enclosing_interval + non_forward_mode + fd_ad_caution + ad_backend_incompatible + alias_u0_immutable + linsolve_failed_noncurrent + jacobian_free + termination_condition + # Performance + colorvec_non_sparse + colorvec_no_prototype + sparsity_using_jac_prototype + sparse_matrixcolorings_not_loaded + # Numerical + threshold_state + pinv_undefined +end - Verbosity.Default() => NonlinearNumericalVerbosity() +function NonlinearVerbosity(; + error_control = nothing, performance = nothing, numerical = nothing, + linear_verbosity = nothing, kwargs...) + # Validate group arguments + if error_control !== nothing && !(error_control isa AbstractMessageLevel) + throw(ArgumentError("error_control must be a SciMLLogging.AbstractMessageLevel, got $(typeof(error_control))")) + end + if performance !== nothing && !(performance isa AbstractMessageLevel) + throw(ArgumentError("performance must be a SciMLLogging.AbstractMessageLevel, got $(typeof(performance))")) + end + if numerical !== nothing && !(numerical isa AbstractMessageLevel) + throw(ArgumentError("numerical must be a SciMLLogging.AbstractMessageLevel, got $(typeof(numerical))")) + end - Verbosity.Edge() => NonlinearNumericalVerbosity() + # Validate individual kwargs + for (key, value) in kwargs + if !(key in error_control_options || key in performance_options || + key in numerical_options) + throw(ArgumentError("Unknown verbosity option: $key. Valid options are: $(tuple(error_control_options..., performance_options..., numerical_options...))")) + end + if !(value isa AbstractMessageLevel) + throw(ArgumentError("$key must be a SciMLLogging.AbstractMessageLevel, got $(typeof(value))")) + end + end - _ => @error "Not a valid choice for verbosity." + # Build arguments using NamedTuple for type stability + default_args = ( + linear_verbosity = linear_verbosity === nothing ? Minimal() : linear_verbosity, + immutable_u0 = WarnLevel(), + non_enclosing_interval = WarnLevel(), + non_forward_mode = WarnLevel(), + fd_ad_caution = WarnLevel(), + ad_backend_incompatible = WarnLevel(), + alias_u0_immutable = WarnLevel(), + linsolve_failed_noncurrent = WarnLevel(), + jacobian_free = WarnLevel(), + termination_condition = WarnLevel(), + colorvec_non_sparse = WarnLevel(), + colorvec_no_prototype = WarnLevel(), + sparsity_using_jac_prototype = WarnLevel(), + sparse_matrixcolorings_not_loaded = WarnLevel(), + threshold_state = WarnLevel(), + pinv_undefined = WarnLevel() + ) + + # Apply group-level settings + final_args = if error_control !== nothing || performance !== nothing || + numerical !== nothing + NamedTuple{keys(default_args)}( + _resolve_arg_value( + key, default_args[key], error_control, performance, numerical) + for key in keys(default_args) + ) + else + default_args end -end -struct NonlinearVerbosity{T} <: AbstractVerbositySpecifier{T} - linear_verbosity + # Apply individual overrides + if !isempty(kwargs) + final_args = merge(final_args, NamedTuple(kwargs)) + end - error_control::NonlinearErrorControlVerbosity - performance::NonlinearPerformanceVerbosity - numerical::NonlinearNumericalVerbosity + NonlinearVerbosity(values(final_args)...) end -function NonlinearVerbosity(verbose::Verbosity.Type) - @match verbose begin - Verbosity.Default() => NonlinearVerbosity{true}( - Verbosity.Default(), - NonlinearErrorControlVerbosity(Verbosity.Default()), - NonlinearPerformanceVerbosity(Verbosity.Default()), - NonlinearNumericalVerbosity(Verbosity.Default()) +# Constructor for verbosity presets following the hierarchical levels: +# None < Minimal < Standard < Detailed < All +# Each level includes all messages from levels below it plus additional ones +function NonlinearVerbosity(verbose::AbstractVerbosityPreset) + if verbose isa Minimal + # Minimal: Only fatal errors and critical warnings + NonlinearVerbosity( + linear_verbosity = Minimal(), + immutable_u0 = WarnLevel(), + non_enclosing_interval = WarnLevel(), + non_forward_mode = Silent(), + fd_ad_caution = Silent(), + ad_backend_incompatible = WarnLevel(), + alias_u0_immutable = Silent(), + linsolve_failed_noncurrent = WarnLevel(), + jacobian_free = Silent(), + termination_condition = Silent(), + colorvec_non_sparse = Silent(), + colorvec_no_prototype = Silent(), + sparsity_using_jac_prototype = Silent(), + sparse_matrixcolorings_not_loaded = Silent(), + threshold_state = Silent(), + pinv_undefined = ErrorLevel() ) - - Verbosity.None() => NonlinearVerbosity{false}( - Verbosity.None(), - NonlinearErrorControlVerbosity(Verbosity.None()), - NonlinearPerformanceVerbosity(Verbosity.None()), - NonlinearNumericalVerbosity(Verbosity.None())) - - Verbosity.All() => NonlinearVerbosity{true}( - Verbosity.All(), - NonlinearErrorControlVerbosity(Verbosity.Info()), - NonlinearPerformanceVerbosity(Verbosity.Info()), - NonlinearNumericalVerbosity(Verbosity.Info()) + elseif verbose isa Standard + # Standard: Everything from Minimal + non-fatal warnings + NonlinearVerbosity() + elseif verbose isa Detailed + # Detailed: Everything from Standard + debugging/solver behavior + NonlinearVerbosity( + linear_verbosity = Detailed(), + immutable_u0 = WarnLevel(), + non_enclosing_interval = WarnLevel(), + non_forward_mode = InfoLevel(), + fd_ad_caution = WarnLevel(), + ad_backend_incompatible = WarnLevel(), + alias_u0_immutable = WarnLevel(), + linsolve_failed_noncurrent = WarnLevel(), + jacobian_free = InfoLevel(), + termination_condition = WarnLevel(), + colorvec_non_sparse = InfoLevel(), + colorvec_no_prototype = InfoLevel(), + sparsity_using_jac_prototype = InfoLevel(), + sparse_matrixcolorings_not_loaded = InfoLevel(), + threshold_state = WarnLevel(), + pinv_undefined = WarnLevel() + ) + elseif verbose isa All + # All: Maximum verbosity - every possible logging message at InfoLevel + NonlinearVerbosity( + linear_verbosity = All(), + immutable_u0 = WarnLevel(), + non_enclosing_interval = WarnLevel(), + non_forward_mode = InfoLevel(), + fd_ad_caution = WarnLevel(), + ad_backend_incompatible = WarnLevel(), + alias_u0_immutable = WarnLevel(), + linsolve_failed_noncurrent = WarnLevel(), + jacobian_free = InfoLevel(), + termination_condition = WarnLevel(), + colorvec_non_sparse = InfoLevel(), + colorvec_no_prototype = InfoLevel(), + sparsity_using_jac_prototype = InfoLevel(), + sparse_matrixcolorings_not_loaded = InfoLevel(), + threshold_state = InfoLevel(), + pinv_undefined = WarnLevel() ) - - _ => @error "Not a valid choice for verbosity." end end -function NonlinearVerbosity(; - error_control=Verbosity.Default(), performance=Verbosity.Default(), - numerical=Verbosity.Default(), linear_verbosity = Verbosity.Default(), kwargs...) - - - if error_control isa Verbosity.Type - error_control_verbosity = NonlinearErrorControlVerbosity(error_control) - else - error_control_verbosity = error_control - end +@inline function NonlinearVerbosity(verbose::None) + NonlinearVerbosity( + None(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent(), + Silent() + ) +end - if performance isa Verbosity.Type - performance_verbosity = NonlinearPerformanceVerbosity(performance) +# Helper function to resolve argument values based on group membership +@inline function _resolve_arg_value( + key::Symbol, default_val, error_control, performance, numerical) + if key === :linear_verbosity + return default_val + elseif key in error_control_options && error_control !== nothing + return error_control + elseif key in performance_options && performance !== nothing + return performance + elseif key in numerical_options && numerical !== nothing + return numerical else - performance_verbosity = performance + return default_val end +end - if numerical isa Verbosity.Type - numerical_verbosity = NonlinearNumericalVerbosity(numerical) +function Base.getproperty(verbosity::NonlinearVerbosity, name::Symbol) + # Check if this is a group name + if name === :error_control + return group_options(verbosity, :error_control) + elseif name === :performance + return group_options(verbosity, :performance) + elseif name === :numerical + return group_options(verbosity, :numerical) else - numerical_verbosity = numerical + # Fall back to default field access + return getfield(verbosity, name) end - - if !isempty(kwargs) - for (key, value) in pairs(kwargs) - if hasfield(NonlinearErrorControlVerbosity, key) - setproperty!(error_control_verbosity, key, value) - elseif hasfield(NonlinearPerformanceVerbosity, key) - setproperty!(performance_verbosity, key, value) - elseif hasfield(NonlinearNumericalVerbosity, key) - setproperty!(numerical_verbosity, key, value) - else - error("$key is not a recognized verbosity toggle.") - end - end - end - - NonlinearVerbosity{true}(linear_verbosity, error_control_verbosity, - performance_verbosity, numerical_verbosity) -end \ No newline at end of file +end From df26802c7c7a8a0a7054310e8d995772b63a9864 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Mon, 20 Oct 2025 11:15:35 -0400 Subject: [PATCH 35/51] fix @SciMLMessage macro usage --- lib/BracketingNonlinearSolve/src/bisection.jl | 2 +- lib/BracketingNonlinearSolve/src/brent.jl | 2 +- lib/BracketingNonlinearSolve/src/falsi.jl | 2 +- lib/BracketingNonlinearSolve/src/itp.jl | 2 +- lib/BracketingNonlinearSolve/src/ridder.jl | 2 +- lib/NonlinearSolveBase/src/polyalg.jl | 2 +- lib/NonlinearSolveBase/src/solve.jl | 2 +- lib/NonlinearSolveFirstOrder/src/solve.jl | 2 +- lib/NonlinearSolveQuasiNewton/src/initialization.jl | 2 +- lib/NonlinearSolveQuasiNewton/src/solve.jl | 2 +- lib/NonlinearSolveSpectralMethods/src/solve.jl | 2 +- lib/SimpleNonlinearSolve/src/lbroyden.jl | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/BracketingNonlinearSolve/src/bisection.jl b/lib/BracketingNonlinearSolve/src/bisection.jl index 95ed2fe07..153772d27 100644 --- a/lib/BracketingNonlinearSolve/src/bisection.jl +++ b/lib/BracketingNonlinearSolve/src/bisection.jl @@ -47,7 +47,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - verbose, :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/brent.jl b/lib/BracketingNonlinearSolve/src/brent.jl index b4936ddb6..5541e7a5c 100644 --- a/lib/BracketingNonlinearSolve/src/brent.jl +++ b/lib/BracketingNonlinearSolve/src/brent.jl @@ -45,7 +45,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - verbose, :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/falsi.jl b/lib/BracketingNonlinearSolve/src/falsi.jl index e529798ac..763740224 100644 --- a/lib/BracketingNonlinearSolve/src/falsi.jl +++ b/lib/BracketingNonlinearSolve/src/falsi.jl @@ -44,7 +44,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - verbose, :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/itp.jl b/lib/BracketingNonlinearSolve/src/itp.jl index f9791bddf..2a4af0362 100644 --- a/lib/BracketingNonlinearSolve/src/itp.jl +++ b/lib/BracketingNonlinearSolve/src/itp.jl @@ -85,7 +85,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - verbose, :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/BracketingNonlinearSolve/src/ridder.jl b/lib/BracketingNonlinearSolve/src/ridder.jl index 62207f510..e0686be95 100644 --- a/lib/BracketingNonlinearSolve/src/ridder.jl +++ b/lib/BracketingNonlinearSolve/src/ridder.jl @@ -34,7 +34,7 @@ function SciMLBase.__solve( if sign(fl) == sign(fr) @SciMLMessage("The interval is not an enclosing interval, opposite signs at the \ boundaries are required.", - verbose, :non_enclosing_interval, :error_control) + verbose, :non_enclosing_interval) return SciMLBase.build_solution( prob, alg, left, fl; retcode = ReturnCode.InitialFailure, left, right ) diff --git a/lib/NonlinearSolveBase/src/polyalg.jl b/lib/NonlinearSolveBase/src/polyalg.jl index 1b3420d8a..9eba2862c 100644 --- a/lib/NonlinearSolveBase/src/polyalg.jl +++ b/lib/NonlinearSolveBase/src/polyalg.jl @@ -124,7 +124,7 @@ function SciMLBase.__init( ) where {IN} if alias_u0 && !ArrayInterface.ismutable(prob.u0) @SciMLMessage("`alias_u0` has been set to `true`, but `u0` is - immutable (checked using `ArrayInterface.ismutable``).", verbose, :alias_u0_immutable, :error_control) + immutable (checked using `ArrayInterface.ismutable``).", verbose, :alias_u0_immutable) alias_u0 = false # If immutable don't care about aliasing end diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index b7898d547..27b47eaff 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -396,7 +396,7 @@ end current = alg.start_index if alias_u0 && !ArrayInterface.ismutable(prob.u0) @SciMLMessage("`alias_u0` has been set to `true`, but `u0` is - immutable (checked using `ArrayInterface.ismutable``).", verbose, :alias_u0_immutable, :error_control) + immutable (checked using `ArrayInterface.ismutable``).", verbose, :alias_u0_immutable) alias_u0 = false # If immutable don't care about aliasing end end] diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index d7c718f6c..63f7d9498 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -278,7 +278,7 @@ function InternalAPI.step!( else # Jacobian Information is not current and linear solve failed, recompute it @SciMLMessage("Linear Solve Failed but Jacobian information is not current. Retrying with updated Jacobian. \ - Retrying with updated Jacobian.", cache.verbose, :linsolve_failed_noncurrent, :error_control) + Retrying with updated Jacobian.", cache.verbose, :linsolve_failed_noncurrent) # In the 2nd call the `new_jacobian` is guaranteed to be `true`. cache.make_new_jacobian = true InternalAPI.step!(cache; recompute_jacobian = true, cache.kwargs...) diff --git a/lib/NonlinearSolveQuasiNewton/src/initialization.jl b/lib/NonlinearSolveQuasiNewton/src/initialization.jl index 34844adba..4e05501a5 100644 --- a/lib/NonlinearSolveQuasiNewton/src/initialization.jl +++ b/lib/NonlinearSolveQuasiNewton/src/initialization.jl @@ -180,7 +180,7 @@ function InternalAPI.init( threshold = min(Utils.unwrap_val(alg.threshold), maxiters) if threshold > length(u) @SciMLMessage("`threshold` is larger than the size of the state, which may cause \ - numerical instability. Consider reducing `threshold`.", verbose, :threshold_state, :numerical) + numerical instability. Consider reducing `threshold`.", verbose, :threshold_state) end J = BroydenLowRankJacobian(fu, u; threshold, alpha = α) end diff --git a/lib/NonlinearSolveQuasiNewton/src/solve.jl b/lib/NonlinearSolveQuasiNewton/src/solve.jl index f8ffffdc4..7807d3342 100644 --- a/lib/NonlinearSolveQuasiNewton/src/solve.jl +++ b/lib/NonlinearSolveQuasiNewton/src/solve.jl @@ -349,7 +349,7 @@ function InternalAPI.step!( # Force a reinit because the problem is currently un-solvable @SciMLMessage("Linear Solve Failed but Jacobian information is not current. Retrying with updated Jacobian. \ - Retrying with updated Jacobian.", cache.verbose, :linsolve_failed_noncurrent, :error_control) + Retrying with updated Jacobian.", cache.verbose, :linsolve_failed_noncurrent) cache.force_reinit = true InternalAPI.step!(cache; recompute_jacobian = true) diff --git a/lib/NonlinearSolveSpectralMethods/src/solve.jl b/lib/NonlinearSolveSpectralMethods/src/solve.jl index 038acde08..7269cacfd 100644 --- a/lib/NonlinearSolveSpectralMethods/src/solve.jl +++ b/lib/NonlinearSolveSpectralMethods/src/solve.jl @@ -189,7 +189,7 @@ function InternalAPI.step!( ) if recompute_jacobian !== nothing @SciMLMessage("GeneralizedDFSane is a Jacobian-Free Algorithm. Ignoring \ - `recompute_jacobian`", cache.verbose, :jacobian_free, :error_control) + `recompute_jacobian`", cache.verbose, :jacobian_free) end @static_timeit cache.timer "descent" begin diff --git a/lib/SimpleNonlinearSolve/src/lbroyden.jl b/lib/SimpleNonlinearSolve/src/lbroyden.jl index d5a2ea425..cb4ca97cc 100644 --- a/lib/SimpleNonlinearSolve/src/lbroyden.jl +++ b/lib/SimpleNonlinearSolve/src/lbroyden.jl @@ -58,7 +58,7 @@ function SciMLBase.__solve( @SciMLMessage("Specifying `termination_condition = $(termination_condition)` for \ `SimpleLimitedMemoryBroyden` with `SArray` is not non-allocating. Use \ either `termination_condition = AbsNormTerminationMode(Base.Fix2(norm, Inf))` \ - or `termination_condition = nothing`.", verbose, :termination_condition, :error_control) + or `termination_condition = nothing`.", verbose, :termination_condition) end return internal_generic_solve(prob, alg, args...; termination_condition, kwargs...) end From 9170758c7888f43d8917aac52c03f6c1edc49b56 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Mon, 20 Oct 2025 12:36:07 -0400 Subject: [PATCH 36/51] fix imports, add tests --- lib/NonlinearSolveBase/Project.toml | 9 +- .../ext/NonlinearSolveBaseLinearSolveExt.jl | 2 +- .../src/NonlinearSolveBase.jl | 5 +- lib/NonlinearSolveBase/src/verbosity.jl | 82 ++++++++-------- test/verbosity.jl | 93 +++++++++++++++++-- 5 files changed, 136 insertions(+), 55 deletions(-) diff --git a/lib/NonlinearSolveBase/Project.toml b/lib/NonlinearSolveBase/Project.toml index 498b8036c..57385af12 100644 --- a/lib/NonlinearSolveBase/Project.toml +++ b/lib/NonlinearSolveBase/Project.toml @@ -21,10 +21,10 @@ Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" SciMLJacobianOperators = "19f34311-ddf3-4b8b-af20-060888a46c0e" +SciMLLogging = "a6db7da4-7206-11f0-1eab-35f2a5dbe1d1" 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" @@ -55,7 +55,6 @@ NonlinearSolveBaseSparseArraysExt = "SparseArrays" NonlinearSolveBaseSparseMatrixColoringsExt = "SparseMatrixColorings" NonlinearSolveBaseTrackerExt = "Tracker" - [compat] ADTypes = "1.9" Adapt = "4.1.0" @@ -67,8 +66,8 @@ CommonSolve = "0.2.4" Compat = "4.15" ConcreteStructs = "0.2.3" DifferentiationInterface = "0.6.16, 0.7" -EnzymeCore = "0.8" Enzyme = "0.13.12" +EnzymeCore = "0.8" ExplicitImports = "1.10.1" FastClosures = "0.3" ForwardDiff = "0.10.36, 1" @@ -85,17 +84,17 @@ RecursiveArrayTools = "3" ReverseDiff = "1.15" SciMLBase = "2.116" SciMLJacobianOperators = "0.1.1" +SciMLLogging = "1.3.0" SciMLOperators = "1.7" SciMLStructures = "1.5" Setfield = "1.1.2" -SciMLVerbosity = "1.2.0" SparseArrays = "1.10" SparseMatrixColorings = "0.4.5" StaticArraysCore = "1.4" SymbolicIndexingInterface = "0.3.43" Test = "1.10" -Tracker = "0.2.35" TimerOutputs = "0.5.23" +Tracker = "0.2.35" julia = "1.10" [extras] diff --git a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl index 6ccc2b1d6..50512300b 100644 --- a/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl +++ b/lib/NonlinearSolveBase/ext/NonlinearSolveBaseLinearSolveExt.jl @@ -5,7 +5,7 @@ using ArrayInterface: ArrayInterface using CommonSolve: CommonSolve, init, solve! using LinearSolve: LinearSolve, QRFactorization, SciMLLinearSolveAlgorithm using SciMLBase: ReturnCode, LinearProblem, LinearAliasSpecifier -using SciMLVerbosity: @SciMLMessage +using SciMLLogging: @SciMLMessage using LinearAlgebra: ColumnNorm diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index 246693ee6..194ffe246 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -28,7 +28,10 @@ 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 SciMLLogging: @SciMLMessage, AbstractVerbositySpecifier, AbstractVerbosityPreset, + None, Minimal, Standard, Detailed, All, Silent, InfoLevel, WarnLevel, ErrorLevel, + CustomLevel + using SymbolicIndexingInterface: SymbolicIndexingInterface import SciMLStructures using Setfield: @set! diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index 87ae07edc..58b7fbe59 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -1,43 +1,3 @@ -# Group classifications -const error_control_options = ( - :immutable_u0, :non_enclosing_interval, :non_forward_mode, :fd_ad_caution, - :ad_backend_incompatible, :alias_u0_immutable, :linsolve_failed_noncurrent, - :jacobian_free, :termination_condition -) -const performance_options = ( - :colorvec_non_sparse, :colorvec_no_prototype, :sparsity_using_jac_prototype, - :sparse_matrixcolorings_not_loaded -) -const numerical_options = (:threshold_state, :pinv_undefined) - -function option_group(option::Symbol) - if option in error_control_options - return :error_control - elseif option in performance_options - return :performance - elseif option in numerical_options - return :numerical - else - error("Unknown verbosity option: $option") - end -end - -# Get all options in a group -function group_options(verbosity::NonlinearVerbosity, group::Symbol) - if group === :error_control - return NamedTuple{error_control_options}(getproperty(verbosity, opt) - for opt in error_control_options) - elseif group === :performance - return NamedTuple{performance_options}(getproperty(verbosity, opt) - for opt in performance_options) - elseif group === :numerical - return NamedTuple{numerical_options}(getproperty(verbosity, opt) - for opt in numerical_options) - else - error("Unknown group: $group") - end -end - """ NonlinearVerbosity <: AbstractVerbositySpecifier @@ -67,7 +27,7 @@ diagnostic messages, warnings, and errors during nonlinear system solution. - `threshold_state`: Messages about threshold state - `pinv_undefined`: Messages when pseudoinverse is undefined -## Linear Solver Group +## Linear Solver - `linear_verbosity`: Verbosity configuration for linear solvers # Constructors @@ -133,6 +93,46 @@ verbose = NonlinearVerbosity( pinv_undefined end +# Group classifications +const error_control_options = ( + :immutable_u0, :non_enclosing_interval, :non_forward_mode, :fd_ad_caution, + :ad_backend_incompatible, :alias_u0_immutable, :linsolve_failed_noncurrent, + :jacobian_free, :termination_condition +) +const performance_options = ( + :colorvec_non_sparse, :colorvec_no_prototype, :sparsity_using_jac_prototype, + :sparse_matrixcolorings_not_loaded +) +const numerical_options = (:threshold_state, :pinv_undefined) + +function option_group(option::Symbol) + if option in error_control_options + return :error_control + elseif option in performance_options + return :performance + elseif option in numerical_options + return :numerical + else + error("Unknown verbosity option: $option") + end +end + +# Get all options in a group +function group_options(verbosity::NonlinearVerbosity, group::Symbol) + if group === :error_control + return NamedTuple{error_control_options}(getproperty(verbosity, opt) + for opt in error_control_options) + elseif group === :performance + return NamedTuple{performance_options}(getproperty(verbosity, opt) + for opt in performance_options) + elseif group === :numerical + return NamedTuple{numerical_options}(getproperty(verbosity, opt) + for opt in numerical_options) + else + error("Unknown group: $group") + end +end + function NonlinearVerbosity(; error_control = nothing, performance = nothing, numerical = nothing, linear_verbosity = nothing, kwargs...) diff --git a/test/verbosity.jl b/test/verbosity.jl index 062d3baae..5b377185a 100644 --- a/test/verbosity.jl +++ b/test/verbosity.jl @@ -3,7 +3,7 @@ using NonlinearSolve using NonlinearSolve: NonlinearVerbosity using LinearSolve: LinearVerbosity - using SciMLVerbosity: SciMLVerbosity, Verbosity + using SciMLLogging: SciMLLogging using Test using Logging @@ -28,18 +28,13 @@ @test_logs (:warn, "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( prob, - verbose = NonlinearVerbosity()) + verbose = NonlinearVerbosity(linear_verbosity = Detailed())) @test_logs (:info, "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( prob, verbose = NonlinearVerbosity(linear_verbosity = LinearVerbosity(default_lu_fallback = Verbosity.Info()))) - @test_logs (:warn, - "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( - prob, - verbose = true) - @test_logs min_level=Logging.Info solve(prob, verbose = NonlinearVerbosity(Verbosity.None())) @@ -50,4 +45,88 @@ cache = init(prob, verbose = NonlinearVerbosity(threshold_state = Verbosity.Info())) @test cache.verbose.numerical.threshold_state == Verbosity.Info() + + @testset "NonlinearVerbosity preset constructors" begin + v_none = NonlinearVerbosity(SciMLLogging.None()) + v_all = NonlinearVerbosity(SciMLLogging.All()) + v_minimal = NonlinearVerbosity(SciMLLogging.Minimal()) + v_standard = NonlinearVerbosity(SciMLLogging.Standard()) + v_detailed = NonlinearVerbosity(SciMLLogging.Detailed()) + + @test v_none.immutable_u0 isa SciMLLogging.Silent + @test v_none.threshold_state isa SciMLLogging.Silent + @test v_none.colorvec_non_sparse isa SciMLLogging.Silent + + @test v_minimal.immutable_u0 isa SciMLLogging.ErrorLevel + @test v_minimal.colorvec_non_sparse isa SciMLLogging.Silent + @test v_minimal.non_forward_mode isa SciMLLogging.Silent + + @test v_standard.immutable_u0 isa SciMLLogging.WarnLevel + @test v_standard.threshold_state isa SciMLLogging.WarnLevel + + @test v_detailed.colorvec_non_sparse isa SciMLLogging.InfoLevel + @test v_detailed.non_forward_mode isa SciMLLogging.InfoLevel + @test v_detailed.jacobian_free isa SciMLLogging.InfoLevel + + @test v_all.colorvec_non_sparse isa SciMLLogging.InfoLevel + @test v_all.threshold_state isa SciMLLogging.InfoLevel + end + + @testset "Group-level keyword constructors" begin + v_error = NonlinearVerbosity(error_control = ErrorLevel()) + @test v_error.immutable_u0 isa SciMLLogging.ErrorLevel + @test v_error.non_enclosing_interval isa SciMLLogging.ErrorLevel + @test v_error.termination_condition isa SciMLLogging.ErrorLevel + + v_numerical = NonlinearVerbosity(numerical = Silent()) + @test v_numerical.threshold_state isa SciMLLogging.Silent + @test v_numerical.pinv_undefined isa SciMLLogging.Silent + + v_performance = NonlinearVerbosity(performance = InfoLevel()) + @test v_performance.colorvec_non_sparse isa SciMLLogging.InfoLevel + @test v_performance.colorvec_no_prototype isa SciMLLogging.InfoLevel + @test v_performance.sparsity_using_jac_prototype isa SciMLLogging.InfoLevel + @test v_performance.sparse_matrixcolorings_not_loaded isa SciMLLogging.InfoLevel + end + + @testset "Mixed group and individual settings" begin + v_mixed = NonlinearVerbosity( + numerical = Silent(), + threshold_state = WarnLevel(), + performance = InfoLevel() + ) + # Individual override should take precedence + @test v_mixed.threshold_state isa SciMLLogging.WarnLevel + # Other numerical options should use group setting + @test v_mixed.pinv_undefined isa SciMLLogging.Silent + # Performance group setting should apply + @test v_mixed.colorvec_non_sparse isa SciMLLogging.InfoLevel + @test v_mixed.colorvec_no_prototype isa SciMLLogging.InfoLevel + end + + @testset "Individual keyword arguments" begin + v_individual = NonlinearVerbosity( + immutable_u0 = ErrorLevel(), + threshold_state = InfoLevel(), + colorvec_non_sparse = Silent() + ) + @test v_individual.immutable_u0 isa SciMLLogging.ErrorLevel + @test v_individual.threshold_state isa SciMLLogging.InfoLevel + @test v_individual.colorvec_non_sparse isa SciMLLogging.Silent + # Unspecified options should use defaults + @test v_individual.non_enclosing_interval isa SciMLLogging.WarnLevel + @test v_individual.pinv_undefined isa SciMLLogging.WarnLevel + end + + @testset "Linear verbosity passthrough" begin + v_with_linear = NonlinearVerbosity( + linear_verbosity = SciMLLogging.Detailed() + ) + @test v_with_linear.linear_verbosity isa SciMLLogging.Detailed + + v_with_linear2 = NonlinearVerbosity( + linear_verbosity = SciMLLogging.None() + ) + @test v_with_linear2.linear_verbosity isa SciMLLogging.None + end end From c4344e3bdb2f8cc96e80b6512e15a3551b779eee Mon Sep 17 00:00:00 2001 From: jClugstor Date: Mon, 20 Oct 2025 17:05:08 -0400 Subject: [PATCH 37/51] refactor for new SciMLLogging --- .../src/BracketingNonlinearSolve.jl | 2 +- lib/BracketingNonlinearSolve/src/brent.jl | 4 +- lib/BracketingNonlinearSolve/src/falsi.jl | 4 +- .../src/NonlinearSolveBase.jl | 2 +- lib/NonlinearSolveBase/src/polyalg.jl | 4 +- lib/NonlinearSolveBase/src/solve.jl | 4 +- .../src/NonlinearSolveFirstOrder.jl | 3 +- lib/NonlinearSolveFirstOrder/src/solve.jl | 4 +- .../src/NonlinearSolveQuasiNewton.jl | 2 +- .../src/initialization.jl | 4 +- lib/NonlinearSolveQuasiNewton/src/solve.jl | 4 +- .../src/NonlinearSolveSpectralMethods.jl | 2 +- .../src/solve.jl | 4 +- lib/SimpleNonlinearSolve/src/lbroyden.jl | 4 +- test/{verbosity.jl => verbosity_tests.jl} | 124 +++++++++--------- 15 files changed, 86 insertions(+), 85 deletions(-) rename test/{verbosity.jl => verbosity_tests.jl} (72%) diff --git a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl index 3198e9b44..fd9398832 100644 --- a/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl +++ b/lib/BracketingNonlinearSolve/src/BracketingNonlinearSolve.jl @@ -5,7 +5,7 @@ using PrecompileTools: @compile_workload, @setup_workload using Reexport: @reexport using CommonSolve: CommonSolve, solve -using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, Verbosity +using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, AbstractVerbosityPreset using SciMLBase: SciMLBase, IntervalNonlinearProblem, ReturnCode abstract type AbstractBracketingAlgorithm <: AbstractNonlinearSolveAlgorithm end diff --git a/lib/BracketingNonlinearSolve/src/brent.jl b/lib/BracketingNonlinearSolve/src/brent.jl index 5541e7a5c..cce3428ad 100644 --- a/lib/BracketingNonlinearSolve/src/brent.jl +++ b/lib/BracketingNonlinearSolve/src/brent.jl @@ -15,9 +15,9 @@ function SciMLBase.__solve( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/BracketingNonlinearSolve/src/falsi.jl b/lib/BracketingNonlinearSolve/src/falsi.jl index 763740224..edd57cbc6 100644 --- a/lib/BracketingNonlinearSolve/src/falsi.jl +++ b/lib/BracketingNonlinearSolve/src/falsi.jl @@ -15,9 +15,9 @@ function SciMLBase.__solve( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index 194ffe246..3b8523c41 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -28,7 +28,7 @@ import SciMLBase: solve, init, __init, __solve, wrap_sol, get_root_indp, isinpla using SciMLJacobianOperators: JacobianOperator, StatefulJacobianOperator using SciMLOperators: AbstractSciMLOperator, IdentityOperator -using SciMLLogging: @SciMLMessage, AbstractVerbositySpecifier, AbstractVerbosityPreset, +using SciMLLogging: @SciMLMessage, AbstractVerbositySpecifier, AbstractVerbosityPreset, AbstractMessageLevel, None, Minimal, Standard, Detailed, All, Silent, InfoLevel, WarnLevel, ErrorLevel, CustomLevel diff --git a/lib/NonlinearSolveBase/src/polyalg.jl b/lib/NonlinearSolveBase/src/polyalg.jl index 9eba2862c..76edb3033 100644 --- a/lib/NonlinearSolveBase/src/polyalg.jl +++ b/lib/NonlinearSolveBase/src/polyalg.jl @@ -132,9 +132,9 @@ function SciMLBase.__init( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index 27b47eaff..407037505 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -383,9 +383,9 @@ end if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl index 5b29a2a82..c3333fca0 100644 --- a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl +++ b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl @@ -22,7 +22,8 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, update_trace!, L2_NORM, NonlinearSolvePolyAlgorithm, NewtonDescent, DampedNewtonDescent, GeodesicAcceleration, Dogleg, NonlinearSolveForwardDiffCache, NonlinearVerbosity, - @SciMLMessage, Verbosity, reused_jacobian + @SciMLMessage, None, reused_jacobian, AbstractVerbositySpecifier, + AbstractVerbosityPreset using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearFunction, NonlinearLeastSquaresProblem, NonlinearProblem, NoSpecialize diff --git a/lib/NonlinearSolveFirstOrder/src/solve.jl b/lib/NonlinearSolveFirstOrder/src/solve.jl index 63f7d9498..e577da907 100644 --- a/lib/NonlinearSolveFirstOrder/src/solve.jl +++ b/lib/NonlinearSolveFirstOrder/src/solve.jl @@ -158,9 +158,9 @@ function SciMLBase.__init( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl index 73d85b8a0..592648367 100644 --- a/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl +++ b/lib/NonlinearSolveQuasiNewton/src/NonlinearSolveQuasiNewton.jl @@ -19,7 +19,7 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractApproximateJacobianUpdateRuleCache, Utils, InternalAPI, get_timer_output, @static_timeit, update_trace!, L2_NORM, NewtonDescent, NonlinearVerbosity, - @SciMLMessage, Verbosity, reused_jacobian + @SciMLMessage, None, AbstractVerbosityPreset, reused_jacobian using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize using SciMLOperators: AbstractSciMLOperator diff --git a/lib/NonlinearSolveQuasiNewton/src/initialization.jl b/lib/NonlinearSolveQuasiNewton/src/initialization.jl index 4e05501a5..e52a5aaa8 100644 --- a/lib/NonlinearSolveQuasiNewton/src/initialization.jl +++ b/lib/NonlinearSolveQuasiNewton/src/initialization.jl @@ -166,9 +166,9 @@ function InternalAPI.init( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/NonlinearSolveQuasiNewton/src/solve.jl b/lib/NonlinearSolveQuasiNewton/src/solve.jl index 7807d3342..7585f537e 100644 --- a/lib/NonlinearSolveQuasiNewton/src/solve.jl +++ b/lib/NonlinearSolveQuasiNewton/src/solve.jl @@ -161,9 +161,9 @@ function SciMLBase.__init( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl index 161c6e5da..b9b80e13b 100644 --- a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl +++ b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl @@ -9,7 +9,7 @@ using LineSearch: RobustNonMonotoneLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractNonlinearSolveCache, Utils, InternalAPI, get_timer_output, - @static_timeit, update_trace!, NonlinearVerbosity, @SciMLMessage, Verbosity + @static_timeit, update_trace!, NonlinearVerbosity, @SciMLMessage, None using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize diff --git a/lib/NonlinearSolveSpectralMethods/src/solve.jl b/lib/NonlinearSolveSpectralMethods/src/solve.jl index 7269cacfd..74ba39bf9 100644 --- a/lib/NonlinearSolveSpectralMethods/src/solve.jl +++ b/lib/NonlinearSolveSpectralMethods/src/solve.jl @@ -165,9 +165,9 @@ function SciMLBase.__init( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/lib/SimpleNonlinearSolve/src/lbroyden.jl b/lib/SimpleNonlinearSolve/src/lbroyden.jl index cb4ca97cc..85a884ede 100644 --- a/lib/SimpleNonlinearSolve/src/lbroyden.jl +++ b/lib/SimpleNonlinearSolve/src/lbroyden.jl @@ -49,9 +49,9 @@ function SciMLBase.__solve( if verbose verbose = NonlinearVerbosity() else - verbose = NonlinearVerbosity(Verbosity.None()) + verbose = NonlinearVerbosity(None()) end - elseif verbose isa Verbosity.Type + elseif verbose isa AbstractVerbosityPreset verbose = NonlinearVerbosity(verbose) end diff --git a/test/verbosity.jl b/test/verbosity_tests.jl similarity index 72% rename from test/verbosity.jl rename to test/verbosity_tests.jl index 5b377185a..f727dd619 100644 --- a/test/verbosity.jl +++ b/test/verbosity_tests.jl @@ -1,50 +1,12 @@ -@testitem "Nonlinear Verbosity" tags=[:misc] begin - using IntervalNonlinearSolve +@testitem "Nonlinear Verbosity" tags=[:verbosity] begin using NonlinearSolve + using BracketingNonlinearSolve using NonlinearSolve: NonlinearVerbosity using LinearSolve: LinearVerbosity using SciMLLogging: SciMLLogging - using Test using Logging - - g(u, p) = u^2 - 4 - - int_prob = IntervalNonlinearProblem(g, (3.0, 5.0)) - - @test_logs (:info, - "The interval is not an enclosing interval, opposite signs at the boundaries are required.") solve( - int_prob, - ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = Verbosity.Info())) - - @test_logs (:error, - "The interval is not an enclosing interval, opposite signs at the boundaries are required.") solve( - int_prob, - ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = Verbosity.Error())) - - # Test that the linear verbosity is passed to the linear solve - f(u, p) = [u[1]^2 - 2u[1] + 1, sum(u)] - prob = NonlinearProblem(f, [1.0, 1.0]) - - @test_logs (:warn, - "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( - prob, - verbose = NonlinearVerbosity(linear_verbosity = Detailed())) - - @test_logs (:info, - "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( - prob, - verbose = NonlinearVerbosity(linear_verbosity = LinearVerbosity(default_lu_fallback = Verbosity.Info()))) - - @test_logs min_level=Logging.Info solve(prob, - verbose = NonlinearVerbosity(Verbosity.None())) - - @test_logs min_level=Logging.Info solve(prob, - verbose = false) - - # Test that caches get correct verbosities - cache = init(prob, verbose = NonlinearVerbosity(threshold_state = Verbosity.Info())) - - @test cache.verbose.numerical.threshold_state == Verbosity.Info() + using Test + using Logging @testset "NonlinearVerbosity preset constructors" begin v_none = NonlinearVerbosity(SciMLLogging.None()) @@ -57,7 +19,7 @@ @test v_none.threshold_state isa SciMLLogging.Silent @test v_none.colorvec_non_sparse isa SciMLLogging.Silent - @test v_minimal.immutable_u0 isa SciMLLogging.ErrorLevel + @test v_minimal.immutable_u0 isa SciMLLogging.WarnLevel @test v_minimal.colorvec_non_sparse isa SciMLLogging.Silent @test v_minimal.non_forward_mode isa SciMLLogging.Silent @@ -73,16 +35,16 @@ end @testset "Group-level keyword constructors" begin - v_error = NonlinearVerbosity(error_control = ErrorLevel()) + v_error = NonlinearVerbosity(error_control = SciMLLogging.ErrorLevel()) @test v_error.immutable_u0 isa SciMLLogging.ErrorLevel @test v_error.non_enclosing_interval isa SciMLLogging.ErrorLevel @test v_error.termination_condition isa SciMLLogging.ErrorLevel - v_numerical = NonlinearVerbosity(numerical = Silent()) + v_numerical = NonlinearVerbosity(numerical = SciMLLogging.Silent()) @test v_numerical.threshold_state isa SciMLLogging.Silent @test v_numerical.pinv_undefined isa SciMLLogging.Silent - v_performance = NonlinearVerbosity(performance = InfoLevel()) + v_performance = NonlinearVerbosity(performance = SciMLLogging.InfoLevel()) @test v_performance.colorvec_non_sparse isa SciMLLogging.InfoLevel @test v_performance.colorvec_no_prototype isa SciMLLogging.InfoLevel @test v_performance.sparsity_using_jac_prototype isa SciMLLogging.InfoLevel @@ -91,9 +53,9 @@ @testset "Mixed group and individual settings" begin v_mixed = NonlinearVerbosity( - numerical = Silent(), - threshold_state = WarnLevel(), - performance = InfoLevel() + numerical = SciMLLogging.Silent(), + threshold_state = SciMLLogging.WarnLevel(), + performance = SciMLLogging.InfoLevel() ) # Individual override should take precedence @test v_mixed.threshold_state isa SciMLLogging.WarnLevel @@ -106,9 +68,9 @@ @testset "Individual keyword arguments" begin v_individual = NonlinearVerbosity( - immutable_u0 = ErrorLevel(), - threshold_state = InfoLevel(), - colorvec_non_sparse = Silent() + immutable_u0 = SciMLLogging.ErrorLevel(), + threshold_state = SciMLLogging.InfoLevel(), + colorvec_non_sparse = SciMLLogging.Silent() ) @test v_individual.immutable_u0 isa SciMLLogging.ErrorLevel @test v_individual.threshold_state isa SciMLLogging.InfoLevel @@ -118,15 +80,53 @@ @test v_individual.pinv_undefined isa SciMLLogging.WarnLevel end - @testset "Linear verbosity passthrough" begin - v_with_linear = NonlinearVerbosity( - linear_verbosity = SciMLLogging.Detailed() - ) - @test v_with_linear.linear_verbosity isa SciMLLogging.Detailed + g(u, p) = u^2 - 4 - v_with_linear2 = NonlinearVerbosity( - linear_verbosity = SciMLLogging.None() - ) - @test v_with_linear2.linear_verbosity isa SciMLLogging.None - end + int_prob = IntervalNonlinearProblem(g, (3.0, 5.0)) + + @test_logs (:info, + "The interval is not an enclosing interval, opposite signs at the boundaries are required.") solve( + int_prob, + ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = SciMLLogging.InfoLevel())) + + @test_throws Test.FallbackTestSetException @test_logs (:error, + "The interval is not an enclosing interval, opposite signs at the boundaries are required.") solve( + int_prob, + ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = SciMLLogging.ErrorLevel())) + + # Test that the linear verbosity is passed to the linear solve + f(u, p) = [u[1]^2 - 2u[1] + 1, sum(u)] + prob = NonlinearProblem(f, [1.0, 1.0]) + + @test_logs (:warn, + "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( + prob, + verbose = NonlinearVerbosity(linear_verbosity = SciMLLogging.Detailed())) + + @test_logs (:info, + "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( + prob, + verbose = NonlinearVerbosity(linear_verbosity = LinearVerbosity(default_lu_fallback = SciMLLogging.InfoLevel()))) + + @test_logs min_level=Logging.Info solve( + prob, + verbose = NonlinearVerbosity(linear_verbosity = SciMLLogging.Standard())) + + @test_logs (:warn, + "LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.") match_mode=:any solve( + prob, + verbose = NonlinearVerbosity(linear_verbosity = SciMLLogging.Detailed()) + ) + + @test_logs min_level=Logging.Info solve(prob, + verbose = NonlinearVerbosity(SciMLLogging.None())) + + @test_logs min_level=Logging.Info solve(prob, + verbose = false) + + # Test that caches get correct verbosities + cache = init( + prob, verbose = NonlinearVerbosity(threshold_state = SciMLLogging.InfoLevel())) + + @test cache.verbose.threshold_state == SciMLLogging.InfoLevel() end From 0ae7c11970ac244a1919f17d1fa328a17d4967b4 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 21 Oct 2025 10:15:41 -0400 Subject: [PATCH 38/51] linear should be minimal --- lib/NonlinearSolveBase/src/verbosity.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index 58b7fbe59..dbe479cc2 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -228,7 +228,7 @@ function NonlinearVerbosity(verbose::AbstractVerbosityPreset) elseif verbose isa Detailed # Detailed: Everything from Standard + debugging/solver behavior NonlinearVerbosity( - linear_verbosity = Detailed(), + linear_verbosity = Minimal(), immutable_u0 = WarnLevel(), non_enclosing_interval = WarnLevel(), non_forward_mode = InfoLevel(), From 3713686efd8891fced4d593bc988246b8f5a9b9a Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 21 Oct 2025 12:20:55 -0400 Subject: [PATCH 39/51] fix imports and exports --- lib/NonlinearSolveBase/src/NonlinearSolveBase.jl | 2 +- .../src/NonlinearSolveSpectralMethods.jl | 3 ++- lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index 3b8523c41..21604be5a 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -98,7 +98,7 @@ export DescentResult, SteepestDescent, NewtonDescent, DampedNewtonDescent, Dogle export NonlinearSolvePolyAlgorithm -export NonlinearVerbosity, NonlinearPerformanceVerbosity, NonlinearErrorControlVerbosity, NonlinearNumericalVerbosity +export NonlinearVerbosity export pickchunksize diff --git a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl index b9b80e13b..ae897d58c 100644 --- a/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl +++ b/lib/NonlinearSolveSpectralMethods/src/NonlinearSolveSpectralMethods.jl @@ -9,7 +9,8 @@ using LineSearch: RobustNonMonotoneLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, AbstractNonlinearSolveCache, Utils, InternalAPI, get_timer_output, - @static_timeit, update_trace!, NonlinearVerbosity, @SciMLMessage, None + @static_timeit, update_trace!, NonlinearVerbosity, @SciMLMessage, None, + AbstractVerbosityPreset using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearProblem, NonlinearFunction, NoSpecialize diff --git a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl index 0d218561d..0cc71cdb6 100644 --- a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl +++ b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl @@ -12,7 +12,8 @@ using LineSearch: LiFukushimaLineSearch using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, ImmutableNonlinearProblem, L2_NORM, nonlinearsolve_forwarddiff_solve, nonlinearsolve_dual_solution, - AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, Verbosity + AbstractNonlinearSolveAlgorithm, NonlinearVerbosity, @SciMLMessage, + AbstractVerbosityPreset using SciMLBase: SciMLBase, NonlinearFunction, NonlinearProblem, NonlinearLeastSquaresProblem, ReturnCode, remake From 75c2155cd8fb5780bcf6ea99bc47bd059a9fe702 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 21 Oct 2025 12:21:20 -0400 Subject: [PATCH 40/51] add SciMLLogging to test target --- Project.toml | 4 +++- test/verbosity_tests.jl | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index d5777fc11..128d5f519 100644 --- a/Project.toml +++ b/Project.toml @@ -106,6 +106,7 @@ Random = "1.10" ReTestItems = "1.24" Reexport = "1.2.2" ReverseDiff = "1.15" +SciMLLogging = "1.3" SIAMFANLEquations = "1.0.1" SciMLBase = "2.116" SimpleNonlinearSolve = "2.1" @@ -145,6 +146,7 @@ PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" ReTestItems = "817f1d60-ba6b-4fd5-9520-3cf149f6a823" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" +SciMLLogging = "a6db7da4-7206-11f0-1eab-35f2a5dbe1d1" SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4" SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" @@ -157,4 +159,4 @@ Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [targets] -test = ["Aqua", "BandedMatrices", "BenchmarkTools", "ExplicitImports", "FastLevenbergMarquardt", "FixedPointAcceleration", "Hwloc", "InteractiveUtils", "LeastSquaresOptim", "LineSearches", "MINPACK", "NLSolvers", "NLsolve", "NaNMath", "NonlinearProblemLibrary", "OrdinaryDiffEqTsit5", "PETSc", "Pkg", "PolyesterForwardDiff", "Random", "ReTestItems", "SIAMFANLEquations", "SparseConnectivityTracer", "SparseMatrixColorings", "SpeedMapping", "StableRNGs", "StaticArrays", "Sundials", "Test", "Zygote", "ReverseDiff", "Tracker"] +test = ["Aqua", "BandedMatrices", "BenchmarkTools", "ExplicitImports", "FastLevenbergMarquardt", "FixedPointAcceleration", "Hwloc", "InteractiveUtils", "LeastSquaresOptim", "LineSearches", "MINPACK", "NLSolvers", "NLsolve", "NaNMath", "NonlinearProblemLibrary", "OrdinaryDiffEqTsit5", "PETSc", "Pkg", "PolyesterForwardDiff", "Random", "ReTestItems", "SIAMFANLEquations", "SparseConnectivityTracer", "SparseMatrixColorings", "SpeedMapping", "StableRNGs", "StaticArrays", "Sundials", "Test", "Zygote", "ReverseDiff", "Tracker", "SciMLLogging"] diff --git a/test/verbosity_tests.jl b/test/verbosity_tests.jl index f727dd619..24a8bf419 100644 --- a/test/verbosity_tests.jl +++ b/test/verbosity_tests.jl @@ -6,7 +6,6 @@ using SciMLLogging: SciMLLogging using Logging using Test - using Logging @testset "NonlinearVerbosity preset constructors" begin v_none = NonlinearVerbosity(SciMLLogging.None()) @@ -89,8 +88,8 @@ int_prob, ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = SciMLLogging.InfoLevel())) - @test_throws Test.FallbackTestSetException @test_logs (:error, - "The interval is not an enclosing interval, opposite signs at the boundaries are required.") solve( + @test_logs (:error, + "The interval is not an enclosing interval, opposite signs at the boundaries are required.") @test_throws ErrorException solve( int_prob, ITP(), verbose = NonlinearVerbosity(non_enclosing_interval = SciMLLogging.ErrorLevel())) From ba250b07acb8f901bdc84cac26aab05d4475d894 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 21 Oct 2025 12:45:39 -0400 Subject: [PATCH 41/51] fix verbosity tests --- test/verbosity_tests.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/verbosity_tests.jl b/test/verbosity_tests.jl index 24a8bf419..eb70f6caa 100644 --- a/test/verbosity_tests.jl +++ b/test/verbosity_tests.jl @@ -4,7 +4,6 @@ using NonlinearSolve: NonlinearVerbosity using LinearSolve: LinearVerbosity using SciMLLogging: SciMLLogging - using Logging using Test @testset "NonlinearVerbosity preset constructors" begin @@ -107,7 +106,7 @@ prob, verbose = NonlinearVerbosity(linear_verbosity = LinearVerbosity(default_lu_fallback = SciMLLogging.InfoLevel()))) - @test_logs min_level=Logging.Info solve( + @test_logs min_level=0 solve( prob, verbose = NonlinearVerbosity(linear_verbosity = SciMLLogging.Standard())) @@ -117,10 +116,10 @@ verbose = NonlinearVerbosity(linear_verbosity = SciMLLogging.Detailed()) ) - @test_logs min_level=Logging.Info solve(prob, + @test_logs min_level=0 solve(prob, verbose = NonlinearVerbosity(SciMLLogging.None())) - @test_logs min_level=Logging.Info solve(prob, + @test_logs min_level=0 solve(prob, verbose = false) # Test that caches get correct verbosities From 58840ade0c7178c52e8ae319ea0f916c9071a522 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 21 Oct 2025 13:57:18 -0400 Subject: [PATCH 42/51] remove bad getproperty --- lib/NonlinearSolveBase/src/verbosity.jl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index dbe479cc2..c02aaab80 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -305,16 +305,3 @@ end end end -function Base.getproperty(verbosity::NonlinearVerbosity, name::Symbol) - # Check if this is a group name - if name === :error_control - return group_options(verbosity, :error_control) - elseif name === :performance - return group_options(verbosity, :performance) - elseif name === :numerical - return group_options(verbosity, :numerical) - else - # Fall back to default field access - return getfield(verbosity, name) - end -end From d6ee5c5f0eda582acab6d28b56339377a144a89a Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 21 Oct 2025 13:57:26 -0400 Subject: [PATCH 43/51] bump SciMLLogging --- lib/NonlinearSolveBase/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/Project.toml b/lib/NonlinearSolveBase/Project.toml index 57385af12..4bbc73948 100644 --- a/lib/NonlinearSolveBase/Project.toml +++ b/lib/NonlinearSolveBase/Project.toml @@ -84,7 +84,7 @@ RecursiveArrayTools = "3" ReverseDiff = "1.15" SciMLBase = "2.116" SciMLJacobianOperators = "0.1.1" -SciMLLogging = "1.3.0" +SciMLLogging = "1.3.1" SciMLOperators = "1.7" SciMLStructures = "1.5" Setfield = "1.1.2" From 5be94e0e1ee3ce482fe8b9f703e4039e1ab5c6cf Mon Sep 17 00:00:00 2001 From: jClugstor Date: Tue, 21 Oct 2025 19:09:13 -0400 Subject: [PATCH 44/51] remove unused toggles --- lib/NonlinearSolveBase/src/verbosity.jl | 116 +++--------------- .../src/solve.jl | 4 +- test/verbosity_tests.jl | 49 +++----- 3 files changed, 41 insertions(+), 128 deletions(-) diff --git a/lib/NonlinearSolveBase/src/verbosity.jl b/lib/NonlinearSolveBase/src/verbosity.jl index c02aaab80..ab4b558f1 100644 --- a/lib/NonlinearSolveBase/src/verbosity.jl +++ b/lib/NonlinearSolveBase/src/verbosity.jl @@ -7,27 +7,15 @@ diagnostic messages, warnings, and errors during nonlinear system solution. # Fields ## Error Control Group -- `immutable_u0`: Messages when u0 is immutable -- `non_enclosing_interval`: Messages when interval doesn't enclose root -- `non_forward_mode`: Messages when forward mode AD is not used -- `fd_ad_caution`: Messages about finite differencing cautions -- `ad_backend_incompatible`: Messages when AD backend is incompatible +- `non_enclosing_interval`: Messages when interval doesn't enclose root (bracketing methods) - `alias_u0_immutable`: Messages when aliasing u0 with immutable array - `linsolve_failed_noncurrent`: Messages when linear solve fails on non-current iteration -- `jacobian_free`: Messages about jacobian-free methods - `termination_condition`: Messages about termination conditions -## Performance Group -- `colorvec_non_sparse`: Messages when color vector is used with non-sparse matrix -- `colorvec_no_prototype`: Messages when color vector has no prototype -- `sparsity_using_jac_prototype`: Messages when using jacobian prototype for sparsity -- `sparse_matrixcolorings_not_loaded`: Messages when SparseMatrixColorings not loaded - ## Numerical Group -- `threshold_state`: Messages about threshold state -- `pinv_undefined`: Messages when pseudoinverse is undefined +- `threshold_state`: Messages about threshold state in low-rank methods -## Linear Solver +## Linear Solver Group - `linear_verbosity`: Verbosity configuration for linear solvers # Constructors @@ -59,14 +47,14 @@ verbose = NonlinearVerbosity( # Set individual fields verbose = NonlinearVerbosity( - immutable_u0 = SciMLLogging.WarnLevel(), + alias_u0_immutable = SciMLLogging.WarnLevel(), threshold_state = SciMLLogging.InfoLevel() ) # Mix group and individual settings verbose = NonlinearVerbosity( numerical = SciMLLogging.InfoLevel(), # Set all numerical to InfoLevel - pinv_undefined = SciMLLogging.ErrorLevel() # Override specific field + threshold_state = SciMLLogging.ErrorLevel() # Override specific field ) ``` """ @@ -74,36 +62,21 @@ verbose = NonlinearVerbosity( # Linear verbosity linear_verbosity # Error control - immutable_u0 non_enclosing_interval - non_forward_mode - fd_ad_caution - ad_backend_incompatible alias_u0_immutable linsolve_failed_noncurrent - jacobian_free termination_condition - # Performance - colorvec_non_sparse - colorvec_no_prototype - sparsity_using_jac_prototype - sparse_matrixcolorings_not_loaded # Numerical threshold_state - pinv_undefined end # Group classifications const error_control_options = ( - :immutable_u0, :non_enclosing_interval, :non_forward_mode, :fd_ad_caution, - :ad_backend_incompatible, :alias_u0_immutable, :linsolve_failed_noncurrent, - :jacobian_free, :termination_condition -) -const performance_options = ( - :colorvec_non_sparse, :colorvec_no_prototype, :sparsity_using_jac_prototype, - :sparse_matrixcolorings_not_loaded + :non_enclosing_interval, :alias_u0_immutable, :linsolve_failed_noncurrent, + :termination_condition ) -const numerical_options = (:threshold_state, :pinv_undefined) +const performance_options = () +const numerical_options = (:threshold_state,) function option_group(option::Symbol) if option in error_control_options @@ -121,13 +94,13 @@ end function group_options(verbosity::NonlinearVerbosity, group::Symbol) if group === :error_control return NamedTuple{error_control_options}(getproperty(verbosity, opt) - for opt in error_control_options) + for opt in error_control_options) elseif group === :performance return NamedTuple{performance_options}(getproperty(verbosity, opt) - for opt in performance_options) + for opt in performance_options) elseif group === :numerical return NamedTuple{numerical_options}(getproperty(verbosity, opt) - for opt in numerical_options) + for opt in numerical_options) else error("Unknown group: $group") end @@ -161,21 +134,11 @@ function NonlinearVerbosity(; # Build arguments using NamedTuple for type stability default_args = ( linear_verbosity = linear_verbosity === nothing ? Minimal() : linear_verbosity, - immutable_u0 = WarnLevel(), non_enclosing_interval = WarnLevel(), - non_forward_mode = WarnLevel(), - fd_ad_caution = WarnLevel(), - ad_backend_incompatible = WarnLevel(), alias_u0_immutable = WarnLevel(), linsolve_failed_noncurrent = WarnLevel(), - jacobian_free = WarnLevel(), termination_condition = WarnLevel(), - colorvec_non_sparse = WarnLevel(), - colorvec_no_prototype = WarnLevel(), - sparsity_using_jac_prototype = WarnLevel(), - sparse_matrixcolorings_not_loaded = WarnLevel(), - threshold_state = WarnLevel(), - pinv_undefined = WarnLevel() + threshold_state = WarnLevel() ) # Apply group-level settings @@ -206,21 +169,11 @@ function NonlinearVerbosity(verbose::AbstractVerbosityPreset) # Minimal: Only fatal errors and critical warnings NonlinearVerbosity( linear_verbosity = Minimal(), - immutable_u0 = WarnLevel(), non_enclosing_interval = WarnLevel(), - non_forward_mode = Silent(), - fd_ad_caution = Silent(), - ad_backend_incompatible = WarnLevel(), alias_u0_immutable = Silent(), linsolve_failed_noncurrent = WarnLevel(), - jacobian_free = Silent(), termination_condition = Silent(), - colorvec_non_sparse = Silent(), - colorvec_no_prototype = Silent(), - sparsity_using_jac_prototype = Silent(), - sparse_matrixcolorings_not_loaded = Silent(), - threshold_state = Silent(), - pinv_undefined = ErrorLevel() + threshold_state = Silent() ) elseif verbose isa Standard # Standard: Everything from Minimal + non-fatal warnings @@ -228,42 +181,22 @@ function NonlinearVerbosity(verbose::AbstractVerbosityPreset) elseif verbose isa Detailed # Detailed: Everything from Standard + debugging/solver behavior NonlinearVerbosity( - linear_verbosity = Minimal(), - immutable_u0 = WarnLevel(), + linear_verbosity = Detailed(), non_enclosing_interval = WarnLevel(), - non_forward_mode = InfoLevel(), - fd_ad_caution = WarnLevel(), - ad_backend_incompatible = WarnLevel(), alias_u0_immutable = WarnLevel(), linsolve_failed_noncurrent = WarnLevel(), - jacobian_free = InfoLevel(), termination_condition = WarnLevel(), - colorvec_non_sparse = InfoLevel(), - colorvec_no_prototype = InfoLevel(), - sparsity_using_jac_prototype = InfoLevel(), - sparse_matrixcolorings_not_loaded = InfoLevel(), - threshold_state = WarnLevel(), - pinv_undefined = WarnLevel() + threshold_state = WarnLevel() ) elseif verbose isa All # All: Maximum verbosity - every possible logging message at InfoLevel NonlinearVerbosity( - linear_verbosity = All(), - immutable_u0 = WarnLevel(), + linear_verbosity = Detailed(), non_enclosing_interval = WarnLevel(), - non_forward_mode = InfoLevel(), - fd_ad_caution = WarnLevel(), - ad_backend_incompatible = WarnLevel(), alias_u0_immutable = WarnLevel(), linsolve_failed_noncurrent = WarnLevel(), - jacobian_free = InfoLevel(), termination_condition = WarnLevel(), - colorvec_non_sparse = InfoLevel(), - colorvec_no_prototype = InfoLevel(), - sparsity_using_jac_prototype = InfoLevel(), - sparse_matrixcolorings_not_loaded = InfoLevel(), - threshold_state = InfoLevel(), - pinv_undefined = WarnLevel() + threshold_state = InfoLevel() ) end end @@ -275,16 +208,6 @@ end Silent(), Silent(), Silent(), - Silent(), - Silent(), - Silent(), - Silent(), - Silent(), - Silent(), - Silent(), - Silent(), - Silent(), - Silent(), Silent() ) end @@ -303,5 +226,4 @@ end else return default_val end -end - +end \ No newline at end of file diff --git a/lib/NonlinearSolveSpectralMethods/src/solve.jl b/lib/NonlinearSolveSpectralMethods/src/solve.jl index 74ba39bf9..04dc2d661 100644 --- a/lib/NonlinearSolveSpectralMethods/src/solve.jl +++ b/lib/NonlinearSolveSpectralMethods/src/solve.jl @@ -188,8 +188,8 @@ function InternalAPI.step!( kwargs... ) if recompute_jacobian !== nothing - @SciMLMessage("GeneralizedDFSane is a Jacobian-Free Algorithm. Ignoring \ - `recompute_jacobian`", cache.verbose, :jacobian_free) + @warn "GeneralizedDFSane is a Jacobian-Free Algorithm. Ignoring \ + `recompute_jacobian`" end @static_timeit cache.timer "descent" begin diff --git a/test/verbosity_tests.jl b/test/verbosity_tests.jl index eb70f6caa..6cfb01df7 100644 --- a/test/verbosity_tests.jl +++ b/test/verbosity_tests.jl @@ -13,69 +13,60 @@ v_standard = NonlinearVerbosity(SciMLLogging.Standard()) v_detailed = NonlinearVerbosity(SciMLLogging.Detailed()) - @test v_none.immutable_u0 isa SciMLLogging.Silent + @test v_none.non_enclosing_interval isa SciMLLogging.Silent @test v_none.threshold_state isa SciMLLogging.Silent - @test v_none.colorvec_non_sparse isa SciMLLogging.Silent + @test v_none.alias_u0_immutable isa SciMLLogging.Silent - @test v_minimal.immutable_u0 isa SciMLLogging.WarnLevel - @test v_minimal.colorvec_non_sparse isa SciMLLogging.Silent - @test v_minimal.non_forward_mode isa SciMLLogging.Silent + @test v_minimal.non_enclosing_interval isa SciMLLogging.WarnLevel + @test v_minimal.alias_u0_immutable isa SciMLLogging.Silent + @test v_minimal.termination_condition isa SciMLLogging.Silent - @test v_standard.immutable_u0 isa SciMLLogging.WarnLevel + @test v_standard.non_enclosing_interval isa SciMLLogging.WarnLevel @test v_standard.threshold_state isa SciMLLogging.WarnLevel - @test v_detailed.colorvec_non_sparse isa SciMLLogging.InfoLevel - @test v_detailed.non_forward_mode isa SciMLLogging.InfoLevel - @test v_detailed.jacobian_free isa SciMLLogging.InfoLevel + @test v_detailed.alias_u0_immutable isa SciMLLogging.WarnLevel + @test v_detailed.termination_condition isa SciMLLogging.WarnLevel - @test v_all.colorvec_non_sparse isa SciMLLogging.InfoLevel + @test v_all.linsolve_failed_noncurrent isa SciMLLogging.WarnLevel @test v_all.threshold_state isa SciMLLogging.InfoLevel end @testset "Group-level keyword constructors" begin v_error = NonlinearVerbosity(error_control = SciMLLogging.ErrorLevel()) - @test v_error.immutable_u0 isa SciMLLogging.ErrorLevel + @test v_error.alias_u0_immutable isa SciMLLogging.ErrorLevel @test v_error.non_enclosing_interval isa SciMLLogging.ErrorLevel @test v_error.termination_condition isa SciMLLogging.ErrorLevel + @test v_error.linsolve_failed_noncurrent isa SciMLLogging.ErrorLevel v_numerical = NonlinearVerbosity(numerical = SciMLLogging.Silent()) @test v_numerical.threshold_state isa SciMLLogging.Silent - @test v_numerical.pinv_undefined isa SciMLLogging.Silent - - v_performance = NonlinearVerbosity(performance = SciMLLogging.InfoLevel()) - @test v_performance.colorvec_non_sparse isa SciMLLogging.InfoLevel - @test v_performance.colorvec_no_prototype isa SciMLLogging.InfoLevel - @test v_performance.sparsity_using_jac_prototype isa SciMLLogging.InfoLevel - @test v_performance.sparse_matrixcolorings_not_loaded isa SciMLLogging.InfoLevel end @testset "Mixed group and individual settings" begin v_mixed = NonlinearVerbosity( numerical = SciMLLogging.Silent(), threshold_state = SciMLLogging.WarnLevel(), - performance = SciMLLogging.InfoLevel() + error_control = SciMLLogging.InfoLevel() ) # Individual override should take precedence @test v_mixed.threshold_state isa SciMLLogging.WarnLevel - # Other numerical options should use group setting - @test v_mixed.pinv_undefined isa SciMLLogging.Silent - # Performance group setting should apply - @test v_mixed.colorvec_non_sparse isa SciMLLogging.InfoLevel - @test v_mixed.colorvec_no_prototype isa SciMLLogging.InfoLevel + # Error control group setting should apply + @test v_mixed.alias_u0_immutable isa SciMLLogging.InfoLevel + @test v_mixed.linsolve_failed_noncurrent isa SciMLLogging.InfoLevel end @testset "Individual keyword arguments" begin v_individual = NonlinearVerbosity( - immutable_u0 = SciMLLogging.ErrorLevel(), + alias_u0_immutable = SciMLLogging.ErrorLevel(), threshold_state = SciMLLogging.InfoLevel(), - colorvec_non_sparse = SciMLLogging.Silent() + termination_condition = SciMLLogging.Silent() ) - @test v_individual.immutable_u0 isa SciMLLogging.ErrorLevel + @test v_individual.alias_u0_immutable isa SciMLLogging.ErrorLevel @test v_individual.threshold_state isa SciMLLogging.InfoLevel - @test v_individual.colorvec_non_sparse isa SciMLLogging.Silent + @test v_individual.termination_condition isa SciMLLogging.Silent # Unspecified options should use defaults @test v_individual.non_enclosing_interval isa SciMLLogging.WarnLevel - @test v_individual.pinv_undefined isa SciMLLogging.WarnLevel + @test v_individual.linsolve_failed_noncurrent isa SciMLLogging.WarnLevel end g(u, p) = u^2 - 4 From 643f6677844f8e24527fc384dd7075f2cd5f6d5b Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Wed, 29 Oct 2025 06:42:48 -0400 Subject: [PATCH 45/51] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 128d5f519..06da666a1 100644 --- a/Project.toml +++ b/Project.toml @@ -85,7 +85,7 @@ LeastSquaresOptim = "0.8.5" LineSearch = "0.1.4" LineSearches = "7.3" LinearAlgebra = "1.10" -LinearSolve = "2.36.1, 3" +LinearSolve = "3.46" MINPACK = "1.2" MPI = "0.20.22" NLSolvers = "0.5" From cc41979c27a127342a585f16076bb8139c67106b Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Wed, 29 Oct 2025 06:43:09 -0400 Subject: [PATCH 46/51] Update Project.toml --- lib/NonlinearSolveBase/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NonlinearSolveBase/Project.toml b/lib/NonlinearSolveBase/Project.toml index 4bbc73948..dd98006f0 100644 --- a/lib/NonlinearSolveBase/Project.toml +++ b/lib/NonlinearSolveBase/Project.toml @@ -74,7 +74,7 @@ ForwardDiff = "0.10.36, 1" InteractiveUtils = "<0.0.1, 1" LineSearch = "0.1.4" LinearAlgebra = "1.10" -LinearSolve = "3.15" +LinearSolve = "3.46" Markdown = "1.10" MaybeInplace = "0.1.4" Mooncake = "0.4" From eb9bd6a7d625ed50b8965235f2cfb96910fe04e7 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 29 Oct 2025 13:39:30 -0400 Subject: [PATCH 47/51] remove stale imports --- lib/NonlinearSolveBase/src/NonlinearSolveBase.jl | 3 +-- lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl index 21604be5a..43d7e8439 100644 --- a/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl +++ b/lib/NonlinearSolveBase/src/NonlinearSolveBase.jl @@ -29,8 +29,7 @@ import SciMLBase: solve, init, __init, __solve, wrap_sol, get_root_indp, isinpla using SciMLJacobianOperators: JacobianOperator, StatefulJacobianOperator using SciMLOperators: AbstractSciMLOperator, IdentityOperator using SciMLLogging: @SciMLMessage, AbstractVerbositySpecifier, AbstractVerbosityPreset, AbstractMessageLevel, - None, Minimal, Standard, Detailed, All, Silent, InfoLevel, WarnLevel, ErrorLevel, - CustomLevel + None, Minimal, Standard, Detailed, All, Silent, InfoLevel, WarnLevel using SymbolicIndexingInterface: SymbolicIndexingInterface import SciMLStructures diff --git a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl index c3333fca0..72ce1ae1e 100644 --- a/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl +++ b/lib/NonlinearSolveFirstOrder/src/NonlinearSolveFirstOrder.jl @@ -22,8 +22,7 @@ using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm, update_trace!, L2_NORM, NonlinearSolvePolyAlgorithm, NewtonDescent, DampedNewtonDescent, GeodesicAcceleration, Dogleg, NonlinearSolveForwardDiffCache, NonlinearVerbosity, - @SciMLMessage, None, reused_jacobian, AbstractVerbositySpecifier, - AbstractVerbosityPreset + @SciMLMessage, None, reused_jacobian, AbstractVerbosityPreset using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode, NonlinearFunction, NonlinearLeastSquaresProblem, NonlinearProblem, NoSpecialize From 14e2e3f02df54ab74fd7b515d71aa206b780cdf2 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Wed, 29 Oct 2025 15:26:43 -0400 Subject: [PATCH 48/51] bump versions --- Project.toml | 4 ++-- lib/NonlinearSolveBase/Project.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 06da666a1..acefa9890 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "NonlinearSolve" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" authors = ["SciML"] -version = "4.12.0" +version = "4.13.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -92,7 +92,7 @@ NLSolvers = "0.5" NLsolve = "4.5" NaNMath = "1" NonlinearProblemLibrary = "0.1.2" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" NonlinearSolveFirstOrder = "1.2" NonlinearSolveQuasiNewton = "1.8" NonlinearSolveSpectralMethods = "1.1" diff --git a/lib/NonlinearSolveBase/Project.toml b/lib/NonlinearSolveBase/Project.toml index dd98006f0..41e51ddab 100644 --- a/lib/NonlinearSolveBase/Project.toml +++ b/lib/NonlinearSolveBase/Project.toml @@ -1,7 +1,7 @@ name = "NonlinearSolveBase" uuid = "be0214bd-f91f-a760-ac4e-3421ce2b2da0" authors = ["Avik Pal and contributors"] -version = "2.0" +version = "2.1" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" From 78288cd687e232ffb2fdaa0837262d76eca4e7a9 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Thu, 30 Oct 2025 12:35:54 -0400 Subject: [PATCH 49/51] bump nonlinearsolvebase for downgrade --- lib/BracketingNonlinearSolve/Project.toml | 2 +- lib/NonlinearSolveFirstOrder/Project.toml | 2 +- lib/NonlinearSolveHomotopyContinuation/Project.toml | 2 +- lib/NonlinearSolveQuasiNewton/Project.toml | 2 +- lib/NonlinearSolveSciPy/Project.toml | 2 +- lib/NonlinearSolveSpectralMethods/Project.toml | 2 +- lib/SCCNonlinearSolve/Project.toml | 2 +- lib/SimpleNonlinearSolve/Project.toml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/BracketingNonlinearSolve/Project.toml b/lib/BracketingNonlinearSolve/Project.toml index bfc4e05ad..850fa0201 100644 --- a/lib/BracketingNonlinearSolve/Project.toml +++ b/lib/BracketingNonlinearSolve/Project.toml @@ -30,7 +30,7 @@ ConcreteStructs = "0.2.3" ExplicitImports = "1.10.1" ForwardDiff = "0.10.36, 1" InteractiveUtils = "<0.0.1, 1" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" PrecompileTools = "1.2" Reexport = "1.2.2" SciMLBase = "2.116" diff --git a/lib/NonlinearSolveFirstOrder/Project.toml b/lib/NonlinearSolveFirstOrder/Project.toml index 6013a0360..41c99f87b 100644 --- a/lib/NonlinearSolveFirstOrder/Project.toml +++ b/lib/NonlinearSolveFirstOrder/Project.toml @@ -47,7 +47,7 @@ LinearAlgebra = "1.10" LinearSolve = "2.36.1, 3" MaybeInplace = "0.1.4" NonlinearProblemLibrary = "0.1.2" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" Pkg = "1.10" PrecompileTools = "1.2" Random = "1.10" diff --git a/lib/NonlinearSolveHomotopyContinuation/Project.toml b/lib/NonlinearSolveHomotopyContinuation/Project.toml index 41a4ea3c4..4239bbe89 100644 --- a/lib/NonlinearSolveHomotopyContinuation/Project.toml +++ b/lib/NonlinearSolveHomotopyContinuation/Project.toml @@ -34,7 +34,7 @@ HomotopyContinuation = "2.12.0" LinearAlgebra = "1.10" NaNMath = "1.1" NonlinearSolve = "4.10" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" SciMLBase = "2.116" SymbolicIndexingInterface = "0.3.43" TaylorDiff = "0.3.1" diff --git a/lib/NonlinearSolveQuasiNewton/Project.toml b/lib/NonlinearSolveQuasiNewton/Project.toml index 40d0be717..c5c5661cd 100644 --- a/lib/NonlinearSolveQuasiNewton/Project.toml +++ b/lib/NonlinearSolveQuasiNewton/Project.toml @@ -45,7 +45,7 @@ LinearAlgebra = "1.10" LinearSolve = "2.36.1, 3" MaybeInplace = "0.1.4" NonlinearProblemLibrary = "0.1.2" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" Pkg = "1.10" PrecompileTools = "1.2" ReTestItems = "1.24" diff --git a/lib/NonlinearSolveSciPy/Project.toml b/lib/NonlinearSolveSciPy/Project.toml index 9c7bc2880..ad5b05a50 100644 --- a/lib/NonlinearSolveSciPy/Project.toml +++ b/lib/NonlinearSolveSciPy/Project.toml @@ -18,7 +18,7 @@ path = "../NonlinearSolveBase" ConcreteStructs = "0.2.3" Hwloc = "3" InteractiveUtils = "<0.0.1, 1" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" PrecompileTools = "1.2" PythonCall = "0.9" ReTestItems = "1.24" diff --git a/lib/NonlinearSolveSpectralMethods/Project.toml b/lib/NonlinearSolveSpectralMethods/Project.toml index 267ea51f8..b19b18de0 100644 --- a/lib/NonlinearSolveSpectralMethods/Project.toml +++ b/lib/NonlinearSolveSpectralMethods/Project.toml @@ -34,7 +34,7 @@ InteractiveUtils = "<0.0.1, 1" LineSearch = "0.1.4" MaybeInplace = "0.1.4" NonlinearProblemLibrary = "0.1.2" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" Pkg = "1.10" PrecompileTools = "1.2" ReTestItems = "1.24" diff --git a/lib/SCCNonlinearSolve/Project.toml b/lib/SCCNonlinearSolve/Project.toml index bd547fa43..f44d9e9b8 100644 --- a/lib/SCCNonlinearSolve/Project.toml +++ b/lib/SCCNonlinearSolve/Project.toml @@ -20,7 +20,7 @@ LinearAlgebra = "1.10" InteractiveUtils = "<0.0.1, 1" NonlinearProblemLibrary = "0.1.2" NonlinearSolve = "4.8" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" NonlinearSolveFirstOrder = "1" Pkg = "1.10" PrecompileTools = "1.2" diff --git a/lib/SimpleNonlinearSolve/Project.toml b/lib/SimpleNonlinearSolve/Project.toml index a4b487f35..a7154cfeb 100644 --- a/lib/SimpleNonlinearSolve/Project.toml +++ b/lib/SimpleNonlinearSolve/Project.toml @@ -58,7 +58,7 @@ LineSearch = "0.1.3" LinearAlgebra = "1.10" MaybeInplace = "0.1.4" NonlinearProblemLibrary = "0.1.2" -NonlinearSolveBase = "2" +NonlinearSolveBase = "2.1" Pkg = "1.10" PolyesterForwardDiff = "0.1.3" PrecompileTools = "1.2" From 3991f12a1570bc42e2844aa07c3e9315d80d4f53 Mon Sep 17 00:00:00 2001 From: jClugstor Date: Mon, 3 Nov 2025 15:14:00 -0500 Subject: [PATCH 50/51] add some docs --- docs/src/basics/solve.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/src/basics/solve.md b/docs/src/basics/solve.md index 3bc7df056..15e967d52 100644 --- a/docs/src/basics/solve.md +++ b/docs/src/basics/solve.md @@ -36,3 +36,32 @@ These are exclusively available for native `NonlinearSolve.jl` solvers. level of detail of the trace. (Defaults to `TraceMinimal()`) - `store_trace`: Must be `Val(true)` or `Val(false)`. This controls whether the trace is stored in the solution object. (Defaults to `Val(false)`) + +## Verbosity Controls + +NonlinearSolve.jl provides fine-grained control over diagnostic messages, warnings, and errors +through the `verbose` keyword argument. The verbosity system allows you to control what +information is displayed during the solve process. See [SciMLLogging.jl](https://docs.sciml.ai/SciMLLogging/dev/) for more details. + +```@docs +NonlinearVerbosity +``` + +### Quick Start + +```julia +# Use a preset +solve(prob, alg; verbose = NonlinearVerbosity(SciMLLogging.Standard())) + +# Silence all messages +solve(prob, alg; verbose = NonlinearVerbosity(SciMLLogging.None())) + +# Maximum verbosity +solve(prob, alg; verbose = NonlinearVerbosity(SciMLLogging.All())) + +# Custom configuration +solve(prob, alg; verbose = NonlinearVerbosity( + alias_u0_immutable = SciMLLogging.WarnLevel(), + threshold_state = SciMLLogging.InfoLevel() +)) +``` \ No newline at end of file From bba8e7299bef28002bfffdebc32accd07189532a Mon Sep 17 00:00:00 2001 From: jClugstor Date: Mon, 3 Nov 2025 15:42:47 -0500 Subject: [PATCH 51/51] add some tests --- lib/NonlinearSolveBase/src/solve.jl | 32 ++++++++++-- test/verbosity_tests.jl | 81 ++++++++++++++++++++++++++++- 2 files changed, 109 insertions(+), 4 deletions(-) diff --git a/lib/NonlinearSolveBase/src/solve.jl b/lib/NonlinearSolveBase/src/solve.jl index 407037505..7632171f8 100644 --- a/lib/NonlinearSolveBase/src/solve.jl +++ b/lib/NonlinearSolveBase/src/solve.jl @@ -45,11 +45,23 @@ problems. https://docs.sciml.ai/SciMLSensitivity/stable/ """ function solve(prob::AbstractNonlinearProblem, args...; sensealg = nothing, - u0 = nothing, p = nothing, wrap = Val(true), kwargs...) + u0 = nothing, p = nothing, wrap = Val(true), verbose = NonlinearVerbosity(), kwargs...) if sensealg === nothing && haskey(prob.kwargs, :sensealg) sensealg = prob.kwargs[:sensealg] end + if verbose isa Bool + # @warn "Using `true` or `false` for `verbose` is being deprecated. Please use a `NonlinearVerbosity` type to specify verbosity settings. + # For details see the verbosity section of the common solver options documentation page." + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(None()) + end + elseif verbose isa AbstractVerbosityPreset + verbose = NonlinearVerbosity(verbose) + end + if haskey(prob.kwargs, :alias_u0) @warn "The `alias_u0` keyword argument is deprecated. Please use a NonlinearAliasSpecifier, e.g. `alias = NonlinearAliasSpecifier(alias_u0 = true)`." alias_spec = NonlinearAliasSpecifier(alias_u0 = prob.kwargs[:alias_u0]) @@ -85,6 +97,7 @@ function solve(prob::AbstractNonlinearProblem, args...; sensealg = nothing, args...; alias_u0 = alias_u0, originator = SciMLBase.ChainRulesOriginator(), + verbose, kwargs...)) else solve_up(prob, @@ -94,6 +107,7 @@ function solve(prob::AbstractNonlinearProblem, args...; sensealg = nothing, args...; alias_u0 = alias_u0, originator = SciMLBase.ChainRulesOriginator(), + verbose, kwargs...) end end @@ -165,15 +179,27 @@ end function init( prob::AbstractNonlinearProblem, args...; sensealg = nothing, - u0 = nothing, p = nothing, kwargs...) + u0 = nothing, p = nothing, verbose = NonlinearVerbosity(), kwargs...) if sensealg === nothing && has_kwargs(prob) && haskey(prob.kwargs, :sensealg) sensealg = prob.kwargs[:sensealg] end + if verbose isa Bool + # @warn "Using `true` or `false` for `verbose` is being deprecated. Please use a `NonlinearVerbosity` type to specify verbosity settings. + # For details see the verbosity section of the common solver options documentation page." + if verbose + verbose = NonlinearVerbosity() + else + verbose = NonlinearVerbosity(None()) + end + elseif verbose isa AbstractVerbosityPreset + verbose = NonlinearVerbosity(verbose) + end + u0 = u0 !== nothing ? u0 : prob.u0 p = p !== nothing ? p : prob.p - init_up(prob, sensealg, u0, p, args...; kwargs...) + init_up(prob, sensealg, u0, p, args...; verbose, kwargs...) end function init_up(prob::AbstractNonlinearProblem, diff --git a/test/verbosity_tests.jl b/test/verbosity_tests.jl index 6cfb01df7..d984b40e3 100644 --- a/test/verbosity_tests.jl +++ b/test/verbosity_tests.jl @@ -118,4 +118,83 @@ prob, verbose = NonlinearVerbosity(threshold_state = SciMLLogging.InfoLevel())) @test cache.verbose.threshold_state == SciMLLogging.InfoLevel() -end + + f(u, p) = u .* u .- 2 + prob = NonlinearProblem(f, [1.0, 1.0]) + + @testset "solve with Bool verbose" begin + # Test verbose = true works (default verbosity) + sol1 = solve(prob, verbose = true) + @test sol1.retcode == ReturnCode.Success + + # Test verbose = false silences all output + @test_logs min_level=0 sol2=solve(prob, verbose = false) + end + + @testset "solve with Preset verbose" begin + # Test verbose = SciMLLogging.Standard() works + sol1 = solve(prob, verbose = SciMLLogging.Standard()) + @test sol1.retcode == ReturnCode.Success + + # Test verbose = SciMLLogging.None() silences output + @test_logs min_level=0 sol2=solve(prob, verbose = SciMLLogging.None()) + + # Test verbose = SciMLLogging.Detailed() works + sol3 = solve(prob, verbose = SciMLLogging.Detailed()) + @test sol3.retcode == ReturnCode.Success + + # Test verbose = SciMLLogging.All() works + sol4 = solve(prob, verbose = SciMLLogging.All()) + @test sol4.retcode == ReturnCode.Success + + # Test verbose = SciMLLogging.Minimal() works + sol5 = solve(prob, verbose = SciMLLogging.Minimal()) + @test sol5.retcode == ReturnCode.Success + end + + @testset "init with Bool verbose" begin + # Test verbose = true converts to NonlinearVerbosity() + cache1 = init(prob, verbose = true) + @test cache1.verbose isa NonlinearVerbosity + @test cache1.verbose.threshold_state == SciMLLogging.WarnLevel() + + # Test verbose = false converts to NonlinearVerbosity(None()) + cache2 = init(prob, verbose = false) + @test cache2.verbose isa NonlinearVerbosity + @test cache2.verbose.threshold_state isa SciMLLogging.Silent + @test cache2.verbose.non_enclosing_interval isa SciMLLogging.Silent + end + + @testset "init with Preset verbose" begin + # Test verbose = SciMLLogging.Standard() converts to NonlinearVerbosity(Standard()) + cache1 = init(prob, verbose = SciMLLogging.Standard()) + @test cache1.verbose isa NonlinearVerbosity + @test cache1.verbose.threshold_state == SciMLLogging.WarnLevel() + + # Test verbose = SciMLLogging.None() converts to NonlinearVerbosity(None()) + cache2 = init(prob, verbose = SciMLLogging.None()) + @test cache2.verbose isa NonlinearVerbosity + @test cache2.verbose.threshold_state isa SciMLLogging.Silent + + # Test verbose = SciMLLogging.Detailed() + cache3 = init(prob, verbose = SciMLLogging.Detailed()) + @test cache3.verbose isa NonlinearVerbosity + @test cache3.verbose.linear_verbosity isa SciMLLogging.Detailed + + # Test verbose = SciMLLogging.All() + cache4 = init(prob, verbose = SciMLLogging.All()) + @test cache4.verbose isa NonlinearVerbosity + @test cache4.verbose.threshold_state == SciMLLogging.InfoLevel() + + # Test verbose = SciMLLogging.Minimal() + cache5 = init(prob, verbose = SciMLLogging.Minimal()) + @test cache5.verbose isa NonlinearVerbosity + @test cache5.verbose.alias_u0_immutable isa SciMLLogging.Silent + end + + @testset "init then solve with converted verbose" begin + # Ensure the converted verbose works through the full solve pipeline + cache = init(prob, verbose = false) + @test_logs min_level=0 sol=solve!(cache) + end +end \ No newline at end of file