diff --git a/docs/src/advanced/developing.md b/docs/src/advanced/developing.md index 31b7a5d1f..ea70d32e1 100644 --- a/docs/src/advanced/developing.md +++ b/docs/src/advanced/developing.md @@ -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 diff --git a/ext/LinearSolveBandedMatricesExt.jl b/ext/LinearSolveBandedMatricesExt.jl index deb85e25a..a6ff8755c 100644 --- a/ext/LinearSolveBandedMatricesExt.jl +++ b/ext/LinearSolveBandedMatricesExt.jl @@ -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 @@ -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 diff --git a/ext/LinearSolveCUDAExt.jl b/ext/LinearSolveCUDAExt.jl index 94f6d7df0..13a677142 100644 --- a/ext/LinearSolveCUDAExt.jl +++ b/ext/LinearSolveCUDAExt.jl @@ -38,26 +38,26 @@ function SciMLBase.solve!(cache::LinearSolve.LinearCache, alg::CudaOffloadFactor end function LinearSolve.init_cacheval(alg::CudaOffloadFactorization, A, 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 diff --git a/ext/LinearSolveFastAlmostBandedMatricesExt.jl b/ext/LinearSolveFastAlmostBandedMatricesExt.jl index 1ceff10c5..99314d835 100644 --- a/ext/LinearSolveFastAlmostBandedMatricesExt.jl +++ b/ext/LinearSolveFastAlmostBandedMatricesExt.jl @@ -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 diff --git a/ext/LinearSolveFastLapackInterfaceExt.jl b/ext/LinearSolveFastLapackInterfaceExt.jl index 45b690037..945442e2c 100644 --- a/ext/LinearSolveFastLapackInterfaceExt.jl +++ b/ext/LinearSolveFastLapackInterfaceExt.jl @@ -9,7 +9,7 @@ struct WorkspaceAndFactors{W, F} end function LinearSolve.init_cacheval(::FastLUFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ws = LUWs(A) return WorkspaceAndFactors( @@ -36,7 +36,7 @@ end function LinearSolve.init_cacheval( alg::FastQRFactorization{NoPivot}, A::AbstractMatrix, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ws = QRWYWs(A; blocksize = alg.blocksize) return WorkspaceAndFactors(ws, @@ -44,7 +44,7 @@ function LinearSolve.init_cacheval( end function LinearSolve.init_cacheval( ::FastQRFactorization{ColumnNorm}, A::AbstractMatrix, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ws = QRpWs(A) return WorkspaceAndFactors(ws, @@ -52,10 +52,10 @@ function LinearSolve.init_cacheval( end function LinearSolve.init_cacheval(alg::FastQRFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) return init_cacheval(alg, convert(AbstractMatrix, A), b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) end diff --git a/ext/LinearSolveHYPREExt.jl b/ext/LinearSolveHYPREExt.jl index ad7d98333..1c6774f99 100644 --- a/ext/LinearSolveHYPREExt.jl +++ b/ext/LinearSolveHYPREExt.jl @@ -22,7 +22,7 @@ end function LinearSolve.init_cacheval(alg::HYPREAlgorithm, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) return HYPRECache(nothing, nothing, nothing, nothing, true, true, true) end @@ -64,7 +64,7 @@ function SciMLBase.init(prob::LinearProblem, alg::HYPREAlgorithm, eltype(prob.A)), # TODO: Implement length() for HYPREVector in HYPRE.jl? maxiters::Int = prob.b isa HYPREVector ? 1000 : length(prob.b), - verbose::Bool = false, + verbose::LinearVerbosity = false, Pl = LinearAlgebra.I, Pr = LinearAlgebra.I, assumptions = OperatorAssumptions(), diff --git a/ext/LinearSolveIterativeSolversExt.jl b/ext/LinearSolveIterativeSolversExt.jl index 198cc0a5e..4c860cb21 100644 --- a/ext/LinearSolveIterativeSolversExt.jl +++ b/ext/LinearSolveIterativeSolversExt.jl @@ -51,7 +51,7 @@ LinearSolve.default_alias_b(::IterativeSolversJL, ::Any, ::Any) = true function LinearSolve.init_cacheval(alg::IterativeSolversJL, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) restart = (alg.gmres_restart == 0) ? min(20, size(A, 1)) : alg.gmres_restart s = :idrs_s in keys(alg.kwargs) ? alg.kwargs.idrs_s : 4 # shadow space @@ -60,7 +60,8 @@ function LinearSolve.init_cacheval(alg::IterativeSolversJL, A, b, u, Pl, Pr, max iterable = if alg.generate_iterator === IterativeSolvers.cg_iterator! !LinearSolve._isidentity_struct(Pr) && - @warn "$(alg.generate_iterator) doesn't support right preconditioning" + @SciMLMessage("$(alg.generate_iterator) doesn't support right preconditioning", + verbose, :no_right_preconditioning, :performance) alg.generate_iterator(u, A, b, Pl; kwargs...) elseif alg.generate_iterator === IterativeSolvers.gmres_iterable! @@ -68,7 +69,8 @@ function LinearSolve.init_cacheval(alg::IterativeSolversJL, A, b, u, Pl, Pr, max kwargs...) elseif alg.generate_iterator === IterativeSolvers.idrs_iterable! !!LinearSolve._isidentity_struct(Pr) && - @warn "$(alg.generate_iterator) doesn't support right preconditioning" + @SciMLMessage("$(alg.generate_iterator) doesn't support right preconditioning", + verbose, :no_right_preconditioning, :performance) history = IterativeSolvers.ConvergenceHistory(partial = true) history[:abstol] = abstol history[:reltol] = reltol @@ -76,7 +78,8 @@ function LinearSolve.init_cacheval(alg::IterativeSolversJL, A, b, u, Pl, Pr, max alg.kwargs...) elseif alg.generate_iterator === IterativeSolvers.bicgstabl_iterator! !!LinearSolve._isidentity_struct(Pr) && - @warn "$(alg.generate_iterator) doesn't support right preconditioning" + @SciMLMessage("$(alg.generate_iterator) doesn't support right preconditioning", + verbose, :no_right_preconditioning, :performance) alg.generate_iterator(u, A, b, alg.args...; Pl = Pl, abstol = abstol, reltol = reltol, max_mv_products = maxiters * 2, @@ -107,14 +110,13 @@ function SciMLBase.solve!(cache::LinearCache, alg::IterativeSolversJL; kwargs... end purge_history!(cache.cacheval, cache.u, cache.b) - cache.verbose && println("Using IterativeSolvers.$(alg.generate_iterator)") + @SciMLMessage("Using IterativeSolvers.$(alg.generate_iterator)", cache.verbose, :using_IterativeSolvers, :numerical) i = 0 for iter in enumerate(cache.cacheval) i += 1 - cache.verbose && println("Iter: $(iter[1]), residual: $(iter[2])") + @SciMLMessage("Iter: $(iter[1]), residual: $(iter[2])", cache.verbose, :IterativeSolvers_iterations) # TODO inject callbacks KSP into solve! cb!(cache.cacheval) end - cache.verbose && println() resid = cache.cacheval isa IterativeSolvers.IDRSIterable ? cache.cacheval.R : cache.cacheval.residual diff --git a/ext/LinearSolveKrylovKitExt.jl b/ext/LinearSolveKrylovKitExt.jl index 1aa1e5d52..dded0338b 100644 --- a/ext/LinearSolveKrylovKitExt.jl +++ b/ext/LinearSolveKrylovKitExt.jl @@ -26,6 +26,7 @@ function SciMLBase.solve!(cache::LinearCache, alg::KrylovKitJL; kwargs...) rtol = float(cache.reltol) maxiter = cache.maxiters verbosity = cache.verbose ? 1 : 0 + verbosity = verbosity_to_KrylovKit(cache.verbose.numerical.Krylovkit_verbosity) krylovdim = (alg.gmres_restart == 0) ? min(20, size(cache.A, 1)) : alg.gmres_restart kwargs = (atol = atol, rtol = rtol, maxiter = maxiter, verbosity = verbosity, @@ -41,4 +42,13 @@ function SciMLBase.solve!(cache::LinearCache, alg::KrylovKitJL; kwargs...) iters = iters) end +function verbosity_to_KrylovKit(verb::SciMLBase.Verbosity.Type) + SciML.@match verb begin + Verbosity.None() => 0 + Verbosity.Warn() => 1 + Verbosity.Error() => 2 + Verbosity.Info() => 3 + Level(x) => x + _ => error("Not a valid verbosity level for KrylovKit.") + end end diff --git a/ext/LinearSolveMetalExt.jl b/ext/LinearSolveMetalExt.jl index 036ffa9cd..507ae0142 100644 --- a/ext/LinearSolveMetalExt.jl +++ b/ext/LinearSolveMetalExt.jl @@ -9,7 +9,7 @@ default_alias_A(::MetalLUFactorization, ::Any, ::Any) = false default_alias_b(::MetalLUFactorization, ::Any, ::Any) = false function LinearSolve.init_cacheval(alg::MetalLUFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(convert(AbstractMatrix, A)) end diff --git a/ext/LinearSolvePardisoExt.jl b/ext/LinearSolvePardisoExt.jl index 7f27bf875..8f21625fe 100644 --- a/ext/LinearSolvePardisoExt.jl +++ b/ext/LinearSolvePardisoExt.jl @@ -21,7 +21,7 @@ function LinearSolve.init_cacheval(alg::PardisoJL, maxiters::Int, abstol, reltol, - verbose::Bool, + verbose::LinearVerbosity, assumptions::LinearSolve.OperatorAssumptions) @unpack nprocs, solver_type, matrix_type, cache_analysis, iparm, dparm, vendor = alg A = convert(AbstractMatrix, A) diff --git a/ext/LinearSolveSparseArraysExt.jl b/ext/LinearSolveSparseArraysExt.jl index d04e8117f..a0059cbca 100644 --- a/ext/LinearSolveSparseArraysExt.jl +++ b/ext/LinearSolveSparseArraysExt.jl @@ -3,7 +3,7 @@ module LinearSolveSparseArraysExt using LinearSolve, LinearAlgebra using SparseArrays using SparseArrays: AbstractSparseMatrixCSC, nonzeros, rowvals, getcolptr -using LinearSolve: BLASELTYPES, pattern_changed +using LinearSolve: BLASELTYPES, pattern_changed, LinearVerbosity # Can't `using KLU` because cannot have a dependency in there without # requiring the user does `using KLU` @@ -23,7 +23,7 @@ end function LinearSolve.init_cacheval(alg::RFLUFactorization, A::Union{AbstractSparseArray, LinearSolve.SciMLOperators.AbstractSciMLOperator}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing, nothing end @@ -54,7 +54,7 @@ end function LinearSolve.init_cacheval(alg::GenericFactorization, A::Union{Hermitian{T, <:SparseMatrixCSC}, Symmetric{T, <:SparseMatrixCSC}}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T} newA = copy(convert(AbstractMatrix, A)) LinearSolve.do_factorization(alg, newA, b, u) @@ -67,7 +67,7 @@ function LinearSolve.init_cacheval( alg::LUFactorization, A::AbstractSparseArray{<:Number, <:Integer}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -75,7 +75,7 @@ function LinearSolve.init_cacheval( alg::GenericLUFactorization, A::AbstractSparseArray{<:Number, <:Integer}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -83,7 +83,7 @@ function LinearSolve.init_cacheval( alg::UMFPACKFactorization, A::AbstractArray, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -91,7 +91,7 @@ function LinearSolve.init_cacheval( alg::LUFactorization, A::AbstractSparseArray{Float64, Int64}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_UMFPACK end @@ -99,7 +99,7 @@ function LinearSolve.init_cacheval( alg::LUFactorization, A::AbstractSparseArray{T, Int64}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} + verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} SparseArrays.UMFPACK.UmfpackLU(SparseMatrixCSC{T, Int64}(zero(Int64), zero(Int64), [Int64(1)], Int64[], T[])) end @@ -107,7 +107,7 @@ function LinearSolve.init_cacheval( alg::LUFactorization, A::AbstractSparseArray{T, Int32}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} + verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} SparseArrays.UMFPACK.UmfpackLU(SparseMatrixCSC{T, Int32}(zero(Int32), zero(Int32), [Int32(1)], Int32[], T[])) end @@ -115,7 +115,7 @@ function LinearSolve.init_cacheval( alg::UMFPACKFactorization, A::AbstractSparseArray{Float64, Int}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_UMFPACK end @@ -124,7 +124,7 @@ function LinearSolve.init_cacheval( alg::UMFPACKFactorization, A::AbstractSparseArray{T, Int64}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} + verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} SparseArrays.UMFPACK.UmfpackLU(SparseMatrixCSC{T, Int64}(zero(Int64), zero(Int64), [Int64(1)], Int64[], T[])) end @@ -132,7 +132,7 @@ function LinearSolve.init_cacheval( alg::UMFPACKFactorization, A::AbstractSparseArray{T, Int32}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} + verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T<:BLASELTYPES} SparseArrays.UMFPACK.UmfpackLU(SparseMatrixCSC{T, Int32}(zero(Int32), zero(Int32), [Int32(1)], Int32[], T[])) end @@ -179,7 +179,7 @@ function LinearSolve.init_cacheval( alg::KLUFactorization, A::AbstractArray, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -187,7 +187,7 @@ function LinearSolve.init_cacheval( alg::KLUFactorization, A::AbstractSparseArray{Float64, Int64}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_KLU end @@ -195,7 +195,7 @@ function LinearSolve.init_cacheval( alg::KLUFactorization, A::AbstractSparseArray{Float64, Int32}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) KLU.KLUFactorization(SparseMatrixCSC{Float64, Int32}(0, 0, [Int32(1)], Int32[], Float64[])) end @@ -239,7 +239,7 @@ function LinearSolve.init_cacheval(alg::CHOLMODFactorization, A::Union{SparseMatrixCSC{T, Int}, Symmetric{T, SparseMatrixCSC{T, Int}}}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) where {T <: + verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T <: Float64} PREALLOCATED_CHOLMOD end @@ -248,7 +248,7 @@ function LinearSolve.init_cacheval(alg::CHOLMODFactorization, A::Union{SparseMatrixCSC{T, Int}, Symmetric{T, SparseMatrixCSC{T, Int}}}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) where {T <: + verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T <: BLASELTYPES} cholesky(sparse(reshape([one(T)],1,1))) end @@ -257,14 +257,14 @@ function LinearSolve.init_cacheval(alg::CHOLMODFactorization, A::AbstractArray, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end function LinearSolve.init_cacheval(alg::NormalCholeskyFactorization, A::Union{AbstractSparseArray{T}, LinearSolve.GPUArraysCore.AnyGPUArray, Symmetric{T, <:AbstractSparseArray{T}}}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T <: BLASELTYPES} LinearSolve.ArrayInterface.cholesky_instance(convert(AbstractMatrix, A)) end @@ -324,25 +324,25 @@ function LinearSolve.init_cacheval( alg::QRFactorization, A::AbstractSparseArray{<:Number, <:Integer}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end function LinearSolve.init_cacheval(alg::QRFactorization, A::SparseMatrixCSC{Float64, Int}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) LinearSolve.ArrayInterface.qr_instance(convert(AbstractMatrix, A), alg.pivot) end function LinearSolve.init_cacheval(alg::QRFactorization, A::SparseMatrixCSC{Float64, Int32}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) LinearSolve.ArrayInterface.qr_instance(convert(AbstractMatrix, A), alg.pivot) end function LinearSolve.init_cacheval( alg::QRFactorization, A::Symmetric{<:Number, <:SparseMatrixCSC}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) return nothing end diff --git a/ext/LinearSolveSparspakExt.jl b/ext/LinearSolveSparspakExt.jl index 617e3a54d..e7f2ab27f 100644 --- a/ext/LinearSolveSparspakExt.jl +++ b/ext/LinearSolveSparspakExt.jl @@ -12,14 +12,14 @@ function LinearSolve.init_cacheval( ::SparspakFactorization, A::SparseMatrixCSC{Float64, Int}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_SPARSEPAK end function LinearSolve.init_cacheval( ::SparspakFactorization, A::AbstractSparseMatrixCSC{Tv, Ti}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) where {Tv, Ti} + verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {Tv, Ti} if size(A,1) == size(A,2) A = convert(AbstractMatrix, A) diff --git a/src/LinearSolve.jl b/src/LinearSolve.jl index c7680903b..d54e596c8 100644 --- a/src/LinearSolve.jl +++ b/src/LinearSolve.jl @@ -9,7 +9,7 @@ using ArrayInterface using Base: cache_dependencies, Bool using LinearAlgebra using LazyArrays: @~, BroadcastArray -using SciMLBase: AbstractLinearAlgorithm, LinearAliasSpecifier +using SciMLBase: AbstractLinearAlgorithm, LinearAliasSpecifier, LinearVerbosity, Verbosity, @SciMLMessage, LinearVerbosity using SciMLOperators using SciMLOperators: AbstractSciMLOperator, IdentityOperator using Setfield diff --git a/src/appleaccelerate.jl b/src/appleaccelerate.jl index 917ad9c4a..cf564c58e 100644 --- a/src/appleaccelerate.jl +++ b/src/appleaccelerate.jl @@ -220,14 +220,14 @@ const PREALLOCATED_APPLE_LU = begin end function LinearSolve.init_cacheval(alg::AppleAccelerateLUFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_APPLE_LU end function LinearSolve.init_cacheval(alg::AppleAccelerateLUFactorization, 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) luinst = ArrayInterface.lu_instance(A) diff --git a/src/common.jl b/src/common.jl index 1be103f16..da406fc33 100644 --- a/src/common.jl +++ b/src/common.jl @@ -79,7 +79,7 @@ mutable struct LinearCache{TA, Tb, Tu, Tp, Talg, Tc, Tl, Tr, Ttol, issq, S} abstol::Ttol reltol::Ttol maxiters::Int - verbose::Bool + verbose::LinearVerbosity assumptions::OperatorAssumptions{issq} sensealg::S end @@ -143,7 +143,7 @@ function SciMLBase.init(prob::LinearProblem, alg::SciMLLinearSolveAlgorithm, abstol = default_tol(real(eltype(prob.b))), reltol = default_tol(real(eltype(prob.b))), maxiters::Int = length(prob.b), - verbose::Bool = false, + verbose::LinearVerbosity = LinearVerbosity(), Pl = nothing, Pr = nothing, assumptions = OperatorAssumptions(issquare(prob.A)), diff --git a/src/default.jl b/src/default.jl index 5051d000e..ed8181077 100644 --- a/src/default.jl +++ b/src/default.jl @@ -301,7 +301,7 @@ function SciMLBase.solve!(cache::LinearCache, alg::Nothing, end function init_cacheval(alg::Nothing, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assump::OperatorAssumptions) + verbose::LinearVerbosity, assump::OperatorAssumptions) init_cacheval(defaultalg(A, b, assump), A, b, u, Pl, Pr, maxiters, abstol, reltol, verbose, assump) @@ -312,7 +312,7 @@ cache.cacheval = NamedTuple(LUFactorization = cache of LUFactorization, ...) """ @generated function init_cacheval(alg::DefaultLinearSolver, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assump::OperatorAssumptions) + verbose::LinearVerbosity, assump::OperatorAssumptions) caches = map(first.(EnumX.symbol_map(DefaultAlgorithmChoice.T))) do alg if alg === :KrylovJL_GMRES || alg === :KrylovJL_CRAIGMR || alg === :KrylovJL_LSMR quote @@ -364,7 +364,9 @@ end newex = quote sol = SciMLBase.solve!(cache, $(algchoice_to_alg(alg)), args...; kwargs...) if sol.retcode === ReturnCode.Failure && alg.safetyfallback - ## TODO: Add verbosity logging here about using the fallback + @SciMLMessage("LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.", + cache.verbose, :default_lu_fallback, :error_control) + sol = SciMLBase.solve!(cache, QRFactorization(ColumnNorm()), args...; kwargs...) SciMLBase.build_linear_solution(alg, sol.u, sol.resid, sol.cache; retcode = sol.retcode, @@ -383,7 +385,9 @@ end sol = SciMLBase.solve!(cache, $(algchoice_to_alg(alg)), args...; kwargs...) if sol.retcode === ReturnCode.Failure && alg.safetyfallback - ## TODO: Add verbosity logging here about using the fallback + @SciMLMessage("LU factorization failed, falling back to QR factorization. `A` is potentially rank-deficient.", + cache.verbose, :default_lu_fallback, :error_control) + sol = SciMLBase.solve!(cache, QRFactorization(ColumnNorm()), args...; kwargs...) SciMLBase.build_linear_solution(alg, sol.u, sol.resid, sol.cache; retcode = sol.retcode, diff --git a/src/factorization.jl b/src/factorization.jl index 8d03a5d2c..8f787aa00 100644 --- a/src/factorization.jl +++ b/src/factorization.jl @@ -49,14 +49,14 @@ end # RF Bad fallback: will fail if `A` is just a stand-in # This should instead just create the factorization type. function init_cacheval(alg::AbstractFactorization, A, b, u, Pl, Pr, maxiters::Int, abstol, - reltol, verbose::Bool, assumptions::OperatorAssumptions) + reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) do_factorization(alg, convert(AbstractMatrix, A), b, u) end ## RFLU Factorization function LinearSolve.init_cacheval(alg::RFLUFactorization, A, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ipiv = Vector{LinearAlgebra.BlasInt}(undef, min(size(A)...)) ArrayInterface.lu_instance(convert(AbstractMatrix, A)), ipiv end @@ -64,14 +64,14 @@ end function LinearSolve.init_cacheval( alg::RFLUFactorization, A::Matrix{Float64}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_LU, PREALLOCATED_IPIV end function LinearSolve.init_cacheval(alg::RFLUFactorization, A::Union{Diagonal, SymTridiagonal, Tridiagonal}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing, nothing end @@ -169,7 +169,7 @@ end function init_cacheval( alg::GenericLUFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ipiv = Vector{LinearAlgebra.BlasInt}(undef, min(size(A)...)) ArrayInterface.lu_instance(convert(AbstractMatrix, A)), ipiv @@ -177,7 +177,7 @@ end function init_cacheval( alg::GenericLUFactorization, A::Matrix{Float64}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_LU, PREALLOCATED_IPIV end @@ -208,21 +208,21 @@ end function init_cacheval( alg::LUFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(convert(AbstractMatrix, A)) end function init_cacheval(alg::LUFactorization, A::Union{<:Adjoint, <:Transpose}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) error_no_cudss_lu(A) return lu(A; check = false) end function init_cacheval(alg::GenericLUFactorization, A::Union{<:Adjoint, <:Transpose}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) error_no_cudss_lu(A) A isa GPUArraysCore.AnyGPUArray && return nothing ipiv = Vector{LinearAlgebra.BlasInt}(undef, 0) @@ -233,21 +233,21 @@ const PREALLOCATED_LU = ArrayInterface.lu_instance(rand(1, 1)) function init_cacheval(alg::LUFactorization, A::Matrix{Float64}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_LU end function init_cacheval(alg::LUFactorization, A::AbstractSciMLOperator, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end function init_cacheval(alg::GenericLUFactorization, A::AbstractSciMLOperator, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -297,13 +297,13 @@ function do_factorization(alg::QRFactorization, A, b, u) end function init_cacheval(alg::QRFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.qr_instance(convert(AbstractMatrix, A), alg.pivot) end function init_cacheval(alg::QRFactorization, A::Symmetric{<:Number, <:Array}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) return qr(convert(AbstractMatrix, A), alg.pivot) end @@ -311,13 +311,13 @@ end const PREALLOCATED_QR_ColumnNorm = ArrayInterface.qr_instance(rand(1, 1), ColumnNorm()) function init_cacheval(alg::QRFactorization{ColumnNorm}, A::Matrix{Float64}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) return PREALLOCATED_QR_ColumnNorm end function init_cacheval( alg::QRFactorization, A::Union{<:Adjoint, <:Transpose}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) A isa GPUArraysCore.AnyGPUArray && return qr(A) return qr(A, alg.pivot) end @@ -325,12 +325,12 @@ end const PREALLOCATED_QR_NoPivot = ArrayInterface.qr_instance(rand(1, 1)) function init_cacheval(alg::QRFactorization{NoPivot}, A::Matrix{Float64}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) return PREALLOCATED_QR_NoPivot end function init_cacheval(alg::QRFactorization, A::AbstractSciMLOperator, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -376,33 +376,33 @@ function do_factorization(alg::CholeskyFactorization, A, b, u) end function init_cacheval(alg::CholeskyFactorization, A::SMatrix{S1, S2}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {S1, S2} cholesky(A) end function init_cacheval(alg::CholeskyFactorization, A::GPUArraysCore.AnyGPUArray, b, u, Pl, - Pr, maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + Pr, maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) cholesky(A; check = false) end function init_cacheval( alg::CholeskyFactorization, A::AbstractArray{<:BLASELTYPES}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.cholesky_instance(convert(AbstractMatrix, A), alg.pivot) end const PREALLOCATED_CHOLESKY = ArrayInterface.cholesky_instance(rand(1, 1), NoPivot()) function init_cacheval(alg::CholeskyFactorization, A::Matrix{Float64}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_CHOLESKY end function init_cacheval(alg::CholeskyFactorization, A::Union{Diagonal, AbstractSciMLOperator, AbstractArray}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -430,12 +430,12 @@ end function init_cacheval(alg::LDLtFactorization, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end function init_cacheval(alg::LDLtFactorization, A::SymTridiagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.ldlt_instance(convert(AbstractMatrix, A)) end @@ -469,7 +469,7 @@ function do_factorization(alg::SVDFactorization, A, b, u) end function init_cacheval(alg::SVDFactorization, A::Union{Matrix, SMatrix}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.svd_instance(convert(AbstractMatrix, A)) end @@ -477,13 +477,13 @@ end const PREALLOCATED_SVD = ArrayInterface.svd_instance(rand(1, 1)) function init_cacheval(alg::SVDFactorization, A::Matrix{Float64}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_SVD end function init_cacheval(alg::SVDFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -512,7 +512,7 @@ end function init_cacheval(alg::BunchKaufmanFactorization, A::Symmetric{<:Number, <:Matrix}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.bunchkaufman_instance(convert(AbstractMatrix, A)) end @@ -522,13 +522,13 @@ const PREALLOCATED_BUNCHKAUFMAN = ArrayInterface.bunchkaufman_instance(Symmetric function init_cacheval(alg::BunchKaufmanFactorization, A::Symmetric{Float64, Matrix{Float64}}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_BUNCHKAUFMAN end function init_cacheval(alg::BunchKaufmanFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -569,58 +569,58 @@ end function init_cacheval( alg::GenericFactorization{typeof(lu)}, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(lu!)}, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(lu)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(lu!)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(lu)}, A::Diagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval(alg::GenericFactorization{typeof(lu)}, A::Tridiagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(lu!)}, A::Diagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval( alg::GenericFactorization{typeof(lu!)}, A::Tridiagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(lu!)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end function init_cacheval( alg::GenericFactorization{typeof(lu)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end @@ -628,24 +628,24 @@ end function init_cacheval( alg::GenericFactorization{typeof(qr)}, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.qr_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(qr!)}, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.qr_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(qr)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end function init_cacheval( alg::GenericFactorization{typeof(qr!)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end @@ -653,33 +653,33 @@ end function init_cacheval(alg::GenericFactorization{typeof(qr)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.qr_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(qr!)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.qr_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(qr)}, A::Diagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval(alg::GenericFactorization{typeof(qr)}, A::Tridiagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.qr_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(qr!)}, A::Diagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval( alg::GenericFactorization{typeof(qr!)}, A::Tridiagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.qr_instance(A) end @@ -687,87 +687,87 @@ end function init_cacheval( alg::GenericFactorization{typeof(svd)}, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.svd_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(svd!)}, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.svd_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(svd)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.svd_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(svd!)}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.svd_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(svd)}, A::Diagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval( alg::GenericFactorization{typeof(svd)}, A::Tridiagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.svd_instance(A) end function init_cacheval(alg::GenericFactorization{typeof(svd!)}, A::Diagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval(alg::GenericFactorization{typeof(svd!)}, A::Tridiagonal, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.svd_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(svd!)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end function init_cacheval( alg::GenericFactorization{typeof(svd)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end function init_cacheval(alg::GenericFactorization, A::Diagonal, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval(alg::GenericFactorization, A::Tridiagonal, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval(alg::GenericFactorization, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end function init_cacheval(alg::GenericFactorization, A, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) init_cacheval(alg, convert(AbstractMatrix, A), b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) end function init_cacheval(alg::GenericFactorization, A::AbstractMatrix, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) do_factorization(alg, A, b, u) end @@ -775,7 +775,7 @@ function init_cacheval( alg::Union{GenericFactorization{typeof(bunchkaufman!)}, GenericFactorization{typeof(bunchkaufman)}}, A::Union{Hermitian, Symmetric}, b, u, Pl, Pr, maxiters::Int, abstol, - reltol, verbose::Bool, assumptions::OperatorAssumptions) + reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) BunchKaufman(A.data, Array(1:size(A, 1)), A.uplo, true, false, 0) end @@ -784,7 +784,7 @@ function init_cacheval( GenericFactorization{typeof(bunchkaufman)}}, A::StridedMatrix{<:LinearAlgebra.BlasFloat}, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) if eltype(A) <: Complex return bunchkaufman!(Hermitian(A)) else @@ -798,49 +798,49 @@ end # Cholesky needs the posdef matrix, for GenericFactorization assume structure is needed function init_cacheval( alg::GenericFactorization{typeof(cholesky)}, A::AbstractMatrix, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) newA = copy(convert(AbstractMatrix, A)) do_factorization(alg, newA, b, u) end function init_cacheval( alg::GenericFactorization{typeof(cholesky!)}, A::AbstractMatrix, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) newA = copy(convert(AbstractMatrix, A)) do_factorization(alg, newA, b, u) end function init_cacheval(alg::GenericFactorization{typeof(cholesky!)}, A::Diagonal, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval( alg::GenericFactorization{typeof(cholesky!)}, A::Tridiagonal, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(cholesky!)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end function init_cacheval(alg::GenericFactorization{typeof(cholesky)}, A::Diagonal, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) Diagonal(inv.(A.diag)) end function init_cacheval( alg::GenericFactorization{typeof(cholesky)}, A::Tridiagonal, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.lu_instance(A) end function init_cacheval( alg::GenericFactorization{typeof(cholesky)}, A::SymTridiagonal{T, V}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) where {T, V} LinearAlgebra.LDLt{T, SymTridiagonal{T, V}}(A) end @@ -870,7 +870,7 @@ end function init_cacheval(alg::UMFPACKFactorization, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -894,7 +894,7 @@ end function init_cacheval(alg::KLUFactorization, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -922,7 +922,7 @@ end function init_cacheval(alg::CHOLMODFactorization, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -972,13 +972,13 @@ default_alias_b(::NormalCholeskyFactorization, ::Any, ::Any) = true const PREALLOCATED_NORMALCHOLESKY = ArrayInterface.cholesky_instance(rand(1, 1), NoPivot()) function init_cacheval(alg::NormalCholeskyFactorization, A::SMatrix, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) return cholesky(Symmetric((A)' * A)) end function init_cacheval(alg::NormalCholeskyFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) A_ = convert(AbstractMatrix, A) return ArrayInterface.cholesky_instance( @@ -989,13 +989,13 @@ const PREALLOCATED_NORMALCHOLESKY_SYMMETRIC = ArrayInterface.cholesky_instance( Symmetric(rand(1, 1)), NoPivot()) function init_cacheval(alg::NormalCholeskyFactorization, A::Matrix{Float64}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) return PREALLOCATED_NORMALCHOLESKY_SYMMETRIC end function init_cacheval(alg::NormalCholeskyFactorization, A::Union{Diagonal, AbstractSciMLOperator}, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -1049,7 +1049,7 @@ default_alias_A(::NormalBunchKaufmanFactorization, ::Any, ::Any) = true default_alias_b(::NormalBunchKaufmanFactorization, ::Any, ::Any) = true function init_cacheval(alg::NormalBunchKaufmanFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) ArrayInterface.bunchkaufman_instance(convert(AbstractMatrix, A)) end @@ -1077,7 +1077,7 @@ A special implementation only for solving `Diagonal` matrices fast. struct DiagonalFactorization <: AbstractDenseFactorization end function init_cacheval(alg::DiagonalFactorization, A, b, u, Pl, Pr, maxiters::Int, - abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end @@ -1128,22 +1128,22 @@ end function init_cacheval(alg::SparspakFactorization, A::Union{AbstractMatrix, Nothing, AbstractSciMLOperator}, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions) + verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end function init_cacheval(::SparspakFactorization, ::StaticArray, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions) + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) nothing end for alg in vcat(InteractiveUtils.subtypes(AbstractDenseFactorization), InteractiveUtils.subtypes(AbstractSparseFactorization)) @eval function init_cacheval(alg::$alg, A::MatrixOperator, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) init_cacheval(alg, A.A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) end end diff --git a/src/iterative_wrappers.jl b/src/iterative_wrappers.jl index 6eb45d55f..939a30ece 100644 --- a/src/iterative_wrappers.jl +++ b/src/iterative_wrappers.jl @@ -185,7 +185,7 @@ end # zeroinit allows for init_cacheval to start by initing with A (0,0) function init_cacheval(alg::KrylovJL, A, b, u, Pl, Pr, maxiters::Int, abstol, reltol, - verbose::Bool, assumptions::OperatorAssumptions; zeroinit = true) + verbose::LinearVerbosity, assumptions::OperatorAssumptions; zeroinit = true) KS = get_KrylovJL_solver(alg.KrylovAlg) if zeroinit @@ -240,7 +240,7 @@ end # Krylov.jl tries to init with `ArrayPartition(undef, ...)`. Avoid hitting that! function init_cacheval( alg::LinearSolve.KrylovJL, A, b::RecursiveArrayTools.ArrayPartition, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, ::LinearSolve.OperatorAssumptions) + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, ::LinearSolve.OperatorAssumptions) return nothing end @@ -268,7 +268,7 @@ function SciMLBase.solve!(cache::LinearCache, alg::KrylovJL; kwargs...) atol = float(cache.abstol) rtol = float(cache.reltol) itmax = cache.maxiters - verbose = cache.verbose ? 1 : 0 + verbose = cache.verbose cacheval = if cache.alg isa DefaultLinearSolver if alg.KrylovAlg === Krylov.gmres! @@ -284,13 +284,20 @@ function SciMLBase.solve!(cache::LinearCache, alg::KrylovJL; kwargs...) cache.cacheval end + krylovJL_verbose = SciMLBase.@match verbose.numerical.KrylovJL_verbosity begin + SciMLBase.Verbosity.None() => 0 + ::SciMLBase.Verbosity.Type => 1 + _ => error("Invalid verbosity.") + end + args = (cacheval, cache.A, cache.b) - kwargs = (atol = atol, rtol, itmax, verbose, + kwargs = (atol = atol, rtol, itmax, verbose = krylovJL_verbose, ldiv = true, history = true, alg.kwargs...) if cache.cacheval isa Krylov.CgWorkspace N !== I && - @warn "$(alg.KrylovAlg) doesn't support right preconditioning." + @SciMLMessage("$(alg.KrylovAlg) doesn't support right preconditioning.", + verbose, :no_right_preconditioning, :performance) Krylov.krylov_solve!(args...; M, kwargs...) elseif cache.cacheval isa Krylov.GmresWorkspace Krylov.krylov_solve!(args...; M, N, restart = alg.gmres_restart > 0, kwargs...) @@ -298,7 +305,8 @@ function SciMLBase.solve!(cache::LinearCache, alg::KrylovJL; kwargs...) Krylov.krylov_solve!(args...; M, N, kwargs...) elseif cache.cacheval isa Krylov.MinresWorkspace N !== I && - @warn "$(alg.KrylovAlg) doesn't support right preconditioning." + @SciMLMessage("$(alg.KrylovAlg) doesn't support right preconditioning.", + verbose, :no_right_preconditioning, :performance) Krylov.krylov_solve!(args...; M, kwargs...) else Krylov.krylov_solve!(args...; kwargs...) @@ -331,3 +339,5 @@ function SciMLBase.solve!(cache::LinearCache, alg::KrylovJL; kwargs...) return SciMLBase.build_linear_solution(alg, cache.u, Ref(resid), cache; iters = stats.niter, retcode, stats) end + + diff --git a/src/mkl.jl b/src/mkl.jl index a00882e1d..c4d5ae78c 100644 --- a/src/mkl.jl +++ b/src/mkl.jl @@ -197,14 +197,14 @@ const PREALLOCATED_MKL_LU = begin end function LinearSolve.init_cacheval(alg::MKLLUFactorization, A, b, u, Pl, Pr, - maxiters::Int, abstol, reltol, verbose::Bool, + maxiters::Int, abstol, reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) PREALLOCATED_MKL_LU end function LinearSolve.init_cacheval(alg::MKLLUFactorization, 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}() diff --git a/src/simplelu.jl b/src/simplelu.jl index 9c1ad0bf7..910211b2c 100644 --- a/src/simplelu.jl +++ b/src/simplelu.jl @@ -143,6 +143,6 @@ function SciMLBase.solve!(cache::LinearCache, alg::SimpleLUFactorization; kwargs end function init_cacheval(alg::SimpleLUFactorization, A, b, u, Pl, Pr, maxiters::Int, abstol, - reltol, verbose::Bool, assumptions::OperatorAssumptions) + reltol, verbose::LinearVerbosity, assumptions::OperatorAssumptions) LUSolver(convert(AbstractMatrix, A)) end