Skip to content

Commit b7f0a96

Browse files
Merge pull request #43 from Wimmerer/savesymbolic
Initial pass at storing symbolic factorization
2 parents d2a6167 + 734ff6b commit b7f0a96

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

Project.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Requires = "ae029012-a4dd-5104-9daa-d747884805df"
1515
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
1616
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
1717
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
18+
SuiteSparse = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"
1819
UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
1920

2021
[compat]
@@ -35,4 +36,4 @@ Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2"
3536
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3637

3738
[targets]
38-
test = ["Test","Pardiso"]
39+
test = ["Test", "Pardiso"]

src/LinearSolve.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ using SciMLBase: AbstractDiffEqOperator, AbstractLinearAlgorithm
1111
using Setfield
1212
using UnPack
1313
using Requires
14-
14+
using SuiteSparse
1515
# wrap
1616
import Krylov
1717
import KrylovKit # TODO
@@ -44,7 +44,7 @@ function __init__()
4444
end
4545

4646
export LUFactorization, SVDFactorization, QRFactorization, GenericFactorization,
47-
RFLUFactorizaation
47+
RFLUFactorizaation, UMFPACKFactorization
4848
export KrylovJL, KrylovJL_CG, KrylovJL_GMRES, KrylovJL_BICGSTAB, KrylovJL_MINRES,
4949
IterativeSolversJL, IterativeSolversJL_CG, IterativeSolversJL_GMRES,
5050
IterativeSolversJL_BICGSTAB, IterativeSolversJL_MINRES

src/factorization.jl

+24-2
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ function init_cacheval(alg::LUFactorization, A, b, u)
3535
end
3636

3737
# This could be a GenericFactorization perhaps?
38-
struct UMFPACKFactorization <: AbstractFactorization
38+
Base.@kwdef struct UMFPACKFactorization <: AbstractFactorization
39+
reuse_symbolic::Bool = true
3940
end
4041

41-
function init_cacheval(alg::UMFPACKFactorization, A, b, u)
42+
function init_cacheval(::UMFPACKFactorization, A, b, u)
4243
if A isa AbstractDiffEqOperator
4344
A = A.A
4445
end
@@ -49,6 +50,27 @@ function init_cacheval(alg::UMFPACKFactorization, A, b, u)
4950
end
5051
end
5152

53+
function SciMLBase.solve(cache::LinearCache, alg::UMFPACKFactorization)
54+
A = cache.A
55+
if A isa AbstractDiffEqOperator
56+
A = A.A
57+
end
58+
if cache.isfresh
59+
if cache.cacheval !== nothing && alg.reuse_symbolic
60+
# If we have a cacheval already, run umfpack_symbolic to ensure the symbolic factorization exists
61+
# This won't recompute if it does.
62+
SuiteSparse.UMFPACK.umfpack_symbolic!(cache.cacheval)
63+
fact = lu!(cache.cacheval, A)
64+
else
65+
fact = init_cacheval(alg, A, cache.b, cache.u)
66+
end
67+
cache = set_cacheval(cache, fact)
68+
end
69+
70+
y = ldiv!(cache.u, cache.cacheval, cache.b)
71+
SciMLBase.build_linear_solution(alg,y,nothing)
72+
end
73+
5274
## QRFactorization
5375

5476
struct QRFactorization{P} <: AbstractFactorization

test/runtests.jl

+17-1
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,33 @@ end
5959
y = solve(_prob)
6060
@test A1 * y b1
6161

62+
6263
_prob = LinearProblem(sparse(A1.A), b1; u0=x1)
6364
y = solve(_prob)
6465
@test A1 * y b1
6566
end
6667

68+
@testset "UMFPACK Factorization" begin
69+
A1 = A/1; b1 = rand(n); x1 = zero(b)
70+
A2 = A/2; b2 = rand(n); x2 = zero(b)
71+
72+
prob1 = LinearProblem(sparse(A1), b1; u0=x1)
73+
prob2 = LinearProblem(sparse(A2), b2; u0=x2)
74+
test_interface(UMFPACKFactorization(), prob1, prob2)
75+
76+
# Test that refactoring wrong throws.
77+
cache = SciMLBase.init(prob1,UMFPACKFactorization(reuse_symbolic=true); cache_kwargs...) # initialize cache
78+
y = solve(cache)
79+
cache = LinearSolve.set_A(cache,sprand(n, n, 0.8))
80+
@test_throws ArgumentError solve(cache)
81+
end
82+
6783
@testset "Concrete Factorizations" begin
6884
for alg in (
6985
LUFactorization(),
7086
QRFactorization(),
7187
SVDFactorization(),
72-
RFLUFactorizaation(),
88+
RFLUFactorizaation()
7389
)
7490
@testset "$alg" begin
7591
test_interface(alg, prob1, prob2)

0 commit comments

Comments
 (0)