Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 29 additions & 18 deletions src/decompression.jl
Original file line number Diff line number Diff line change
Expand Up @@ -502,13 +502,30 @@ function decompress_single_color!(
return A
end

function decompress!(
A::SparseMatrixCSC, B::AbstractMatrix, result::StarSetColoringResult, uplo::Symbol=:F
"""
decompress_csc!(
nzA::AbstractVector,
A_colptr::AbstractVector{<:Integer},
B::AbstractMatrix,
result::Union{StarSetColoringResult,TreeSetColoringResult},
uplo::Symbol=:F,
)

Decompress the values of `B` into the vector of nonzero entries `nzA` of a
sparse matrix with column pointers `A_colptr`, without constructing the matrix.
The destination pattern must match the full coloring pattern (`uplo=:F`), its
lower triangle (`uplo=:L`), or its upper triangle (`uplo=:U`), with row indices
sorted in increasing order within each column. Return `nothing`.
"""
function decompress_csc!(
nzA::AbstractVector,
A_colptr::AbstractVector{<:Integer},
B::AbstractMatrix,
result::StarSetColoringResult,
uplo::Symbol=:F,
)
(; ag, compressed_indices) = result
(; S) = ag
nzA = nonzeros(A)
check_compatible_pattern(A, ag, uplo)
if uplo == :F
for k in eachindex(nzA, compressed_indices)
nzA[k] = B[compressed_indices[k]]
Expand All @@ -526,6 +543,14 @@ function decompress!(
end
end
end
return nothing
end

function decompress!(
A::SparseMatrixCSC, B::AbstractMatrix, result::StarSetColoringResult, uplo::Symbol=:F
)
check_compatible_pattern(A, result.ag, uplo)
decompress_csc!(nonzeros(A), A.colptr, B, result, uplo)
return A
end

Expand Down Expand Up @@ -585,20 +610,6 @@ function decompress!(
return A
end

"""
decompress_csc!(
nzA::AbstractVector{R},
A_colptr::AbstractVector,
B::AbstractMatrix{R},
result::TreeSetColoringResult,
uplo::Symbol=:F,
) where {R<:Real}

Decompress the values of `B` into the vector of nonzero entries `nzA` of a
sparse matrix with column pointers `colptr`. This function assumes that the
row indices are sorted in increasing order and are the same as those of the
sparse matrix given to the `coloring` function that returned `result`.
"""
function decompress_csc!(
nzA::AbstractVector{R},
A_colptr::AbstractVector{<:Integer},
Expand Down
78 changes: 78 additions & 0 deletions test/decompression.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using LinearAlgebra
using SparseArrays
using SparseMatrixColorings
using SparseMatrixColorings: decompress_csc!
using Test

function test_star_csc_decompression(T, Ti, order, postprocessing)
problem = ColoringProblem(; structure=:symmetric, partition=:column)
algorithm = GreedyColoringAlgorithm(order; decompression=:direct, postprocessing)
@testset "edges = $edges" for edges in (
[(2, 4), (4, 7), (7, 9)],
[(2, 4), (2, 7), (2, 9), (7, 7)],
[(2, 4), (4, 7), (7, 9), (2, 9), (4, 4), (9, 9)],
[(2, 2), (9, 9)],
Tuple{Int,Int}[],
)
A = spzeros(T, Ti, 9, 9)
for (i, j) in edges
A[i, j] = A[j, i] = T <: Complex ? T(10i + j, i - j) : T(10i + j)
end
# Keep a structural zero as well as empty rows and columns.
if !isempty(edges)
A[5, 5] = one(T)
A[5, 5] = zero(T)
end
result = coloring(A, problem, algorithm)
B = compress(A, result)
@testset "$uplo" for uplo in (:F, :L, :U)
expected = if uplo == :F
A
elseif uplo == :L
tril(A)
else
triu(A)
end
V = fill(T(NaN), nnz(expected))
@test decompress_csc!(V, expected.colptr, B, result, uplo) === nothing
@test V == nonzeros(expected)
@test (@allocated decompress_csc!(V, expected.colptr, B, result, uplo)) == 0

dest = copy(expected)
fill!(nonzeros(dest), T(NaN))
@test decompress!(dest, B, result, uplo) === dest
@test dest == expected
@test (@allocated decompress!(dest, B, result, uplo)) == 0

# Abstract buffers and a different destination eltype remain supported.
storage = fill(ComplexF64(NaN), 2nnz(expected))
values = @view storage[1:2:end]
compressed = @view B[:, :]
@test decompress_csc!(values, expected.colptr, compressed, result, uplo) ===
nothing
@test values == nonzeros(expected)
@test (@allocated decompress_csc!(
values, expected.colptr, compressed, result, uplo
)) == 0
mixed = SparseMatrixCSC{ComplexF64,Ti}(expected)
fill!(nonzeros(mixed), ComplexF64(NaN))
@test decompress!(mixed, compressed, result, uplo) === mixed
@test mixed == expected
end
full_values = similar(nonzeros(A))
@test decompress_csc!(full_values, A.colptr, B, result) === nothing
@test full_values == nonzeros(A)
end
return nothing
end

@testset "Star CSC decompression" begin
@testset "$T, $Ti, $order, postprocessing=$postprocessing" for T in (
Float32, Float64, ComplexF64
),
Ti in (Int32, Int64), order in (NaturalOrder(), LargestFirst()),
postprocessing in (false, true)

test_star_csc_decompression(T, Ti, order, postprocessing)
end
end
3 changes: 3 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ using Colors: Colors
end
end
@testset verbose = true "Correctness" begin
@testset "CSC decompression" begin
include("decompression.jl")
end
@testset "Small instances" begin
include("small.jl")
end
Expand Down
Loading