Skip to content

Commit e20b4dc

Browse files
authored
Fix star decompression into SparseMatrixCSC triangle (#90)
* Fix star decompression into `SparseMatrixCSC` triangle * Test with `triu` * Fix * Check that if I remove l tests fail * Document * Add assertion * Precise error * Test throws * Revert to assert
1 parent df4bc6a commit e20b4dc

File tree

4 files changed

+21
-16
lines changed

4 files changed

+21
-16
lines changed

src/decompression.jl

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,14 @@ end
130130
Decompress `B` in-place into `A`, given a coloring `result` of the sparsity pattern of `A`.
131131
The out-of-place alternative is [`decompress`](@ref).
132132
133+
!!! note
134+
In-place decompression is faster when `A isa SparseMatrixCSC`.
135+
133136
Compression means summing either the columns or the rows of `A` which share the same color.
134137
It is done by calling [`compress`](@ref).
135138
136139
For `:symmetric` coloring results (and for those only), an optional positional argument `uplo in (:U, :L, :F)` can be passed to specify which part of the matrix `A` should be updated: the Upper triangle, the Lower triangle, or the Full matrix.
137-
138-
!!! note
139-
In-place decompression is faster when `A isa SparseMatrixCSC`.
140+
When `A isa SparseMatrixCSC`, using the `uplo` argument requires a target matrix which only stores the relevant triangle(s).
140141
141142
# Example
142143
@@ -197,11 +198,12 @@ Decompress the vector `b` corresponding to color `c` in-place into `A`, given a
197198
- If `result` comes from a `:nonsymmetric` structure with `:row` partition, this will update the rows of `A` that share color `c` (whose sum makes up `b`).
198199
- If `result` comes from a `:symmetric` structure with `:column` partition, this will update the coefficients of `A` whose value is deduced from color `c`.
199200
200-
For `:symmetric` coloring results (and for those only), an optional positional argument `uplo in (:U, :L, :F)` can be passed to specify which part of the matrix `A` should be updated: the Upper triangle, the Lower triangle, or the Full matrix.
201-
202201
!!! warning
203202
This function will only update some coefficients of `A`, without resetting the rest to zero.
204203
204+
For `:symmetric` coloring results (and for those only), an optional positional argument `uplo in (:U, :L, :F)` can be passed to specify which part of the matrix `A` should be updated: the Upper triangle, the Lower triangle, or the Full matrix.
205+
When `A isa SparseMatrixCSC`, using the `uplo` argument requires a target matrix which only stores the relevant triangle(s).
206+
205207
# Example
206208
207209
```jldoctest
@@ -448,16 +450,19 @@ function decompress!(
448450
) where {R<:Real}
449451
@compat (; S, compressed_indices) = result
450452
uplo == :F && check_same_pattern(A, S)
451-
rvA = rowvals(A)
453+
rvS = rowvals(S)
452454
nzA = nonzeros(A)
455+
l = 0 # assume A has the same pattern as the triangle
453456
for j in axes(S, 2)
454457
for k in nzrange(S, j)
455-
i = rvA[k]
458+
i = rvS[k]
456459
if in_triangle(i, j, uplo)
457-
nzA[k] = B[compressed_indices[k]]
460+
l += 1
461+
nzA[l] = B[compressed_indices[k]]
458462
end
459463
end
460464
end
465+
@assert l == length(nonzeros(A))
461466
return A
462467
end
463468

test/allocations.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function test_noallocs_decompression(
5454
end
5555
@testset "Triangle decompression" begin
5656
if structure == :symmetric
57-
bench1_triangle = @be similar(A) decompress!(_, B, result, :U) evals = 1
57+
bench1_triangle = @be similar(triu(A)) decompress!(_, B, result, :U) evals = 1
5858
bench2_triangle = @be similar(Matrix(A)) decompress!(_, B, result, :U) evals = 1
5959
@test minimum(bench1_triangle).allocs == 0
6060
@test minimum(bench2_triangle).allocs == 0
@@ -63,7 +63,7 @@ function test_noallocs_decompression(
6363
@testset "Single-color triangle decompression" begin
6464
if structure == :symmetric && decompression == :direct
6565
b = B[:, 1]
66-
bench1_singlecolor_triangle = @be similar(A) decompress_single_color!(
66+
bench1_singlecolor_triangle = @be similar(triu(A)) decompress_single_color!(
6767
_, b, 1, result, :U
6868
) evals = 1
6969
bench2_singlecolor_triangle = @be similar(Matrix(A)) decompress_single_color!(

test/type_stability.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ end
7979
end
8080
@testset "Triangle decompression" begin
8181
if structure == :symmetric
82-
@test_opt decompress!(respectful_similar(A), B, result, :U)
82+
@test_opt decompress!(respectful_similar(triu(A)), B, result, :U)
8383
end
8484
end
8585
@testset "Single-color triangle decompression" begin
8686
if structure == :symmetric && decompression == :direct
8787
@test_opt decompress_single_color!(
88-
respectful_similar(A), B[:, 1], 1, result, :U
88+
respectful_similar(triu(A)), B[:, 1], 1, result, :U
8989
)
9090
end
9191
end

test/utils.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ function test_coloring_decompression(
5151

5252
@testset "Triangle decompression" begin
5353
if structure == :symmetric
54-
A3upper = respectful_similar(A)
55-
A3lower = respectful_similar(A)
54+
A3upper = respectful_similar(triu(A))
55+
A3lower = respectful_similar(tril(A))
5656
A3both = respectful_similar(A)
5757
A3upper .= zero(eltype(A))
5858
A3lower .= zero(eltype(A))
@@ -70,8 +70,8 @@ function test_coloring_decompression(
7070

7171
@testset "Single-color triangle decompression" begin
7272
if structure == :symmetric && decompression == :direct
73-
A4upper = respectful_similar(A)
74-
A4lower = respectful_similar(A)
73+
A4upper = respectful_similar(triu(A))
74+
A4lower = respectful_similar(tril(A))
7575
A4both = respectful_similar(A)
7676
A4upper .= zero(eltype(A))
7777
A4lower .= zero(eltype(A))

0 commit comments

Comments
 (0)