Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5c39756
add SciMLLogging
jClugstor Aug 14, 2025
45e0d9c
add verbosity types
jClugstor Aug 14, 2025
1d6d3ec
replace verbose::Bool with verbose::LinearVerbosity
jClugstor Aug 14, 2025
6cd9cd3
export symbols, include verbosity.jl
jClugstor Aug 14, 2025
1ed323e
add verbosity documentation
jClugstor Aug 14, 2025
a615319
add verbosity to IterativeSolversExt
jClugstor Aug 14, 2025
b633151
add verbosity to KrylovKitExt
jClugstor Aug 14, 2025
122d468
add verbose to PardisoExt
jClugstor Aug 14, 2025
b13cd18
add verbose to HYPREExt
jClugstor Aug 14, 2025
20ee9f2
add verbose for iterative solvers
jClugstor Aug 14, 2025
1e5a1fd
bring in LinearVerbosity
jClugstor Aug 14, 2025
3211d66
imports
jClugstor Aug 14, 2025
9fed2eb
fix default
jClugstor Aug 14, 2025
62493c6
add tests
jClugstor Aug 14, 2025
0a622f1
make verbose = Bool also valid for backwards compat
jClugstor Aug 14, 2025
1d6f117
allow bool verbose
jClugstor Aug 14, 2025
504bed7
fix _init_cacheval
jClugstor Aug 14, 2025
af132db
fix verbose for HYPRE
jClugstor Aug 14, 2025
4c1f8d3
add compat for SciMLLogging
jClugstor Aug 14, 2025
25e508c
get rid of stale import
jClugstor Aug 14, 2025
e4c0d8a
Update runtests.jl
ChrisRackauckas Aug 18, 2025
40250e7
change bool to LinearVerbosity
jClugstor Aug 18, 2025
8d45e45
add messages for fallbacks
jClugstor Aug 18, 2025
02ecd5f
make constructor for logging disabled better
jClugstor Aug 22, 2025
4c1572c
fix up verbosity for extensions
jClugstor Aug 22, 2025
de31163
from Bool to LinearVerbosity
jClugstor Aug 22, 2025
926875c
import LinearVerbosity for extensions
jClugstor Aug 22, 2025
1e6c174
fix the imports for CliqueTrees
jClugstor Aug 22, 2025
6dfa0a1
fix krylov verbosity
jClugstor Aug 22, 2025
7bf8519
update verbosity
jClugstor Sep 21, 2025
8444e87
add more tests for verbosity
jClugstor Sep 21, 2025
1c2f20a
make default constructor not do runtime dispatch
jClugstor Sep 21, 2025
1d72a56
bump version compat
jClugstor Sep 21, 2025
03f2629
remove incorrect exports
jClugstor Sep 21, 2025
78400b8
fix aqua test
jClugstor Sep 21, 2025
f937f2a
fix verbosity kwarg handling
jClugstor Sep 21, 2025
ca0e50c
add BLAS verbosity
jClugstor Sep 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Preferences = "21216c6a-2e73-6563-6e65-726566657250"
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
SciMLLogging = "a6db7da4-7206-11f0-1eab-35f2a5dbe1d1"
SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
Expand Down Expand Up @@ -124,6 +125,7 @@ Reexport = "1.2.2"
SafeTestsets = "0.1"
SciMLBase = "2.70"
SciMLOperators = "1.7.1"
SciMLLogging = "1.1.0"
Setfield = "1.1.1"
SparseArrays = "1.10"
Sparspak = "0.3.9"
Expand Down
2 changes: 1 addition & 1 deletion docs/src/advanced/developing.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct MyLUFactorization{P} <: LinearSolve.SciMLLinearSolveAlgorithm end

function LinearSolve.init_cacheval(
alg::MyLUFactorization, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol,
verbose::Bool, assump::LinearSolve.OperatorAssumptions)
verbose::LinearVerbosity, assump::LinearSolve.OperatorAssumptions)
lu!(convert(AbstractMatrix, A))
end

