Skip to content

Commit 0a1c886

Browse files
authored
Merge pull request #571 from JuliaSparse/backports-release-1.11
Backports to v1.11.2
2 parents cb602d7 + 298f5e1 commit 0a1c886

File tree

15 files changed

+146
-115
lines changed

15 files changed

+146
-115
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,26 @@ jobs:
2323
fail-fast: false
2424
matrix:
2525
version:
26-
- 'nightly'
26+
- '1.11'
2727
os:
2828
- ubuntu-latest
29-
- macOS-latest
3029
- windows-latest
3130
arch:
3231
- x64
33-
- x86
34-
exclude:
32+
include:
3533
- os: macOS-latest
34+
arch: aarch64
35+
version: '1.11'
36+
- os: ubuntu-latest
3637
arch: x86
38+
version: '1.11'
3739
steps:
3840
- uses: actions/checkout@v4
39-
- uses: julia-actions/setup-julia@v1
41+
- uses: julia-actions/setup-julia@latest
4042
with:
4143
version: ${{ matrix.version }}
4244
arch: ${{ matrix.arch }}
43-
- uses: actions/cache@v4
44-
env:
45-
cache-name: cache-artifacts
46-
with:
47-
path: ~/.julia/artifacts
48-
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
49-
restore-keys: |
50-
${{ runner.os }}-test-${{ env.cache-name }}-
51-
${{ runner.os }}-test-${{ matrix.os }}
52-
${{ runner.os }}-
45+
- uses: julia-actions/cache@v2
5346
- run: julia --color=yes .ci/test_and_change_uuid.jl
5447
- uses: julia-actions/julia-buildpkg@v1
5548
- uses: julia-actions/julia-runtest@v1
@@ -67,8 +60,7 @@ jobs:
6760
- uses: actions/checkout@v4
6861
- uses: julia-actions/setup-julia@latest
6962
with:
70-
# version: '1.6'
71-
version: 'nightly'
63+
version: '1.11'
7264
- name: Generate docs
7365
run: |
7466
julia --color=yes -e 'write("Project.toml", replace(read("Project.toml", String), r"uuid = .*?\n" =>"uuid = \"3f01184e-e22b-5df5-ae63-d93ebab69eaf\"\n"));'

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: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,27 @@ 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)
225+
226+
```@meta
227+
DocTestSetup = nothing
228+
```
229+
209230
# [SparseArrays API](@id stdlib-sparse-arrays)
210231

211232
```@docs
@@ -245,6 +266,26 @@ SparseArrays.ftranspose!
245266
```@meta
246267
DocTestSetup = nothing
247268
```
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+
248289
# Noteworthy External Sparse Packages
249290

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

266307
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 & 44 deletions
This file was deleted.

src/linalg.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ for op ∈ (:+, :-)
4747
end
4848
end
4949

50-
generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion2, B::DenseMatrixUnion, _add::MulAddMul) =
50+
@inline generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion2, B::DenseMatrixUnion, _add::MulAddMul) =
5151
spdensemul!(C, tA, tB, A, B, _add)
52-
generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion2, B::AbstractTriangular, _add::MulAddMul) =
52+
@inline generic_matmatmul!(C::StridedMatrix, tA, tB, A::SparseMatrixCSCUnion2, B::AbstractTriangular, _add::MulAddMul) =
5353
spdensemul!(C, tA, tB, A, B, _add)
54-
generic_matvecmul!(C::StridedVecOrMat, tA, A::SparseMatrixCSCUnion2, B::DenseInputVector, _add::MulAddMul) =
54+
@inline generic_matvecmul!(C::StridedVecOrMat, tA, A::SparseMatrixCSCUnion2, B::DenseInputVector, _add::MulAddMul) =
5555
spdensemul!(C, tA, 'N', A, B, _add)
5656

5757
Base.@constprop :aggressive function spdensemul!(C, tA, tB, A, B, _add)

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

src/solvers/spqr.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Matrix{T}(Q::QRSparseQ) where {T} = lmul!(Q, Matrix{T}(I, size(Q, 1), min(size(Q
146146

147147
# From SPQR manual p. 6
148148
_default_tol(A::AbstractSparseMatrixCSC) =
149-
20*sum(size(A))*eps(real(eltype(A)))*maximum(norm(view(A, :, i)) for i in 1:size(A, 2))
149+
20*sum(size(A))*eps()*maximum(norm(view(A, :, i)) for i in 1:size(A, 2))
150150

151151
"""
152152
qr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparse

src/sparsematrix.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,12 @@ SparseMatrixCSC(m, n, colptr::ReadOnly, rowval::ReadOnly, nzval::Vector) =
4949

5050
"""
5151
SparseMatrixCSC{Tv,Ti}(::UndefInitializer, m::Integer, n::Integer)
52+
SparseMatrixCSC{Tv,Ti}(::UndefInitializer, (m,n)::NTuple{2,Integer})
5253
5354
Creates an empty sparse matrix with element type `Tv` and integer type `Ti` of size `m × n`.
5455
"""
5556
SparseMatrixCSC{Tv,Ti}(::UndefInitializer, m::Integer, n::Integer) where {Tv, Ti} = spzeros(Tv, Ti, m, n)
57+
SparseMatrixCSC{Tv,Ti}(::UndefInitializer, mn::NTuple{2,Integer}) where {Tv, Ti} = spzeros(Tv, Ti, mn...)
5658

5759
"""
5860
FixedSparseCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}

0 commit comments

Comments
 (0)