Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ ChainRulesCore = "1.22"
ConcreteStructs = "0.2.3"
DocStringExtensions = "0.9.3"
EnumX = "1.0.4"
ExplicitImports = "1"
EnzymeCore = "0.8.1"
FastAlmostBandedMatrices = "0.1"
FastLapackInterface = "2"
Expand Down Expand Up @@ -122,6 +123,7 @@ julia = "1.10"
[extras]
AllocCheck = "9b6a8646-10ed-4001-bbdc-1d2f46dfbb1a"
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0"
FastAlmostBandedMatrices = "9d29842c-ecb8-4973-b1e9-a27b1157504e"
Expand Down Expand Up @@ -150,4 +152,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"

[targets]
test = ["Aqua", "Test", "IterativeSolvers", "InteractiveUtils", "KrylovKit", "KrylovPreconditioners", "Pkg", "Random", "SafeTestsets", "MultiFloats", "ForwardDiff", "HYPRE", "MPI", "BlockDiagonals", "FiniteDiff", "BandedMatrices", "FastAlmostBandedMatrices", "StaticArrays", "AllocCheck", "StableRNGs", "Zygote", "RecursiveFactorization", "Sparspak", "FastLapackInterface", "SparseArrays"]
test = ["Aqua", "Test", "IterativeSolvers", "InteractiveUtils", "KrylovKit", "KrylovPreconditioners", "Pkg", "Random", "SafeTestsets", "MultiFloats", "ForwardDiff", "HYPRE", "MPI", "BlockDiagonals", "FiniteDiff", "BandedMatrices", "FastAlmostBandedMatrices", "StaticArrays", "AllocCheck", "StableRNGs", "Zygote", "RecursiveFactorization", "Sparspak", "FastLapackInterface", "SparseArrays", "ExplicitImports"]
4 changes: 3 additions & 1 deletion ext/LinearSolveCUDAExt.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module LinearSolveCUDAExt

using CUDA
using LinearSolve
using LinearSolve: LinearSolve, is_cusparse, defaultalg, cudss_loaded, DefaultLinearSolver,
DefaultAlgorithmChoice, ALREADY_WARNED_CUDSS, LinearCache, needs_concrete_A,
Comment on lines +4 to +5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
using LinearSolve: LinearSolve, is_cusparse, defaultalg, cudss_loaded, DefaultLinearSolver,
DefaultAlgorithmChoice, ALREADY_WARNED_CUDSS, LinearCache, needs_concrete_A,
using LinearSolve: LinearSolve, is_cusparse, defaultalg, cudss_loaded, DefaultLinearSolver,
DefaultAlgorithmChoice, ALREADY_WARNED_CUDSS, LinearCache,
needs_concrete_A,

error_no_cudss_lu, CUDSS_LOADED, init_cacheval
using LinearSolve.LinearAlgebra, LinearSolve.SciMLBase, LinearSolve.ArrayInterface
using SciMLBase: AbstractSciMLOperator

Expand Down
2 changes: 1 addition & 1 deletion ext/LinearSolveCUDSSExt.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module LinearSolveCUDSSExt

using LinearSolve
using LinearSolve: LinearSolve, cudss_loaded
using CUDSS

LinearSolve.cudss_loaded(A::CUDSS.CUDA.CUSPARSE.CuSparseMatrixCSR) = true
Expand Down
4 changes: 3 additions & 1 deletion ext/LinearSolveEnzymeExt.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module LinearSolveEnzymeExt

using LinearSolve
using LinearSolve: LinearSolve, SciMLLinearSolveAlgorithm, init, solve!, LinearProblem,
LinearCache, AbstractKrylovSubspaceMethod, DefaultLinearSolver,
Comment on lines +3 to +4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
using LinearSolve: LinearSolve, SciMLLinearSolveAlgorithm, init, solve!, LinearProblem,
LinearCache, AbstractKrylovSubspaceMethod, DefaultLinearSolver,
using LinearSolve: LinearSolve, SciMLLinearSolveAlgorithm, init, solve!, LinearProblem,
LinearCache, AbstractKrylovSubspaceMethod, DefaultLinearSolver,