Expand Down
89 changes: 89 additions & 0 deletions docs/src/basics/common_solver_opts.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,92 @@ solve completely. Error controls only apply to iterative solvers.
- `maxiters`: The number of iterations allowed. Defaults to `length(prob.b)`
- `Pl,Pr`: The left and right preconditioners, respectively. For more information,
see [the Preconditioners page](@ref prec).

## Verbosity Controls

The verbosity system in LinearSolve.jl provides fine-grained control over the diagnostic messages, warnings, and errors that are displayed during the solution of linear systems.

The verbosity system is organized hierarchically into three main categories:

1. Error Control - Messages related to fallbacks and error handling
2. Performance - Messages related to performance considerations
3. Numerical - Messages related to numerical solvers and iterations

Each category can be configured independently, and individual settings can be adjusted to suit your needs.

### Verbosity Levels
The following verbosity levels are available:

#### Individual Settings
These settings are meant for individual settings within a category. These can also be used to set all of the individual settings in a group to the same value.
- SciMLLogging.None() - Suppress all messages
- SciMLLogging.Info() - Show message as log message at info level
- SciMLLogging.Warn() - Show warnings (default for most settings)
- SciMLLogging.Error() - Throw errors instead of warnings
- SciMLLogging.Level(n) - Show messages with a log level setting of n

#### Group Settings
These settings are meant for controlling a group of settings.
- SciMLLogging.Default() - Use the default settings
- SciMLLogging.All() - Show all possible messages

### Basic Usage

#### Global Verbosity Control

```julia
using LinearSolve

# Suppress all messages
verbose = LinearVerbosity(SciMLLogging.None())
prob = LinearProblem(A, b)
sol = solve(prob; verbose=verbose)

# Show all messages
verbose = LinearVerbosity(SciMLLogging.All())
sol = solve(prob; verbose=verbose)

# Use default settings
verbose = LinearVerbosity(SciMLLogging.Default())
sol = solve(prob; verbose=verbose)
```

#### Group Level Control

```julia
# Customize by category
verbose = LinearVerbosity(
error_control = SciMLLogging.Warn(), # Show warnings for error control related issues
performance = SciMLLogging.None(), # Suppress performance messages
numerical = SciMLLogging.Info() # Show all numerical related log messages at info level
)

sol = solve(prob; verbose=verbose)
```

#### Fine-grained Control
The constructor for `LinearVerbosity` allows you to set verbosity for each specific message toggle, giving you fine-grained control.
The verbosity settings for the toggles are automatically passed to the group objects.
```julia
# Set specific message types
verbose = LinearVerbosity(
default_lu_fallback = SciMLLogging.Info(), # Show info when LU fallback is used
KrylovJL_verbosity = SciMLLogging.Warn(), # Show warnings from KrylovJL
no_right_preconditioning = SciMLLogging.None(), # Suppress right preconditioning messages
KrylovKit_verbosity = SciMLLogging.Level(KrylovKit.WARN_LEVEL) # Set KrylovKit verbosity level using KrylovKit's own verbosity levels
)

sol = solve(prob; verbose=verbose)

```

#### Verbosity Levels
##### Error Control Settings
- default_lu_fallback: Controls messages when falling back to LU factorization (default: Warn)
##### Performance Settings
- no_right_preconditioning: Controls messages when right preconditioning is not used (default: Warn)
##### Numerical Settings
- using_IterativeSolvers: Controls messages when using the IterativeSolvers.jl package (default: Warn)
- IterativeSolvers_iterations: Controls messages about iteration counts from IterativeSolvers.jl (default: Warn)
- KrylovKit_verbosity: Controls messages from the KrylovKit.jl package (default: Warn)
- KrylovJL_verbosity: Controls verbosity of the KrylovJL.jl package (default: None)
6 changes: 3 additions & 3 deletions ext/LinearSolveAMDGPUExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module LinearSolveAMDGPUExt

