Skip to content

Commit 44d077d

Browse files
authored
Backports to release 1.12 (#702)
- [x] #689 - [x] #677 - [x] #692
2 parents 2376bf8 + a1478bd commit 44d077d

9 files changed

Lines changed: 159 additions & 118 deletions

File tree

gen/Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
44
SuiteSparse_jll = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
55

66
[compat]
7-
Clang = "0.18"
8-
JuliaFormatter = "1.0.45"
7+
Clang = "0.18, 0.19"
8+
JuliaFormatter = "2"

gen/generator.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ else
2222
end
2323
include_dir = joinpath(artifact_dir, "include", "suitesparse") |> normpath
2424

25+
config_h = joinpath(include_dir, "SuiteSparse_config.h")
26+
@assert isfile(config_h)
27+
2528
cholmod_h = joinpath(include_dir, "cholmod.h")
2629
@assert isfile(cholmod_h)
2730

@@ -42,7 +45,7 @@ options["general"]["output_file_path"] = joinpath(@__DIR__, "..", "src/solvers/w
4245
args = get_default_args()
4346
push!(args, "-I$include_dir")
4447

45-
header_files = [cholmod_h, SuiteSparseQR_C_h, umfpack_h]
48+
header_files = [config_h, cholmod_h, SuiteSparseQR_C_h, umfpack_h]
4649

4750
ctx = create_context(header_files, args, options)
4851

src/SparseArrays.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Base: Matrix, Vector
1919
import LinearAlgebra: mul!, ldiv!, rdiv!, cholesky, adjoint!, diag, eigen, dot,
2020
issymmetric, istril, istriu, lu, tr, transpose!, tril!, triu!, isbanded,
2121
cond, diagm, factorize, ishermitian, norm, opnorm, lmul!, rmul!, tril, triu,
22-
matprod_dest, generic_matvecmul!, generic_matmatmul!, copytrito!
22+
matprod_dest, generic_matvecmul!, generic_matmatmul!, generic_matmatmul_wrapper!, copytrito!
2323

2424
import Base: adjoint, argmin, argmax, Array, broadcast, circshift!, complex, Complex,
2525
conj, conj!, convert, copy, copy!, copyto!, count, diff, findall, findmax, findmin,

src/linalg.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ Base.@constprop :aggressive function spdensemul!(C, tA, tB, A, B, alpha, beta)
6262
_At_or_Ac_mul_B!(transpose, C, A, wrap(B, tB), alpha, beta)
6363
elseif tA_uc == 'C'
6464
_At_or_Ac_mul_B!(adjoint, C, A, wrap(B, tB), alpha, beta)
65-
elseif tA_uc in ('S', 'H') && tB_uc == 'N'
65+
elseif tA_uc in ('S', 'H')
6666
rangefun = isuppercase(tA) ? nzrangeup : nzrangelo
6767
diagop = tA_uc == 'S' ? identity : real
6868
odiagop = tA_uc == 'S' ? transpose : adjoint
6969
T = eltype(C)
70-
_mul!(rangefun, diagop, odiagop, C, A, B, T(alpha), T(beta))
70+
_mul!(rangefun, diagop, odiagop, C, A, wrap(B, tB), T(alpha), T(beta))
7171
else
7272
@stable_muladdmul LinearAlgebra._generic_matmatmul!(C, wrap(A, tA), wrap(B, tB), MulAddMul(alpha, beta))
7373
end
@@ -117,7 +117,7 @@ function _At_or_Ac_mul_B!(tfun::Function, C, A, B, α, β)
117117
C
118118
end
119119

120-
Base.@constprop :aggressive function generic_matmatmul!(C::StridedMatrix, tA, tB, A::DenseMatrixUnion, B::SparseMatrixCSCUnion2, alpha::Number, beta::Number)
120+
Base.@constprop :aggressive function generic_matmatmul_wrapper!(C::StridedMatrix, tA, tB, A::DenseMatrixUnion, B::SparseMatrixCSCUnion2, alpha::Number, beta::Number, ::LinearAlgebra.BlasFlag.SyrkHerkGemm)
121121
transA = tA == 'N' ? identity : tA == 'T' ? transpose : adjoint
122122
if tB == 'N'
123123
_spmul!(C, transA(A), B, alpha, beta)
@@ -128,6 +128,9 @@ Base.@constprop :aggressive function generic_matmatmul!(C::StridedMatrix, tA, tB
128128
end
129129
return C
130130
end
131+
Base.@constprop :aggressive generic_matmatmul_wrapper!(C::StridedMatrix, tA, tB, A::DenseMatrixUnion, B::SparseMatrixCSCUnion2, alpha::Number, beta::Number, @nospecialize(val)) =
132+
LinearAlgebra._generic_matmatmul!(C, wrap(A, tA), wrap(B, tB), alpha, beta)
133+
131134
function _spmul!(C::StridedMatrix, X::DenseMatrixUnion, A::SparseMatrixCSCUnion2, α::Number, β::Number)
132135
mX, nX = size(X)
133136
nX == size(A, 1) ||

src/solvers/LibSuiteSparse.jl

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,106 @@
11
module LibSuiteSparse
22

33
using SuiteSparse_jll
4+
import Libdl
45

56
const TRUE = Int32(1)
67
const FALSE = Int32(0)
78

89
include("wrappers.jl")
910

11+
const SUITESPARSE_MIN_VERSION = v"6.0.0"
12+
const BUILD_VERSION = VersionNumber(
13+
SUITESPARSE_MAIN_VERSION,
14+
SUITESPARSE_SUB_VERSION,
15+
SUITESPARSE_SUBSUB_VERSION
16+
)
17+
18+
public init_suitesparse
19+
20+
"""
21+
LibSuiteSparse.init_suitesparse
22+
23+
Internal function which is used to initialize the SuiteSparse libraries to the correct
24+
memory management functions. Any package which directly wraps one of the following
25+
SuiteSparse libraries *must* ensure that this function is called before the use of that
26+
library: AMD, CAMD, COLAMD, CCOLAMD, UMFPACK, CXSparse, CHOLMOD, KLU, BTF, LDL, RBio,
27+
SPQR, SPEX, and ParU
28+
29+
# Notes:
30+
- Currently this function only sets the memory management functions of SuiteSparse_config,
31+
however there are also override functions for `printf`, `hypot`, and `divcomplex`.
32+
- SuiteSparse_config, and this initialization function, is not a dependency of CSparse,
33+
GraphBLAS, or LAGraph.
34+
"""
35+
const init_suitesparse = Base.OncePerProcess{Nothing}() do
36+
try
37+
### Check if the linked library is compatible with the Julia code
38+
if Libdl.dlsym_e(Libdl.dlopen("libsuitesparseconfig"), :SuiteSparse_version) != C_NULL
39+
current_version_array = Vector{Cint}(undef, 3)
40+
SuiteSparse_version(current_version_array)
41+
current_version = VersionNumber(current_version_array...)
42+
else # SuiteSparse < 4.2.0 does not include SuiteSparse_version()
43+
current_version = v"0.0.0"
44+
end
45+
46+
47+
if current_version < SUITESPARSE_MIN_VERSION
48+
@warn """
49+
SuiteSparse version incompatibility
50+
51+
Julia was compiled with SuiteSparse version $BUILD_VERSION. It is
52+
currently linked with a version older than
53+
$(SUITESPARSE_MIN_VERSION). This might cause Julia to
54+
terminate when working with sparse matrix factorizations,
55+
e.g. solving systems of equations with \\.
56+
57+
It is recommended that you use Julia with a recent version
58+
of SuiteSparse, or download the generic binaries
59+
from www.julialang.org, which ship with the correct
60+
versions of all dependencies.
61+
"""
62+
elseif BUILD_VERSION.major != current_version.major
63+
@warn """
64+
SuiteSparse version incompatibility
65+
66+
Julia was compiled with SuiteSparse version $BUILD_VERSION. It is
67+
currently linked with version $current_version.
68+
This might cause Julia to terminate when working with
69+
sparse matrix factorizations, e.g. solving systems of
70+
equations with \\.
71+
72+
It is recommended that you use Julia with the same major
73+
version of SuiteSparse as the one used during the build, or
74+
download the generic binaries from www.julialang.org,
75+
which ship with the correct versions of all dependencies.
76+
"""
77+
end
78+
79+
current_version >= v"6.0.0" && SuiteSparse_start()
80+
81+
# Register gc tracked allocator if SuiteSparse is new enough
82+
if current_version >= v"7.0.0"
83+
SuiteSparse_config_malloc_func_set(cglobal(:jl_malloc, Ptr{Cvoid}))
84+
SuiteSparse_config_calloc_func_set(cglobal(:jl_calloc, Ptr{Cvoid}))
85+
SuiteSparse_config_realloc_func_set(cglobal(:jl_realloc, Ptr{Cvoid}))
86+
SuiteSparse_config_free_func_set(cglobal(:jl_free, Ptr{Cvoid}))
87+
elseif current_version >= v"4.2.0"
88+
cnfg = cglobal((:SuiteSparse_config, libsuitesparseconfig), Ptr{Cvoid})
89+
unsafe_store!(cnfg, cglobal(:jl_malloc, Ptr{Cvoid}), 1)
90+
unsafe_store!(cnfg, cglobal(:jl_calloc, Ptr{Cvoid}), 2)
91+
unsafe_store!(cnfg, cglobal(:jl_realloc, Ptr{Cvoid}), 3)
92+
unsafe_store!(cnfg, cglobal(:jl_free, Ptr{Cvoid}), 4)
93+
end
94+
95+
current_version >= v"6.0.0" && atexit() do
96+
SuiteSparse_finish()
97+
end
98+
99+
catch ex
100+
@error "Error during initialization of module LibSuiteSparse" exception=ex,catch_backtrace()
101+
end
102+
end
103+
10104
# exports
11105
const PREFIXES = ["cholmod_", "CHOLMOD_", "umfpack_"]
12106
for name in names(@__MODULE__; all=true), prefix in PREFIXES

src/solvers/cholmod.jl

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import LinearAlgebra: (\), AdjointFactorization,
2424

2525
using SparseArrays
2626
using SparseArrays: getcolptr, AbstractSparseVecOrMat
27-
import Libdl
28-
2927
export
3028
Dense,
3129
Factor,
@@ -174,84 +172,19 @@ function newcommon(; print = 0) # no printing from CHOLMOD by default
174172
end
175173

176174
function getcommon(::Type{Int32})
175+
LibSuiteSparse.init_suitesparse()
177176
return get!(newcommon, task_local_storage(), :cholmod_common)::Ref{cholmod_common}
178177
end
179178

180179
function getcommon(::Type{Int64})
180+
LibSuiteSparse.init_suitesparse()
181181
return get!(newcommon_l, task_local_storage(), :cholmod_common_l)::Ref{cholmod_common}
182182
end
183183

184184
getcommon() = getcommon(Int)
185185

186186
const BUILD_VERSION = VersionNumber(CHOLMOD_MAIN_VERSION, CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION)
187187

188-
function __init__()
189-
try
190-
### Check if the linked library is compatible with the Julia code
191-
if Libdl.dlsym_e(Libdl.dlopen("libcholmod"), :cholmod_version) != C_NULL
192-
current_version_array = Vector{Cint}(undef, 3)
193-
cholmod_version(current_version_array)
194-
current_version = VersionNumber(current_version_array...)
195-
else # CHOLMOD < 2.1.1 does not include cholmod_version()
196-
current_version = v"0.0.0"
197-
end
198-
199-
200-
if current_version < CHOLMOD_MIN_VERSION
201-
@warn """
202-
CHOLMOD version incompatibility
203-
204-
Julia was compiled with CHOLMOD version $BUILD_VERSION. It is
205-
currently linked with a version older than
206-
$(CHOLMOD_MIN_VERSION). This might cause Julia to
207-
terminate when working with sparse matrix factorizations,
208-
e.g. solving systems of equations with \\.
209-
210-
It is recommended that you use Julia with a recent version
211-
of CHOLMOD, or download the generic binaries
212-
from www.julialang.org, which ship with the correct
213-
versions of all dependencies.
214-
"""
215-
elseif BUILD_VERSION.major != current_version.major
216-
@warn """
217-
CHOLMOD version incompatibility
218-
219-
Julia was compiled with CHOLMOD version $BUILD_VERSION. It is
220-
currently linked with version $current_version.
221-
This might cause Julia to terminate when working with
222-
sparse matrix factorizations, e.g. solving systems of
223-
equations with \\.
224-
225-
It is recommended that you use Julia with the same major
226-
version of CHOLMOD as the one used during the build, or
227-
download the generic binaries from www.julialang.org,
228-
which ship with the correct versions of all dependencies.
229-
"""
230-
end
231-
232-
# Register gc tracked allocator if CHOLMOD is new enough
233-
if current_version >= v"4.0.3"
234-
ccall((:SuiteSparse_config_malloc_func_set, libsuitesparseconfig),
235-
Cvoid, (Ptr{Cvoid},), cglobal(:jl_malloc, Ptr{Cvoid}))
236-
ccall((:SuiteSparse_config_calloc_func_set, libsuitesparseconfig),
237-
Cvoid, (Ptr{Cvoid},), cglobal(:jl_calloc, Ptr{Cvoid}))
238-
ccall((:SuiteSparse_config_realloc_func_set, libsuitesparseconfig),
239-
Cvoid, (Ptr{Cvoid},), cglobal(:jl_realloc, Ptr{Cvoid}))
240-
ccall((:SuiteSparse_config_free_func_set, libsuitesparseconfig),
241-
Cvoid, (Ptr{Cvoid},), cglobal(:jl_free, Ptr{Cvoid}))
242-
elseif current_version >= v"3.0.0"
243-
cnfg = cglobal((:SuiteSparse_config, libsuitesparseconfig), Ptr{Cvoid})
244-
unsafe_store!(cnfg, cglobal(:jl_malloc, Ptr{Cvoid}), 1)
245-
unsafe_store!(cnfg, cglobal(:jl_calloc, Ptr{Cvoid}), 2)
246-
unsafe_store!(cnfg, cglobal(:jl_realloc, Ptr{Cvoid}), 3)
247-
unsafe_store!(cnfg, cglobal(:jl_free, Ptr{Cvoid}), 4)
248-
end
249-
250-
catch ex
251-
@error "Error during initialization of module CHOLMOD" exception=ex,catch_backtrace()
252-
end
253-
end
254-
255188
####################
256189
# Type definitions #
257190
####################

src/solvers/umfpack.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,15 +325,15 @@ is provided or `q` is `nothing`, UMFPACK's default is used. If the permutation i
325325
zero-based copy is made.
326326
327327
The `control` vector defaults to the Julia SparseArrays package's default configuration for UMFPACK (NB: this is modified from the UMFPACK defaults to
328-
disable iterative refinement), but can be changed by passing a vector of length `UMFPACK_CONTROL`, see the UMFPACK manual for possible configurations.
328+
disable iterative refinement), but can be changed by passing a vector of length `UMFPACK_CONTROL`, see the UMFPACK manual for possible configurations.
329329
For example to reenable iterative refinement:
330330
331331
umfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # read Julia default configuration for a Float64 sparse matrix
332332
SparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # optional - display values
333333
umfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # reenable iterative refinement (2 is UMFPACK default max iterative refinement steps)
334334
335335
Alu = lu(A; control = umfpack_control)
336-
x = Alu \\ b # solve Ax = b, including UMFPACK iterative refinement
336+
x = Alu \\ b # solve Ax = b, including UMFPACK iterative refinement
337337
338338
The individual components of the factorization `F` can be accessed by indexing:
339339
@@ -1036,6 +1036,7 @@ for Tv in (:Float64, :ComplexF64), Ti in UmfpackIndexTypes
10361036
# the control and info arrays
10371037
_defaults = Symbol(umf_nm("defaults", Tv, Ti))
10381038
@eval function get_umfpack_control(::Type{$Tv}, ::Type{$Ti})
1039+
LibSuiteSparse.init_suitesparse()
10391040
control = Vector{Float64}(undef, UMFPACK_CONTROL)
10401041
$_defaults(control)
10411042
# Put julia's config here

0 commit comments

Comments
 (0)