defaultalg_adjoint_eval
using LinearSolve.LinearAlgebra
using EnzymeCore
using EnzymeCore: EnzymeRules
Expand Down
3 changes: 2 additions & 1 deletion ext/LinearSolveRecursiveFactorizationExt.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module LinearSolveRecursiveFactorizationExt

using LinearSolve
using LinearSolve: LinearSolve, userecursivefactorization, LinearCache, @get_cacheval, RFLUFactorization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
using LinearSolve: LinearSolve, userecursivefactorization, LinearCache, @get_cacheval, RFLUFactorization
using LinearSolve: LinearSolve, userecursivefactorization, LinearCache, @get_cacheval,
RFLUFactorization

using LinearSolve.LinearAlgebra, LinearSolve.ArrayInterface, RecursiveFactorization
using SciMLBase: SciMLBase, ReturnCode

LinearSolve.userecursivefactorization(A::Union{Nothing, AbstractMatrix}) = true

Expand Down
40 changes: 21 additions & 19 deletions ext/LinearSolveSparseArraysExt.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
module LinearSolveSparseArraysExt

using LinearSolve, LinearAlgebra
using SparseArrays
using SparseArrays: AbstractSparseMatrixCSC, nonzeros, rowvals, getcolptr
using LinearSolve: BLASELTYPES, pattern_changed, ArrayInterface
using LinearSolve: LinearSolve, BLASELTYPES, pattern_changed, ArrayInterface,
@get_cacheval, CHOLMODFactorization, GenericFactorization, GenericLUFactorization,
KLUFactorization, LUFactorization, NormalCholeskyFactorization, OperatorAssumptions,
QRFactorization, RFLUFactorization, UMFPACKFactorization, solve
Comment on lines +4 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
@get_cacheval, CHOLMODFactorization, GenericFactorization, GenericLUFactorization,
KLUFactorization, LUFactorization, NormalCholeskyFactorization, OperatorAssumptions,
QRFactorization, RFLUFactorization, UMFPACKFactorization, solve
@get_cacheval, CHOLMODFactorization, GenericFactorization,
GenericLUFactorization,
KLUFactorization, LUFactorization, NormalCholeskyFactorization,
OperatorAssumptions,
QRFactorization, RFLUFactorization, UMFPACKFactorization, solve

using ArrayInterface: ArrayInterface
using LinearAlgebra: LinearAlgebra, I, Hermitian, Symmetric, cholesky, ldiv!, lu, lu!, QR
using SparseArrays: SparseArrays, AbstractSparseArray, AbstractSparseMatrixCSC, SparseMatrixCSC,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
using SparseArrays: SparseArrays, AbstractSparseArray, AbstractSparseMatrixCSC, SparseMatrixCSC,
using SparseArrays: SparseArrays, AbstractSparseArray, AbstractSparseMatrixCSC,
SparseMatrixCSC,

nonzeros, rowvals, getcolptr, sparse, sprand
using SparseArrays.UMFPACK: UMFPACK_OK
using Base: /, \, convert
using SciMLBase: SciMLBase, LinearProblem, ReturnCode
import StaticArraysCore: SVector

# Can't `using KLU` because cannot have a dependency in there without
# requiring the user does `using KLU`
Expand Down Expand Up @@ -187,7 +195,7 @@ function SciMLBase.solve!(
end

F = LinearSolve.@get_cacheval(cache, :UMFPACKFactorization)
if F.status == SparseArrays.UMFPACK.UMFPACK_OK
if F.status == UMFPACK_OK
y = ldiv!(cache.u, F, cache.b)
SciMLBase.build_linear_solution(alg, y, nothing, cache; retcode = ReturnCode.Success)
else
Expand Down Expand Up @@ -298,36 +306,36 @@ function LinearSolve.init_cacheval(alg::NormalCholeskyFactorization,
Symmetric{T, <:AbstractSparseArray{T}}}, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
assumptions::OperatorAssumptions) where {T <: BLASELTYPES}
LinearSolve.ArrayInterface.cholesky_instance(convert(AbstractMatrix, A))
ArrayInterface.cholesky_instance(convert(AbstractMatrix, A))
end