using AMDGPU
using LinearSolve: LinearSolve, LinearCache, AMDGPUOffloadLUFactorization,
AMDGPUOffloadQRFactorization, init_cacheval, OperatorAssumptions
AMDGPUOffloadQRFactorization, init_cacheval, OperatorAssumptions, LinearVerbosity
using LinearSolve.LinearAlgebra, LinearSolve.SciMLBase

# LU Factorization
Expand All @@ -25,7 +25,7 @@ function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::AMDGPUOffloadLUFa
end

function LinearSolve.init_cacheval(alg::AMDGPUOffloadLUFactorization, A, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
AMDGPU.rocSOLVER.getrf!(AMDGPU.ROCArray(A))
end
Expand Down Expand Up @@ -57,7 +57,7 @@ function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::AMDGPUOffloadQRFa
end

function LinearSolve.init_cacheval(alg::AMDGPUOffloadQRFactorization, A, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
A_gpu = AMDGPU.ROCArray(A)
tau = AMDGPU.ROCVector{eltype(A_gpu)}(undef, min(size(A_gpu)...))
Expand Down
40 changes: 37 additions & 3 deletions ext/LinearSolveBLISExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ using LinearSolve
using LinearAlgebra: BlasInt, LU
using LinearAlgebra.LAPACK: require_one_based_indexing, chkfinite, chkstride1,
@blasfunc, chkargsok
using LinearSolve: ArrayInterface, BLISLUFactorization, @get_cacheval, LinearCache, SciMLBase
using LinearSolve: ArrayInterface, BLISLUFactorization, @get_cacheval, LinearCache, SciMLBase, LinearVerbosity, get_blas_operation_info, blas_info_msg
using SciMLLogging: SciMLLogging, @SciMLMessage
using SciMLBase: ReturnCode

const global libblis = blis_jll.blis
Expand Down Expand Up @@ -204,13 +205,13 @@ const PREALLOCATED_BLIS_LU = begin
end

function LinearSolve.init_cacheval(alg::BLISLUFactorization, A::Matrix{Float64}, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
PREALLOCATED_BLIS_LU
end

function LinearSolve.init_cacheval(alg::BLISLUFactorization, A::AbstractMatrix{<:Union{Float32,ComplexF32,ComplexF64}}, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
A = rand(eltype(A), 0, 0)
ArrayInterface.lu_instance(A), Ref{BlasInt}()
Expand All @@ -220,12 +221,45 @@ function SciMLBase.solve!(cache::LinearCache, alg::BLISLUFactorization;
kwargs...)
A = cache.A
A = convert(AbstractMatrix, A)
verbose = cache.verbose
if cache.isfresh
cacheval = @get_cacheval(cache, :BLISLUFactorization)
res = getrf!(A; ipiv = cacheval[1].ipiv, info = cacheval[2])
fact = LU(res[1:3]...), res[4]
cache.cacheval = fact

info_value = res[3]

if info_value != 0
if !isa(verbose.blas_info, SciMLLogging.Silent) || !isa(verbose.blas_errors, SciMLLogging.Silent) ||
!isa(verbose.blas_invalid_args, SciMLLogging.Silent)
op_info = get_blas_operation_info(:dgetrf, A, cache.b, condition = !isa(verbose.condition_number, SciMLLogging.Silent))
@SciMLMessage(cache.verbose, :condition_number) do
if op_info[:condition_number] === nothing
return "Matrix condition number calculation failed."
else
return "Matrix condition number: $(round(op_info[:condition_number], sigdigits=4)) for $(size(A, 1))×$(size(A, 2)) matrix in dgetrf"
end
end
verb_option, message = blas_info_msg(
:dgetrf, info_value; extra_context = op_info)
@SciMLMessage(message, verbose, verb_option)
end
else
@SciMLMessage(cache.verbose, :blas_success) do
op_info = get_blas_operation_info(:dgetrf, A, cache.b,
condition = !isa(verbose.condition_number, SciMLLogging.Silent))
@SciMLMessage(cache.verbose, :condition_number) do
if op_info[:condition_number] === nothing
return "Matrix condition number calculation failed."
else
return "Matrix condition number: $(round(op_info[:condition_number], sigdigits=4)) for $(size(A, 1))×$(size(A, 2)) matrix in dgetrf"
end
end
return "BLAS LU factorization (dgetrf) completed successfully for $(op_info[:matrix_size]) matrix"
end
end

if !LinearAlgebra.issuccess(fact[1])
return SciMLBase.build_linear_solution(
alg, cache.u, nothing, cache; retcode = ReturnCode.Failure)
Expand Down
8 changes: 4 additions & 4 deletions ext/LinearSolveBandedMatricesExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module LinearSolveBandedMatricesExt
using BandedMatrices, LinearAlgebra, LinearSolve
import LinearSolve: defaultalg,
do_factorization, init_cacheval, DefaultLinearSolver,
DefaultAlgorithmChoice
DefaultAlgorithmChoice, LinearVerbosity

# Defaults for BandedMatrices
function defaultalg(A::BandedMatrix, b, oa::OperatorAssumptions{Bool})
Expand Down Expand Up @@ -41,14 +41,14 @@ for alg in (:SVDFactorization, :MKLLUFactorization, :DiagonalFactorization,
:AppleAccelerateLUFactorization, :CholeskyFactorization)
@eval begin
function init_cacheval(::$(alg), ::BandedMatrix, b, u, Pl, Pr, maxiters::Int,
abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions)
abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions)
return nothing
end
end
end

function init_cacheval(::LUFactorization, A::BandedMatrix{T}, b, u, Pl, Pr, maxiters::Int,
abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) where {T}
abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T}
(T <: BigFloat) && return qr(similar(A, 0, 0))
return lu(similar(A, 0, 0))
end
Expand All @@ -61,7 +61,7 @@ for alg in (:SVDFactorization, :MKLLUFactorization, :DiagonalFactorization,
:AppleAccelerateLUFactorization, :QRFactorization, :LUFactorization)
@eval begin
function init_cacheval(::$(alg), ::Symmetric{<:Number, <:BandedMatrix}, b, u, Pl,
Pr, maxiters::Int, abstol, reltol, verbose::Bool,
Pr, maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
return nothing
end
Expand Down
16 changes: 8 additions & 8 deletions ext/LinearSolveCUDAExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using LinearSolve: LinearSolve, is_cusparse, defaultalg, cudss_loaded, DefaultLi
error_no_cudss_lu, init_cacheval, OperatorAssumptions,
CudaOffloadFactorization, CudaOffloadLUFactorization, CudaOffloadQRFactorization,
CUDAOffload32MixedLUFactorization,
SparspakFactorization, KLUFactorization, UMFPACKFactorization
SparspakFactorization, KLUFactorization, UMFPACKFactorization, LinearVerbosity
using LinearSolve.LinearAlgebra, LinearSolve.SciMLBase, LinearSolve.ArrayInterface
using SciMLBase: AbstractSciMLOperator

Expand Down Expand Up @@ -51,7 +51,7 @@ function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::CudaOffloadLUFact
end

function LinearSolve.init_cacheval(alg::CudaOffloadLUFactorization, A::AbstractArray, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
# Check if CUDA is functional before creating CUDA arrays
if !CUDA.functional()
Expand Down Expand Up @@ -79,7 +79,7 @@ function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::CudaOffloadQRFact
end

function LinearSolve.init_cacheval(alg::CudaOffloadQRFactorization, A, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
# Check if CUDA is functional before creating CUDA arrays
if !CUDA.functional()
Expand All @@ -103,26 +103,26 @@ function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::CudaOffloadFactor
end

function LinearSolve.init_cacheval(alg::CudaOffloadFactorization, A::AbstractArray, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
qr(CUDA.CuArray(A))
end

function LinearSolve.init_cacheval(
::SparspakFactorization, A::CUDA.CUSPARSE.CuSparseMatrixCSR, b, u,
Pl, Pr, maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions)
Pl, Pr, maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions)
nothing
end

function LinearSolve.init_cacheval(
::KLUFactorization, A::CUDA.CUSPARSE.CuSparseMatrixCSR, b, u,
Pl, Pr, maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions)
Pl, Pr, maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions)
nothing
end

function LinearSolve.init_cacheval(
::UMFPACKFactorization, A::CUDA.CUSPARSE.CuSparseMatrixCSR, b, u,
Pl, Pr, maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions)
Pl, Pr, maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions)
nothing
end

Expand Down Expand Up @@ -156,7 +156,7 @@ function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::CUDAOffload32Mixe
end

function LinearSolve.init_cacheval(alg::CUDAOffload32MixedLUFactorization, A, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
maxiters::Int, abstol, reltol, verbose::LinearVerbosity,
assumptions::OperatorAssumptions)
# Pre-allocate with Float32 arrays
m, n = size(A)
Expand Down
4 changes: 2 additions & 2 deletions ext/LinearSolveCUSOLVERRFExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ using SciMLBase: SciMLBase, LinearProblem, ReturnCode
function LinearSolve.init_cacheval(alg::LinearSolve.CUSOLVERRFFactorization,
A, b, u, Pl, Pr,
maxiters::Int, abstol, reltol,
verbose::Bool, assumptions::OperatorAssumptions)
verbose::LinearVerbosity, assumptions::OperatorAssumptions)
nothing
end

function LinearSolve.init_cacheval(alg::LinearSolve.CUSOLVERRFFactorization,
A::Union{CuSparseMatrixCSR{Float64, Int32}, SparseMatrixCSC{Float64, <:Integer}},
b, u, Pl, Pr,
maxiters::Int, abstol, reltol,
verbose::Bool, assumptions::OperatorAssumptions)
verbose::LinearVerbosity, assumptions::OperatorAssumptions)
# Create initial factorization with appropriate options
nrhs = b isa AbstractMatrix ? size(b, 2) : 1
symbolic = alg.symbolic
Expand Down
2 changes: 1 addition & 1 deletion ext/LinearSolveCliqueTreesExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ end

function LinearSolve.init_cacheval(
alg::CliqueTreesFactorization, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, abstol,
reltol, verbose::Bool, assumptions::OperatorAssumptions)
reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions)
symbfact = _symbolic(A, alg)
cholfact, cholwork = cholinit(A, symbfact)
linwork = lininit(1, cholfact)
Expand Down
4 changes: 2 additions & 2 deletions ext/LinearSolveFastAlmostBandedMatricesExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module LinearSolveFastAlmostBandedMatricesExt
using FastAlmostBandedMatrices, LinearAlgebra, LinearSolve
import LinearSolve: defaultalg,
do_factorization, init_cacheval, DefaultLinearSolver,
DefaultAlgorithmChoice
DefaultAlgorithmChoice, LinearVerbosity

function defaultalg(A::AlmostBandedMatrix, b, oa::OperatorAssumptions{Bool})
if oa.issq
Expand All @@ -21,7 +21,7 @@ for alg in (:SVDFactorization, :MKLLUFactorization, :DiagonalFactorization,
:AppleAccelerateLUFactorization, :CholeskyFactorization, :LUFactorization)
@eval begin
function init_cacheval(::$(alg), ::AlmostBandedMatrix, b, u, Pl, Pr, maxiters::Int,
abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions)
abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions)
return nothing
end
end
Expand Down
Loading
Loading