Skip to content

Commit e8c4cd0

Browse files
committed
Decompression of acyclic coloring with SparseMatrixCSC
1 parent b6f5016 commit e8c4cd0

2 files changed

Lines changed: 65 additions & 24 deletions

File tree

src/decompression.jl

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -514,9 +514,17 @@ function decompress!(
514514
result::TreeSetColoringResult,
515515
uplo::Symbol=:F,
516516
) where {R<:Real}
517-
@compat (; S, color, vertices_by_tree, reverse_bfs_orders,
518-
diagonal_indices, lower_triangle_offsets,
519-
upper_triangle_offsets, buffer) = result
517+
@compat (;
518+
S,
519+
color,
520+
vertices_by_tree,
521+
reverse_bfs_orders,
522+
diagonal_indices,
523+
diagonal_nzind,
524+
lower_triangle_offsets,
525+
upper_triangle_offsets,
526+
buffer,
527+
) = result
520528
nzA = nonzeros(A)
521529
uplo == :F && check_same_pattern(A, S)
522530

@@ -536,31 +544,50 @@ function decompress!(
536544
elseif uplo == :U
537545
for i in diagonal_indices
538546
# A[i, i] is the last element in column i
539-
nzind = A.colptr[i+1] - 1
547+
nzind = A.colptr[i + 1] - 1
540548
nzA[nzind] = B[i, color[i]]
541549
end
542550
else # uplo == :F
543-
for i in diagonal_indices
544-
# A[i, i] is the central element in column i
545-
nzind = (A.colptr[i] + A.colptr[i+1] - 1) ÷ 2
551+
for (k, i) in enumerate(diagonal_indices)
552+
nzind = diagonal_nzind[k]
546553
nzA[nzind] = B[i, color[i]]
547554
end
548555
end
549556

557+
# Index of offsets in lower_triangle_offsets and upper_triangle_offsets
558+
counter = 0
559+
550560
# Recover the off-diagonal coefficients of A
551561
for k in eachindex(vertices_by_tree, reverse_bfs_orders)
552562
for vertex in vertices_by_tree[k]
553563
buffer_right_type[vertex] = zero(R)
554564
end
555565

556566
for (i, j) in reverse_bfs_orders[k]
567+
counter += 1
557568
val = B[i, color[j]] - buffer_right_type[i]
558569
buffer_right_type[j] = buffer_right_type[j] + val
570+
571+
# A[i,j] = val
559572
if in_triangle(i, j, uplo)
560-
A[i, j] = val
573+
if uplo == :L
574+
nzind = A.colptr[j + 1] - lower_triangle_offsets[counter]
575+
else
576+
nzind = A.colptr[j] + upper_triangle_offsets[counter]
577+
end
578+
# Both values of `nzind` can be used if uplo = :F
579+
nzA[nzind] = val
561580
end
581+
582+
# A[j,i] = val
562583
if in_triangle(j, i, uplo)
563-
A[j, i] = val
584+
if uplo == :L
585+
nzind = A.colptr[i + 1] - lower_triangle_offsets[counter]
586+
else
587+
nzind = A.colptr[i] + upper_triangle_offsets[counter]
588+
end
589+
# Both values of `nzind` can be used if uplo = :F
590+
nzA[nzind] = val
564591
end
565592
end
566593
end

src/result.jl

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ struct TreeSetColoringResult{M,R} <:
228228
vertices_by_tree::Vector{Vector{Int}}
229229
reverse_bfs_orders::Vector{Vector{Tuple{Int,Int}}}
230230
diagonal_indices::Vector{Int}
231+
diagonal_nzind::Vector{Int}
231232
lower_triangle_offsets::Vector{Int}
232233
upper_triangle_offsets::Vector{Int}
233234
buffer::Vector{R}
@@ -241,6 +242,7 @@ function TreeSetColoringResult(
241242

242243
# Vector for the decompression of the diagonal coefficients
243244
diagonal_indices = Int[]
245+
diagonal_nzind = Int[]
244246
ndiag = 0
245247

246248
n = size(S, 1)
@@ -250,6 +252,7 @@ function TreeSetColoringResult(
250252
i = rv[k]
251253
if i == j
252254
push!(diagonal_indices, i)
255+
push!(diagonal_nzind, k)
253256
ndiag += 1
254257
end
255258
end
@@ -366,27 +369,30 @@ function TreeSetColoringResult(
366369
end
367370

368371
# Update lower_triangle_offsets and upper_triangle_offsets
369-
index_offsets += 1
370372
i = leaf
371373
j = neighbor
374+
col_i = view(rv, nzrange(S, i))
375+
col_j = view(rv, nzrange(S, j))
376+
index_ij = S.colptr[j] - 1 + searchsortedfirst(col_j, i) # S.nzval[index_ij] = S[i,j]
377+
index_ji = S.colptr[i] - 1 + searchsortedfirst(col_i, j) # S.nzval[index_ji] = S[j,i]
378+
index_offsets += 1
379+
372380
if in_triangle(i, j, :L)
373381
# uplo = :L or uplo = :F
374-
# A[i,j] is stored at the index (A.colptr[j+1] - offset_L) in A.nzval
375-
# offset_L = ...
376-
# lower_triangle_offsets[index_offsets] = S.colptr[j+1] - offset_L
382+
# A[i,j] is stored at index_ij = (A.colptr[j+1] - offset_L) in A.nzval
383+
lower_triangle_offsets[index_offsets] = S.colptr[j + 1] - index_ij
384+
377385
# uplo = :U or uplo = :F
378-
# A[j,i] is stored at the index (A.colptr[i] + offset_U) in A.nzval
379-
# offset_U = ...
380-
# upper_triangle_offsets[index_offsets] = S.colptr[i] + offset_U
386+
# A[j,i] is stored at index_ji = (A.colptr[i] + offset_U) in A.nzval
387+
upper_triangle_offsets[index_offsets] = index_ji - S.colptr[i]
381388
else
382389
# uplo = :L or uplo = :F
383-
# A[j,i] is stored at the index (A.colptr[i+1] - offset_L) in A.nzval
384-
# offset_L = ...
385-
# lower_triangle_offsets[index_offsets] = S.colptr[i+1] - offset_L
390+
# A[j,i] is stored at index_ji = (A.colptr[i+1] - offset_L) in A.nzval
391+
lower_triangle_offsets[index_offsets] = S.colptr[i + 1] - index_ji
392+
386393
# uplo = :U or uplo = :F
387-
# A[i,j] is stored at the index (A.colptr[j] + offset) in A.nzval
388-
# offset_U = ...
389-
# upper_triangle_offsets[index_offsets] = S.colptr[j] + offset_U
394+
# A[i,j] is stored at index_ij = (A.colptr[j] + offset_U) in A.nzval
395+
upper_triangle_offsets[index_offsets] = index_ij - S.colptr[j]
390396
end
391397
end
392398
end
@@ -398,8 +404,16 @@ function TreeSetColoringResult(
398404
buffer = Vector{R}(undef, nvertices)
399405

400406
return TreeSetColoringResult(
401-
S, color, group, vertices_by_tree, reverse_bfs_orders,
402-
diagonal_indices, lower_triangle_offsets, upper_triangle_offsets, buffer
407+
S,
408+
color,
409+
group,
410+
vertices_by_tree,
411+
reverse_bfs_orders,
412+
diagonal_indices,
413+
diagonal_nzind,
414+
lower_triangle_offsets,
415+
upper_triangle_offsets,
416+
buffer,
403417
)
404418
end
405419

0 commit comments

Comments
 (0)