# Specialize QR for the non-square case
# Missing ldiv! definitions: https://github.com/JuliaSparse/SparseArrays.jl/issues/242
function LinearSolve._ldiv!(x::Vector,
A::Union{SparseArrays.QR, LinearAlgebra.QRCompactWY,
A::Union{QR, LinearAlgebra.QRCompactWY,
SparseArrays.SPQR.QRSparse,
SparseArrays.CHOLMOD.Factor}, b::Vector)
x .= A \ b
end

function LinearSolve._ldiv!(x::AbstractVector,
A::Union{SparseArrays.QR, LinearAlgebra.QRCompactWY,
A::Union{QR, LinearAlgebra.QRCompactWY,
SparseArrays.SPQR.QRSparse,
SparseArrays.CHOLMOD.Factor}, b::AbstractVector)
x .= A \ b
end

# Ambiguity removal
function LinearSolve._ldiv!(::LinearSolve.SVector,
function LinearSolve._ldiv!(::SVector,
A::Union{SparseArrays.CHOLMOD.Factor, LinearAlgebra.QR,
LinearAlgebra.QRCompactWY, SparseArrays.SPQR.QRSparse},
b::AbstractVector)
(A \ b)
end
function LinearSolve._ldiv!(::LinearSolve.SVector,
function LinearSolve._ldiv!(::SVector,
A::Union{SparseArrays.CHOLMOD.Factor, LinearAlgebra.QR,
LinearAlgebra.QRCompactWY, SparseArrays.SPQR.QRSparse},
b::LinearSolve.SVector)
b::SVector)
(A \ b)
end

Expand Down Expand Up @@ -360,16 +368,10 @@ function LinearSolve.init_cacheval(
nothing
end

function LinearSolve.init_cacheval(alg::QRFactorization, A::SparseMatrixCSC{Float64, Int}, b, u, Pl, Pr,
function LinearSolve.init_cacheval(alg::QRFactorization, A::SparseMatrixCSC{Float64, <:Integer}, b, u, Pl, Pr,
maxiters::Int, abstol, reltol, verbose::Bool,
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,
assumptions::OperatorAssumptions)
LinearSolve.ArrayInterface.qr_instance(convert(AbstractMatrix, A), alg.pivot)
ArrayInterface.qr_instance(convert(AbstractMatrix, A), alg.pivot)
end

function LinearSolve.init_cacheval(
Expand Down
14 changes: 10 additions & 4 deletions src/KLU/klu.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
module KLU

using SparseArrays
using SparseArrays: SparseMatrixCSC
using SparseArrays: SparseArrays, SparseMatrixCSC
import SparseArrays: nnz

export klu, klu!

const libklu = :libklu
const libsuitesparseconfig = :libsuitesparseconfig
using Base: Ptr, Cvoid, Cint, Cdouble, Cchar, Csize_t
include("wrappers.jl")

import Base: (\), size, getproperty, setproperty!, propertynames, show
import Base: (\), size, getproperty, setproperty!, propertynames, show,
copy, eachindex, view, sortperm, unsafe_load, zeros, convert, eltype,
length, parent, stride, finalizer, Complex, complex, imag, real, map!,
summary, println, oneunit, sizeof, isdefined, setfield!, getfield,
OutOfMemoryError, ArgumentError, OverflowError, ErrorException, DimensionMismatch

# Convert from 1-based to 0-based indices
function decrement!(A::AbstractArray{T}) where {T <: Integer}
Expand All @@ -29,7 +34,8 @@ function increment!(A::AbstractArray{T}) where {T <: Integer}
end
increment(A::AbstractArray{<:Integer}) = increment!(copy(A))

using LinearAlgebra
using LinearAlgebra: LinearAlgebra, ldiv!, Adjoint, Transpose, Factorization
import LinearAlgebra: issuccess

const AdjointFact = isdefined(LinearAlgebra, :AdjointFactorization) ?
LinearAlgebra.AdjointFactorization : Adjoint
Expand Down
47 changes: 27 additions & 20 deletions src/LinearSolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,33 @@ if isdefined(Base, :Experimental) &&
end

import PrecompileTools
using ArrayInterface
using Base: cache_dependencies, Bool
using LinearAlgebra
using ArrayInterface: ArrayInterface
using Base: Bool, convert, copyto!, adjoint, transpose, /, \, require_one_based_indexing
using LinearAlgebra: LinearAlgebra, BlasInt, LU, Adjoint, BLAS, Bidiagonal, BunchKaufman,
ColumnNorm, Diagonal, Factorization, Hermitian, I, LAPACK, NoPivot,
RowMaximum, RowNonZero, SymTridiagonal, Symmetric, Transpose,
Tridiagonal, UniformScaling, axpby!, axpy!, bunchkaufman, bunchkaufman!,
cholesky, cholesky!, diagind, dot, inv, ldiv!, ldlt!, lu, lu!, mul!, norm,
qr, qr!, svd, svd!
Comment on lines +10 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
using LinearAlgebra: LinearAlgebra, BlasInt, LU, Adjoint, BLAS, Bidiagonal, BunchKaufman,
ColumnNorm, Diagonal, Factorization, Hermitian, I, LAPACK, NoPivot,
RowMaximum, RowNonZero, SymTridiagonal, Symmetric, Transpose,
Tridiagonal, UniformScaling, axpby!, axpy!, bunchkaufman, bunchkaufman!,
cholesky, cholesky!, diagind, dot, inv, ldiv!, ldlt!, lu, lu!, mul!, norm,
qr, qr!, svd, svd!
using LinearAlgebra: LinearAlgebra, BlasInt, LU, Adjoint, BLAS, Bidiagonal, BunchKaufman,
ColumnNorm, Diagonal, Factorization, Hermitian, I, LAPACK, NoPivot,
RowMaximum, RowNonZero, SymTridiagonal, Symmetric, Transpose,
Tridiagonal, UniformScaling, axpby!, axpy!, bunchkaufman,
bunchkaufman!,
cholesky, cholesky!, diagind, dot, inv, ldiv!, ldlt!, lu, lu!, mul!,
norm,
qr, qr!, svd, svd!

using LazyArrays: @~, BroadcastArray
using SciMLBase: AbstractLinearAlgorithm, LinearAliasSpecifier
using SciMLOperators
using SciMLOperators: AbstractSciMLOperator, IdentityOperator
using Setfield
using UnPack
using DocStringExtensions
using EnumX
using Markdown
using ChainRulesCore
using SciMLBase: SciMLBase, LinearAliasSpecifier, AbstractSciMLOperator,
init, solve!, reinit!, solve, ReturnCode, LinearProblem
using SciMLOperators: SciMLOperators, AbstractSciMLOperator, IdentityOperator, MatrixOperator,
has_ldiv!, issquare
Comment on lines +19 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
using SciMLOperators: SciMLOperators, AbstractSciMLOperator, IdentityOperator, MatrixOperator,
has_ldiv!, issquare
using SciMLOperators: SciMLOperators, AbstractSciMLOperator, IdentityOperator,
MatrixOperator,
has_ldiv!, issquare

using Setfield: @set, @set!
using UnPack: @unpack
using DocStringExtensions: DocStringExtensions
using EnumX: EnumX, @enumx
using Markdown: Markdown, @doc_str
using ChainRulesCore: ChainRulesCore
using Reexport: Reexport, @reexport
using Libdl: Libdl, dlsym_e
import InteractiveUtils
import RecursiveArrayTools

import StaticArraysCore: StaticArray, SVector, MVector, SMatrix, MMatrix
import StaticArraysCore: StaticArray, SVector, SMatrix

using LinearAlgebra: BlasInt, LU
using LinearAlgebra.LAPACK: require_one_based_indexing,
chkfinite, chkstride1,
using LinearAlgebra.LAPACK: chkfinite, chkstride1,
@blasfunc, chkargsok

import GPUArraysCore
Expand All @@ -34,8 +40,6 @@ import ConcreteStructs: @concrete

# wrap
import Krylov
using SciMLBase
import Preferences

const CRC = ChainRulesCore

Expand All @@ -51,9 +55,7 @@ else
const usemkl = false
end

using Reexport
@reexport using SciMLBase
using SciMLBase: _unwrap_val

abstract type SciMLLinearSolveAlgorithm <: SciMLBase.AbstractLinearAlgorithm end
abstract type AbstractFactorization <: SciMLLinearSolveAlgorithm end
Expand Down Expand Up @@ -95,6 +97,11 @@ issparsematrix(A) = false
make_SparseMatrixCSC(A) = nothing
makeempty_SparseMatrixCSC(A) = nothing

# Stub functions for SparseArrays - overridden in extension
getcolptr(A) = error("SparseArrays extension not loaded")
rowvals(A) = error("SparseArrays extension not loaded")
nonzeros(A) = error("SparseArrays extension not loaded")

EnumX.@enumx DefaultAlgorithmChoice begin
LUFactorization
QRFactorization
Expand Down
2 changes: 1 addition & 1 deletion src/appleaccelerate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ function SciMLBase.solve!(cache::LinearCache, alg::AppleAccelerateLUFactorizatio
end

A, info = @get_cacheval(cache, :AppleAccelerateLUFactorization)
LinearAlgebra.require_one_based_indexing(cache.u, cache.b)
require_one_based_indexing(cache.u, cache.b)
m, n = size(A, 1), size(A, 2)
if m > n
Bc = copy(cache.b)
Expand Down
3 changes: 2 additions & 1 deletion src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ function SciMLBase.init(prob::LinearProblem, alg::SciMLLinearSolveAlgorithm,
elseif b isa Array
copy(b)
elseif issparsematrixcsc(b)
SparseMatrixCSC(size(b)..., getcolptr(b), rowvals(b), nonzeros(b))
# Extension must be loaded if issparsematrixcsc returns true
make_SparseMatrixCSC(b)
else
deepcopy(b)
end
Expand Down
4 changes: 2 additions & 2 deletions src/default.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function defaultalg(A::GPUArraysCore.AnyGPUArray, b::GPUArraysCore.AnyGPUArray,
end
end

function defaultalg(A::SciMLBase.AbstractSciMLOperator, b,
function defaultalg(A::SciMLOperators.AbstractSciMLOperator, b,
assump::OperatorAssumptions{Bool})
if has_ldiv!(A)
return DefaultLinearSolver(DefaultAlgorithmChoice.DirectLdiv!)
Expand All @@ -142,7 +142,7 @@ function defaultalg(A::SciMLBase.AbstractSciMLOperator, b,
end

# Fix ambiguity
function defaultalg(A::SciMLBase.AbstractSciMLOperator, b::GPUArraysCore.AnyGPUArray,
function defaultalg(A::SciMLOperators.AbstractSciMLOperator, b::GPUArraysCore.AnyGPUArray,
assump::OperatorAssumptions{Bool})
if has_ldiv!(A)
return DefaultLinearSolver(DefaultAlgorithmChoice.DirectLdiv!)
Expand Down
20 changes: 20 additions & 0 deletions test/qa.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using LinearSolve, Aqua
using ExplicitImports

@testset "Aqua" begin
Aqua.find_persistent_tasks_deps(LinearSolve)
Aqua.test_ambiguities(LinearSolve, recursive = false, broken = true)
Expand All @@ -10,3 +12,21 @@ using LinearSolve, Aqua
Aqua.test_unbound_args(LinearSolve)
Aqua.test_undefined_exports(LinearSolve)
end

@testset "Explicit Imports" begin
# Get extension modules that might be unanalyzable
klu_mod = try
Base.get_extension(LinearSolve, :LinearSolveSparseArraysExt).KLU
catch
nothing
end
unanalyzable_mods = (LinearSolve.OperatorCondition, LinearSolve.DefaultAlgorithmChoice)
if klu_mod !== nothing
unanalyzable_mods = (unanalyzable_mods..., klu_mod)
end

@test check_no_implicit_imports(LinearSolve; skip = (Base, Core),
Comment on lines +27 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
@test check_no_implicit_imports(LinearSolve; skip = (Base, Core),
@test check_no_implicit_imports(LinearSolve; skip = (Base, Core),

allow_unanalyzable = unanalyzable_mods) === nothing
@test check_no_stale_explicit_imports(LinearSolve; allow_unanalyzable = unanalyzable_mods) === nothing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
@test check_no_stale_explicit_imports(LinearSolve; allow_unanalyzable = unanalyzable_mods) === nothing
@test check_no_stale_explicit_imports(
LinearSolve; allow_unanalyzable = unanalyzable_mods) === nothing

@test check_all_qualified_accesses_via_owners(LinearSolve) === nothing
end
Loading