From bca2f420ad3a1331622a44872fd8f4b5fa96a366 Mon Sep 17 00:00:00 2001 From: Andreas Noack Date: Wed, 2 Jan 2019 21:06:42 +0100 Subject: [PATCH] Add custom deserialize method for UmfpackLU to avoid memory leak (#30425) Fixes #15450 (cherry picked from commit 356ceeee0170e41ac109abc0841d394f5472c5e7) --- stdlib/SuiteSparse/Project.toml | 5 +++-- stdlib/SuiteSparse/src/umfpack.jl | 18 ++++++++++++++++++ stdlib/SuiteSparse/test/umfpack.jl | 13 +++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/stdlib/SuiteSparse/Project.toml b/stdlib/SuiteSparse/Project.toml index 8ea21106262c4..a851e081a383e 100644 --- a/stdlib/SuiteSparse/Project.toml +++ b/stdlib/SuiteSparse/Project.toml @@ -4,13 +4,14 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [extras] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] test = ["Test", "Random", "DelimitedFiles", "Serialization"] diff --git a/stdlib/SuiteSparse/src/umfpack.jl b/stdlib/SuiteSparse/src/umfpack.jl index a8eb90ed379c4..23c0708fb72d8 100644 --- a/stdlib/SuiteSparse/src/umfpack.jl +++ b/stdlib/SuiteSparse/src/umfpack.jl @@ -11,6 +11,8 @@ import LinearAlgebra: Factorization, det, lu, ldiv! using SparseArrays import SparseArrays: nnz +import Serialization: AbstractSerializer, deserialize + import ..increment, ..increment!, ..decrement, ..decrement! include("umfpack_h.jl") @@ -192,6 +194,22 @@ function show(io::IO, F::UmfpackLU) F.numeric != C_NULL && print(io, '\n', F.numeric) end +function deserialize(s::AbstractSerializer, t::Type{UmfpackLU{Tv,Ti}}) where {Tv,Ti} + symbolic = deserialize(s) + numeric = deserialize(s) + m = deserialize(s) + n = deserialize(s) + colptr = deserialize(s) + rowval = deserialize(s) + nzval = deserialize(s) + status = deserialize(s) + obj = UmfpackLU{Tv,Ti}(symbolic, numeric, m, n, colptr, rowval, nzval, status) + + finalizer(umfpack_free_symbolic, obj) + + return obj +end + ## Wrappers for UMFPACK functions # generate the name of the C function according to the value and integer types diff --git a/stdlib/SuiteSparse/test/umfpack.jl b/stdlib/SuiteSparse/test/umfpack.jl index 1683f21aa4aab..12ce4c9bddac4 100644 --- a/stdlib/SuiteSparse/test/umfpack.jl +++ b/stdlib/SuiteSparse/test/umfpack.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using SuiteSparse: increment! +using Serialization using LinearAlgebra: Adjoint, Transpose, SingularException @testset "UMFPACK wrappers" begin @@ -176,4 +177,16 @@ using LinearAlgebra: Adjoint, Transpose, SingularException end end + @testset "deserialization" begin + A = sprandn(10, 10, 0.4) + F1 = lu(A) + b = IOBuffer() + serialize(b, F1) + seekstart(b) + F2 = deserialize(b) + for nm in (:colptr, :m, :n, :nzval, :rowval, :status) + @test getfield(F1, nm) == getfield(F2, nm) + end + end + end