Skip to content

Commit cc65daa

Browse files
committed
Proper handling of static arrays
1 parent bda160c commit cc65daa

File tree

4 files changed

+30
-26
lines changed

4 files changed

+30
-26
lines changed

Project.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ Aqua = "0.8"
6363
ArrayInterface = "7.4.11"
6464
BandedMatrices = "1"
6565
BlockDiagonals = "0.1"
66-
ConcreteStructs = "0.2"
6766
CUDA = "5"
67+
ConcreteStructs = "0.2"
6868
DocStringExtensions = "0.9"
6969
EnumX = "1"
7070
Enzyme = "0.11"
@@ -77,15 +77,15 @@ GPUArraysCore = "0.1"
7777
HYPRE = "1.4.0"
7878
InteractiveUtils = "1.6"
7979
IterativeSolvers = "0.9.3"
80-
Libdl = "1.6"
81-
LinearAlgebra = "1.9"
8280
JET = "0.8"
8381
KLU = "0.3.0, 0.4"
8482
KernelAbstractions = "0.9"
8583
Krylov = "0.9"
8684
KrylovKit = "0.6"
87-
Metal = "0.5"
85+
Libdl = "1.6"
86+
LinearAlgebra = "1.9"
8887
MPI = "0.20"
88+
Metal = "0.5"
8989
MultiFloats = "1"
9090
Pardiso = "0.5"
9191
Pkg = "1"
@@ -102,8 +102,8 @@ SciMLOperators = "0.3"
102102
Setfield = "1"
103103
SparseArrays = "1.9"
104104
Sparspak = "0.3.6"
105-
StaticArraysCore = "1"
106105
StaticArrays = "1"
106+
StaticArraysCore = "1"
107107
Test = "1"
108108
UnPack = "1"
109109
julia = "1.9"

src/common.jl

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ default_alias_b(::Any, ::Any, ::Any) = false
119119
default_alias_A(::AbstractKrylovSubspaceMethod, ::Any, ::Any) = true
120120
default_alias_b(::AbstractKrylovSubspaceMethod, ::Any, ::Any) = true
121121

122+
function __init_u0_from_Ab(A, b)
123+
u0 = similar(b, size(A, 2))
124+
fill!(u0, false)
125+
return u0
126+
end
127+
function __init_u0_from_Ab(A::SMatrix{S1, S2}, b) where {S1, S2}
128+
return zeros(SVector{S2, eltype(b)})
129+
end
130+
122131
function SciMLBase.init(prob::LinearProblem, alg::SciMLLinearSolveAlgorithm,
123132
args...;
124133
alias_A = default_alias_A(alg, prob.A, prob.b),
@@ -133,7 +142,7 @@ function SciMLBase.init(prob::LinearProblem, alg::SciMLLinearSolveAlgorithm,
133142
kwargs...)
134143
@unpack A, b, u0, p = prob
135144

136-
A = if alias_A
145+
A = if alias_A || A isa SMatrix
137146
A
138147
elseif A isa Array || A isa SparseMatrixCSC
139148
copy(A)
@@ -143,34 +152,29 @@ function SciMLBase.init(prob::LinearProblem, alg::SciMLLinearSolveAlgorithm,
143152

144153
b = if b isa SparseArrays.AbstractSparseArray && !(A isa Diagonal)
145154
Array(b) # the solution to a linear solve will always be dense!
146-
elseif alias_b
155+
elseif alias_b || b isa SVector
147156
b
148157
elseif b isa Array || b isa SparseMatrixCSC
149158
copy(b)
150159
else
151160
deepcopy(b)
152161
end
153162

154-
u0 = if u0 !== nothing
155-
u0
156-
else
157-
u0 = similar(b, size(A, 2))
158-
fill!(u0, false)
159-
end
163+
u0_ = u0 !== nothing ? u0 : __init_u0_from_Ab(A, b)
160164

161165
# Guard against type mismatch for user-specified reltol/abstol
162166
reltol = real(eltype(prob.b))(reltol)
163167
abstol = real(eltype(prob.b))(abstol)
164168

165-
cacheval = init_cacheval(alg, A, b, u0, Pl, Pr, maxiters, abstol, reltol, verbose,
169+
cacheval = init_cacheval(alg, A, b, u0_, Pl, Pr, maxiters, abstol, reltol, verbose,
166170
assumptions)
167171
isfresh = true
168172
Tc = typeof(cacheval)
169173

170174
cache = LinearCache{
171175
typeof(A),
172176
typeof(b),
173-
typeof(u0),
177+
typeof(u0_),
174178
typeof(p),
175179
typeof(alg),
176180
Tc,
@@ -180,7 +184,7 @@ function SciMLBase.init(prob::LinearProblem, alg::SciMLLinearSolveAlgorithm,
180184
typeof(assumptions.issq),
181185
}(A,
182186
b,
183-
u0,
187+
u0_,
184188
p,
185189
alg,
186190
cacheval,

src/default.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ function defaultalg(A, b, assump::OperatorAssumptions{Nothing})
3636
defaultalg(A, b, OperatorAssumptions(issq, assump.condition))
3737
end
3838

39+
function defaultalg(A::SMatrix{S1, S2}, b, assump::OperatorAssumptions{Bool}) where {S1, S2}
40+
if S1 == S2
41+
return LUFactorization()
42+
else
43+
return SVDFactorization() # QR(...) \ b is not defined currently
44+
end
45+
end
46+
3947
function defaultalg(A::Tridiagonal, b, assump::OperatorAssumptions{Bool})
4048
if assump.issq
4149
DefaultLinearSolver(DefaultAlgorithmChoice.LUFactorization)
@@ -175,10 +183,6 @@ function defaultalg(A, b, assump::OperatorAssumptions{Bool})
175183
DefaultAlgorithmChoice.LUFactorization
176184
end
177185

178-
# For static arrays GMRES allocates a lot. Use factorization
179-
elseif A isa StaticArray
180-
DefaultAlgorithmChoice.LUFactorization
181-
182186
# This catches the cases where a factorization overload could exist
183187
# For example, BlockBandedMatrix
184188
elseif A !== nothing && ArrayInterface.isstructured(A)
@@ -190,9 +194,6 @@ function defaultalg(A, b, assump::OperatorAssumptions{Bool})
190194
end
191195
elseif assump.condition === OperatorCondition.WellConditioned
192196
DefaultAlgorithmChoice.NormalCholeskyFactorization
193-
elseif A isa StaticArray
194-
# Static Array doesn't have QR() \ b defined
195-
DefaultAlgorithmChoice.SVDFactorization
196197
elseif assump.condition === OperatorCondition.IllConditioned
197198
if is_underdetermined(A)
198199
# Underdetermined
@@ -269,8 +270,7 @@ function SciMLBase.init(prob::LinearProblem, alg::Nothing,
269270
args...;
270271
assumptions = OperatorAssumptions(issquare(prob.A)),
271272
kwargs...)
272-
alg = defaultalg(prob.A, prob.b, assumptions)
273-
SciMLBase.init(prob, alg, args...; assumptions, kwargs...)
273+
SciMLBase.init(prob, defaultalg(prob.A, prob.b, assumptions), args...; assumptions, kwargs...)
274274
end
275275

276276
function SciMLBase.solve!(cache::LinearCache, alg::Nothing,

test/static_arrays.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using LinearSolve, StaticArrays, LinearAlgebra
1+
using LinearSolve, StaticArrays, LinearAlgebra, Test
22

33
A = SMatrix{5, 5}(Hermitian(rand(5, 5) + I))
44
b = SVector{5}(rand(5))

0 commit comments

Comments
 (0)