Skip to content

Commit fcc6102

Browse files
ViralBShahKristofferC
authored andcommitted
Do not use nested dissection by default. (#550)
* Do not use nested dissection by default. Provide a named parameter `nested_dissection` to `symbolic()` to turn it on. Co-authored-by: Kristoffer Carlsson <[email protected]> * Merge Sparse Linear Algebra docs into SparseArrays so that it shows in the Julia manual Consolidate all external packages in one place --------- Co-authored-by: Kristoffer Carlsson <[email protected]>
1 parent 8534357 commit fcc6102

File tree

4 files changed

+82
-74
lines changed

4 files changed

+82
-74
lines changed

docs/make.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ makedocs(
88
sitename = "SparseArrays",
99
pages = Any[
1010
"SparseArrays" => "index.md",
11-
"Sparse Linear Algebra" => "solvers.md",
1211
];
1312
warnonly = [:missing_docs, :cross_references],
1413
)

docs/src/index.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,22 @@ section of the standard library reference.
206206
| [`sprandn(m,n,d)`](@ref) | [`randn(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution. |
207207
| [`sprandn(rng,m,n,d)`](@ref) | [`randn(rng,m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements generated with the `rng` random number generator |
208208

209+
## [Sparse Linear Algebra](@id stdlib-sparse-linalg)
210+
211+
Sparse matrix solvers call functions from [SuiteSparse](http://suitesparse.com). The following factorizations are available:
212+
213+
| Type | Description |
214+
|:----------------------|:--------------------------------------------- |
215+
| `CHOLMOD.Factor` | Cholesky and LDLt factorizations |
216+
| `UMFPACK.UmfpackLU` | LU factorization |
217+
| `SPQR.QRSparse` | QR factorization |
218+
219+
These factorizations are described in more detail in the [Sparse Linear Algebra API section](@ref stdlib-sparse-linalg-api):
220+
221+
1. [`cholesky`](@ref SparseArrays.CHOLMOD.cholesky)
222+
2. [`ldlt`](@ref SparseArrays.CHOLMOD.ldlt)
223+
3. [`lu`](@ref SparseArrays.UMFPACK.lu)
224+
4. [`qr`](@ref SparseArrays.SPQR.qr)
209225

210226
```@meta
211227
DocTestSetup = nothing
@@ -250,6 +266,26 @@ SparseArrays.ftranspose!
250266
```@meta
251267
DocTestSetup = nothing
252268
```
269+
270+
# [Sparse Linear Algebra API](@id stdlib-sparse-linalg-api)
271+
272+
```@docs
273+
SparseArrays.CHOLMOD.cholesky
274+
SparseArrays.CHOLMOD.cholesky!
275+
SparseArrays.CHOLMOD.lowrankupdate
276+
SparseArrays.CHOLMOD.lowrankupdate!
277+
SparseArrays.CHOLMOD.lowrankdowndate
278+
SparseArrays.CHOLMOD.lowrankdowndate!
279+
SparseArrays.CHOLMOD.lowrankupdowndate!
280+
SparseArrays.CHOLMOD.ldlt
281+
SparseArrays.UMFPACK.lu
282+
SparseArrays.SPQR.qr
283+
```
284+
285+
```@meta
286+
DocTestSetup = nothing
287+
```
288+
253289
# Noteworthy External Sparse Packages
254290

255291
Several other Julia packages provide sparse matrix implementations that should be mentioned:
@@ -269,3 +305,15 @@ Several other Julia packages provide sparse matrix implementations that should b
269305
7. [ExtendableSparse.jl](https://github.com/j-fu/ExtendableSparse.jl) enables fast insertion into sparse matrices using a lazy approach to new stored indices.
270306

271307
8. [Finch.jl](https://github.com/willow-ahrens/Finch.jl) supports extensive multidimensional sparse array formats and operations through a mini tensor language and compiler, all in native Julia. Support for COO, CSF, CSR, CSC and more, as well as operations like broadcast, reduce, etc. and custom operations.
308+
309+
External packages providing sparse direct solvers:
310+
1. [KLU.jl](https://github.com/JuliaSparse/KLU.jl)
311+
2. [Pardiso.jl](https://github.com/JuliaSparse/Pardiso.jl/)
312+
313+
External packages providing solvers for iterative solution of eigensystems and singular value decompositions:
314+
1. [ArnoldiMethods.jl](https://github.com/JuliaLinearAlgebra/ArnoldiMethod.jl)
315+
2. [KrylovKit](https://github.com/Jutho/KrylovKit.jl)
316+
3. [Arpack.jl](https://github.com/JuliaLinearAlgebra/Arpack.jl)
317+
318+
External packages for working with graphs:
319+
1. [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl)

docs/src/solvers.md

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/solvers/cholmod.jl

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ function ssmult(A::Sparse{Tv1, Ti1}, B::Sparse{Tv2, Ti2}, stype::Integer,
795795
A, B = convert.(Sparse{promote_type(Tv1, Tv2), promote_type(Ti1, Ti2)}, (A, B))
796796
return ssmult(A, B, stype, values, sorted)
797797
end
798-
function horzcat(A::Sparse{Tv1, Ti1}, B::Sparse{Tv2, Ti2}, values::Bool) where
798+
function horzcat(A::Sparse{Tv1, Ti1}, B::Sparse{Tv2, Ti2}, values::Bool) where
799799
{Tv1<:VRealTypes, Tv2<:VRealTypes, Ti1, Ti2}
800800
A, B = convert.(Sparse{promote_type(Tv1, Tv2), promote_type(Ti1, Ti2)}, (A, B))
801801
return horzcat(A, B, values)
@@ -809,7 +809,7 @@ function sdmult!(A::Sparse{Tv1, Ti}, transpose::Bool,
809809
A, X = convert(Sparse{Tv3, Ti}, A), convert(Dense{Tv3}, X)
810810
return sdmult!(A, transpose, α, β, X, Y)
811811
end
812-
function vertcat(A::Sparse{Tv1, Ti1}, B::Sparse{Tv2, Ti2}, values::Bool) where
812+
function vertcat(A::Sparse{Tv1, Ti1}, B::Sparse{Tv2, Ti2}, values::Bool) where
813813
{Tv1<:VRealTypes, Ti1, Tv2<:VRealTypes, Ti2}
814814
A, B = convert.(Sparse{promote_type(Tv1, Tv2), promote_type(Ti1, Ti2)}, (A, B))
815815
return vertcat(A, B, values)
@@ -895,7 +895,7 @@ function Dense(A::StridedVecOrMatInclAdjAndTrans)
895895
return Dense{T}(A)
896896
end
897897
# Don't always promote to Float64 now that we have Float32 support.
898-
Dense(A::StridedVecOrMatInclAdjAndTrans{T}) where
898+
Dense(A::StridedVecOrMatInclAdjAndTrans{T}) where
899899
{T<:Union{Float16, ComplexF16, Float32, ComplexF32}} = Dense{promote_type(T, Float32)}(A)
900900

901901

@@ -1055,8 +1055,8 @@ Sparse(A::Hermitian{Tv, SparseMatrixCSC{Tv,Ti}}) where {Tv, Ti} =
10551055
Sparse{promote_type(Tv, Float64), Ti <: ITypes ? Ti : promote_type(Ti, Int)}(
10561056
A.data, A.uplo == 'L' ? -1 : 1
10571057
)
1058-
Sparse(A::Hermitian{Tv, SparseMatrixCSC{Tv,Ti}}) where
1059-
{Tv<:Union{Float16, Float32, ComplexF32, ComplexF16}, Ti} =
1058+
Sparse(A::Hermitian{Tv, SparseMatrixCSC{Tv,Ti}}) where
1059+
{Tv<:Union{Float16, Float32, ComplexF32, ComplexF16}, Ti} =
10601060
Sparse{promote_type(Float32, Tv), Ti <: ITypes ? Ti : promote_type(Ti, Int)}(
10611061
A.data, A.uplo == 'L' ? -1 : 1
10621062
)
@@ -1076,7 +1076,7 @@ function Base.convert(::Type{Sparse{Tnew, Inew}}, A::Sparse{Tv, Ti}) where {Tnew
10761076
a = unsafe_load(typedpointer(A))
10771077
S = allocate_sparse(a.nrow, a.ncol, a.nzmax, Bool(a.sorted), Bool(a.packed), a.stype, Tnew, Inew)
10781078
s = unsafe_load(typedpointer(S))
1079-
1079+
10801080
ap = unsafe_wrap(Array, a.p, (a.ncol + 1,), own = false)
10811081
sp = unsafe_wrap(Array, s.p, (s.ncol + 1,), own = false)
10821082
copyto!(sp, ap)
@@ -1376,7 +1376,7 @@ end
13761376

13771377
## Multiplication
13781378
(*)(A::Sparse, B::Sparse) = ssmult(A, B, 0, true, true)
1379-
(*)(A::Sparse, B::Dense) = sdmult!(A, false, 1., 0., B,
1379+
(*)(A::Sparse, B::Dense) = sdmult!(A, false, 1., 0., B,
13801380
zeros(size(A, 1), size(B, 2), promote_type(eltype(A), eltype(B)))
13811381
)
13821382
(*)(A::Sparse, B::VecOrMat) = (*)(A, Dense(B))
@@ -1413,7 +1413,7 @@ function *(adjA::Adjoint{<:Any,<:Sparse}, B::Sparse)
14131413
end
14141414

14151415
*(adjA::Adjoint{<:Any,<:Sparse}, B::Dense) = (
1416-
A = parent(adjA); sdmult!(A, true, 1., 0., B,
1416+
A = parent(adjA); sdmult!(A, true, 1., 0., B,
14171417
zeros(size(A, 2), size(B, 2), promote_type(eltype(A), eltype(B))))
14181418
)
14191419
*(adjA::Adjoint{<:Any,<:Sparse}, B::VecOrMat) = adjA * Dense(B)
@@ -1423,25 +1423,33 @@ end
14231423

14241424
## Compute that symbolic factorization only
14251425
function symbolic(A::Sparse{<:VTypes, Ti};
1426-
perm::Union{Nothing,AbstractVector{<:Integer}}=nothing,
1427-
postorder::Bool=isnothing(perm)||isempty(perm), userperm_only::Bool=true) where Ti
1426+
perm::Union{Nothing,AbstractVector{<:Integer}}=nothing,
1427+
postorder::Bool=isnothing(perm)||isempty(perm),
1428+
userperm_only::Bool=true,
1429+
nested_dissection::Bool=false) where Ti
14281430

14291431
sA = unsafe_load(pointer(A))
14301432
sA.stype == 0 && throw(ArgumentError("sparse matrix is not symmetric/Hermitian"))
14311433

1432-
@cholmod_param postorder = postorder begin
1433-
if perm === nothing || isempty(perm) # TODO: deprecate empty perm
1434-
return analyze(A)
1435-
else # user permutation provided
1436-
if userperm_only # use perm even if it is worse than AMD
1437-
@cholmod_param nmethods = 1 begin
1434+
# The default is to just use AMD. Use nested dissection only if explicitly asked for.
1435+
# https://github.com/JuliaSparse/SparseArrays.jl/issues/548
1436+
# https://github.com/DrTimothyAldenDavis/SuiteSparse/blob/26ababc7f3af725c5fb9168a1b94850eab74b666/CHOLMOD/Include/cholmod.h#L555-L574
1437+
@cholmod_param nmethods = (nested_dissection ? 0 : 2) begin
1438+
@cholmod_param postorder = postorder begin
1439+
if perm === nothing || isempty(perm) # TODO: deprecate empty perm
1440+
return analyze(A)
1441+
else # user permutation provided
1442+
if userperm_only # use perm even if it is worse than AMD
1443+
@cholmod_param nmethods = 1 begin
1444+
return analyze_p(A, Ti[p-1 for p in perm])
1445+
end
1446+
else
14381447
return analyze_p(A, Ti[p-1 for p in perm])
14391448
end
1440-
else
1441-
return analyze_p(A, Ti[p-1 for p in perm])
14421449
end
14431450
end
14441451
end
1452+
14451453
end
14461454

14471455
function cholesky!(F::Factor{Tv}, A::Sparse{Tv};
@@ -1467,7 +1475,7 @@ See also [`cholesky`](@ref).
14671475
14681476
!!! note
14691477
This method uses the CHOLMOD library from SuiteSparse, which only supports
1470-
real or complex types in single or double precision.
1478+
real or complex types in single or double precision.
14711479
Input matrices not of those element types will
14721480
be converted to these types as appropriate.
14731481
"""
@@ -1587,8 +1595,8 @@ true
15871595
15881596
!!! note
15891597
This method uses the CHOLMOD[^ACM887][^DavisHager2009] library from [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse).
1590-
CHOLMOD only supports real or complex types in single or double precision.
1591-
Input matrices not of those element types will be
1598+
CHOLMOD only supports real or complex types in single or double precision.
1599+
Input matrices not of those element types will be
15921600
converted to these types as appropriate.
15931601
15941602
Many other functions from CHOLMOD are wrapped but not exported from the
@@ -1633,8 +1641,8 @@ have the type tag, it must still be symmetric or Hermitian.
16331641
See also [`ldlt`](@ref).
16341642
16351643
!!! note
1636-
This method uses the CHOLMOD library from [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse),
1637-
which only supports real or complex types in single or double precision.
1644+
This method uses the CHOLMOD library from [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse),
1645+
which only supports real or complex types in single or double precision.
16381646
Input matrices not of those element types will
16391647
be converted to these types as appropriate.
16401648
"""
@@ -1695,7 +1703,7 @@ it should be a permutation of `1:size(A,1)` giving the ordering to use
16951703
16961704
!!! note
16971705
This method uses the CHOLMOD[^ACM887][^DavisHager2009] library from [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse).
1698-
CHOLMOD only supports real or complex types in single or double precision.
1706+
CHOLMOD only supports real or complex types in single or double precision.
16991707
Input matrices not of those element types will
17001708
be converted to these types as appropriate.
17011709
@@ -1767,7 +1775,7 @@ See also [`lowrankupdate!`](@ref), [`lowrankdowndate`](@ref), [`lowrankdowndate!
17671775
"""
17681776
lowrankupdate(F::Factor{Tv}, V::AbstractArray{Tv2}) where {Tv, Tv2} =
17691777
lowrankupdate!(
1770-
change_xdtype(F, promote_type(Tv, Tv2)),
1778+
change_xdtype(F, promote_type(Tv, Tv2)),
17711779
convert(AbstractArray{promote_type(Tv, Tv2)}, V)
17721780
)
17731781

@@ -1782,7 +1790,7 @@ See also [`lowrankdowndate!`](@ref), [`lowrankupdate`](@ref), [`lowrankupdate!`]
17821790
"""
17831791
lowrankdowndate(F::Factor{Tv}, V::AbstractArray{Tv2}) where {Tv, Tv2} =
17841792
lowrankdowndate!(
1785-
change_xdtype(F, promote_type(Tv, Tv2)),
1793+
change_xdtype(F, promote_type(Tv, Tv2)),
17861794
convert(AbstractArray{promote_type(Tv, Tv2)}, V)
17871795
)
17881796

0 commit comments

Comments
 (0)