From 126e589f6ed1aea91f3fa2ae685c8173b256c4a6 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 6 May 2026 14:53:46 +0100 Subject: [PATCH 1/2] Fix and test `reuse_symbolic=false` for UMFPACK `lu!()` --- src/solvers/umfpack.jl | 3 ++- test/umfpack.jl | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/solvers/umfpack.jl b/src/solvers/umfpack.jl index 7a8458d9..fc4b9c17 100644 --- a/src/solvers/umfpack.jl +++ b/src/solvers/umfpack.jl @@ -471,7 +471,8 @@ function lu!(F::UmfpackLU{Tv, Ti}, S::AbstractSparseMatrixCSC; return lu!(F; reuse_symbolic, check, q) end -function lu!(F::UmfpackLU; check::Bool=true, reuse_symbolic::Bool=true, q=nothing) +function lu!(F::UmfpackLU{Tv, Ti}; check::Bool=true, reuse_symbolic::Bool=true, + q=nothing) where {Tv, Ti} if !reuse_symbolic && _isnotnull(F.symbolic) F.symbolic = Symbolic{Tv, Ti}(C_NULL) end diff --git a/test/umfpack.jl b/test/umfpack.jl index 59dc9041..90f693d7 100644 --- a/test/umfpack.jl +++ b/test/umfpack.jl @@ -440,6 +440,40 @@ end end end end + + @testset "Do not reuse symbolic LU factorization" begin + A1 = sparse(increment!([0,4,1,1,2,2,0,1,2,3,4,4]), + increment!([0,4,0,2,1,2,1,4,3,2,1,2]), + [2.,1.,3.,4.,-1.,-3.,3.,9.,2.,1.,4.,2.], 5, 5) + testtypes = [Float64, ComplexF64, Float32, ComplexF32, Float16, ComplexF16] + for Tv in testtypes + for Ti in Base.uniontypes(UMFPACK.UMFITypes) + A = convert(SparseMatrixCSC{Tv,Ti}, A0) + B = convert(SparseMatrixCSC{Tv,Ti}, A1) + b = Tv[8., 45., -3., 3., 19.] + F = lu(A) + umfpack_report(F) + lu!(F, B; reuse_symbolic=false) + umfpack_report(F) + @test F\b ≈ B\b ≈ Matrix(B)\b + + # singular matrix + C = copy(B) + C[4, 3] = Tv(0) + F = lu(A) + umfpack_report(F) + @test_throws SingularException lu!(F, C; reuse_symbolic=false) + # change of nonzero pattern + D = copy(B) + D[5, 1] = Tv(1.0) + F = lu(A) + umfpack_report(F) + lu!(F, D; reuse_symbolic=false) + umfpack_report(F) + @test F\b ≈ D\b ≈ Matrix(D)\b + end + end + end end @testset "REPL printing of UmfpackLU" begin From 5181f06f6efca6a584f121491284d733626da7af Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 7 May 2026 15:27:47 +0100 Subject: [PATCH 2/2] Add loop for reuse_symbolic=true,false rather than adding new test block --- test/umfpack.jl | 50 +++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/test/umfpack.jl b/test/umfpack.jl index 90f693d7..0a4525e2 100644 --- a/test/umfpack.jl +++ b/test/umfpack.jl @@ -408,7 +408,7 @@ end umfpack_report(x.b) end - @testset "Reuse symbolic LU factorization" begin + @testset "Do/do not reuse symbolic LU factorization" for reuse ∈ (true, false) A1 = sparse(increment!([0,4,1,1,2,2,0,1,2,3,4,4]), increment!([0,4,0,2,1,2,1,4,3,2,1,2]), [2.,1.,3.,4.,-1.,-3.,3.,9.,2.,1.,4.,2.], 5, 5) @@ -420,7 +420,7 @@ end b = Tv[8., 45., -3., 3., 19.] F = lu(A) umfpack_report(F) - lu!(F, B) + lu!(F, B; reuse_symbolic=reuse) umfpack_report(F) @test F\b ≈ B\b ≈ Matrix(B)\b @@ -429,48 +429,20 @@ end C[4, 3] = Tv(0) F = lu(A) umfpack_report(F) - @test_throws SingularException lu!(F, C) + @test_throws SingularException lu!(F, C; reuse_symbolic=reuse) # change of nonzero pattern D = copy(B) D[5, 1] = Tv(1.0) F = lu(A) umfpack_report(F) - @test_throws ArgumentError lu!(F, D) - umfpack_report(F) - end - end - end - - @testset "Do not reuse symbolic LU factorization" begin - A1 = sparse(increment!([0,4,1,1,2,2,0,1,2,3,4,4]), - increment!([0,4,0,2,1,2,1,4,3,2,1,2]), - [2.,1.,3.,4.,-1.,-3.,3.,9.,2.,1.,4.,2.], 5, 5) - testtypes = [Float64, ComplexF64, Float32, ComplexF32, Float16, ComplexF16] - for Tv in testtypes - for Ti in Base.uniontypes(UMFPACK.UMFITypes) - A = convert(SparseMatrixCSC{Tv,Ti}, A0) - B = convert(SparseMatrixCSC{Tv,Ti}, A1) - b = Tv[8., 45., -3., 3., 19.] - F = lu(A) - umfpack_report(F) - lu!(F, B; reuse_symbolic=false) - umfpack_report(F) - @test F\b ≈ B\b ≈ Matrix(B)\b - - # singular matrix - C = copy(B) - C[4, 3] = Tv(0) - F = lu(A) - umfpack_report(F) - @test_throws SingularException lu!(F, C; reuse_symbolic=false) - # change of nonzero pattern - D = copy(B) - D[5, 1] = Tv(1.0) - F = lu(A) - umfpack_report(F) - lu!(F, D; reuse_symbolic=false) - umfpack_report(F) - @test F\b ≈ D\b ≈ Matrix(D)\b + if reuse + @test_throws ArgumentError lu!(F, D; reuse_symbolic=reuse) + umfpack_report(F) + else + lu!(F, D; reuse_symbolic=reuse) + umfpack_report(F) + @test F\b ≈ D\b ≈ Matrix(D)\b + end end end end