Skip to content

Commit 563a06c

Browse files
authored
[CUSPARSE] Interface color reordering (#1794)
1 parent 15dbba8 commit 563a06c

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

lib/cusparse/CUSPARSE.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ include("level2.jl")
3737
include("level3.jl")
3838
include("extra.jl")
3939
include("preconditioners.jl")
40+
include("reorderings.jl")
4041
include("conversions.jl")
4142
include("generic.jl")
4243

lib/cusparse/reorderings.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# routines that implement reorderings
2+
3+
export color
4+
5+
"""
6+
color(A::CuSparseMatrixCSC, index::SparseChar; percentage::Number=1.0)
7+
color(A::CuSparseMatrixCSR, index::SparseChar; percentage::Number=1.0)
8+
9+
This function performs the coloring of the adjacency graph associated with the matrix A.
10+
The coloring is an assignment of colors (integer numbers) to nodes, such that neighboring nodes have distinct colors.
11+
An approximate coloring algorithm is used in this routine, and is stopped when a certain percentage of nodes has been colored.
12+
The rest of the nodes are assigned distinct colors (an increasing sequence of integers numbers, starting from the last integer used previously).
13+
The reordering is such that nodes that have been assigned the same color are reordered to be next to each other.
14+
15+
The matrix A passed to this routine, must be stored as a general matrix and have a symmetric sparsity pattern.
16+
If the matrix is non-symmetric the user should pass A + Aᵀ as a parameter to this routine.
17+
"""
18+
function color end
19+
20+
for (fname, subty, elty) in ((:cusparseScsrcolor, :Float32, :Float32),
21+
(:cusparseDcsrcolor, :Float64, :Float64),
22+
(:cusparseCcsrcolor, :Float32, :ComplexF32),
23+
(:cusparseZcsrcolor, :Float64, :ComplexF64))
24+
@eval begin
25+
function color(A::Union{CuSparseMatrixCSR{$elty},CuSparseMatrixCSC{$elty}}, index::SparseChar; percentage::Number=1.0)
26+
desc = CuMatrixDescriptor('G', 'L', 'N', index)
27+
m, n = size(A)
28+
(m != n) && throw(DimensionMismatch("A must be square, but has dimensions ($m,$n)!"))
29+
30+
info = cusparseColorInfo_t[0]
31+
cusparseCreateColorInfo(info)
32+
33+
ncolors = Ref{Cint}(-1)
34+
coloring = CuVector{Cint}(undef, m)
35+
reordering = CuVector{Cint}(undef, m)
36+
37+
if isa(A, CuSparseMatrixCSR)
38+
$fname(handle(), m, nnz(A), desc, nonzeros(A), A.rowPtr, A.colVal, Ref{$subty}(percentage), ncolors, coloring, reordering, info[1])
39+
else
40+
$fname(handle(), m, nnz(A), desc, nonzeros(A), A.colPtr, A.rowVal, Ref{$subty}(percentage), ncolors, coloring, reordering, info[1])
41+
end
42+
cusparseDestroyColorInfo(info[1])
43+
ncolors[], coloring, reordering
44+
end
45+
end
46+
end

test/cusparse.jl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,3 +930,45 @@ end
930930
end
931931
end
932932
end
933+
934+
for SparseMatrixType in [CuSparseMatrixCSC, CuSparseMatrixCSR]
935+
@testset "$SparseMatrixType -- color" begin
936+
@testset "color $T" for T in [Float32, Float64, ComplexF32, ComplexF64]
937+
A = sprand(T, 50, 50, 0.03)
938+
A = A + A'
939+
dA = SparseMatrixType(A)
940+
ncolors, coloring, reordering = color(dA, 'O')
941+
@test 1 ncolors 50
942+
@test maximum(coloring) == ncolors
943+
@test minimum(reordering) == 1
944+
@test maximum(reordering) == 50
945+
@test CUDA.@allowscalar isperm(reordering)
946+
end
947+
948+
# The routine color returns the wrong result with small sparse matrices.
949+
# NVIDIA investigates the issue.
950+
if false
951+
A = [ 1 1 0 0 0 ;
952+
1 1 1 1 0 ;
953+
0 1 1 0 1 ;
954+
0 1 0 1 0 ;
955+
0 0 1 0 1 ]
956+
A = sparse(A)
957+
# The adjacency graph of A has at least two colors, one color for
958+
# {1, 3, 4} and another one for {2, 5}.
959+
@testset "5x5 example -- color $T" for T in [Float32, Float64, ComplexF32, ComplexF64]
960+
dA = SparseMatrixType{T}(A)
961+
ncolors, coloring, reordering = color(dA, 'O')
962+
@test ncolors == 2
963+
@test minimum(reordering) == 1
964+
@test maximum(reordering) == 5
965+
CUDA.allowscalar() do
966+
@test isperm(reordering)
967+
@test coloring[1] == coloring[3] == coloring[4]
968+
@test coloring[2] == coloring[5]
969+
@test coloring[1] != coloring[2]
970+
end
971+
end
972+
end
973+
end
974+
end

0 commit comments

Comments
 (0)