Skip to content

Commit ac3da1a

Browse files
authored
Fix type conversion for weird orders (#226)
* Fix type conversion for weird orders * Fix * Add tests
1 parent 2ab1c47 commit ac3da1a

4 files changed

Lines changed: 70 additions & 26 deletions

File tree

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "SparseMatrixColorings"
22
uuid = "0a514795-09f3-496d-8182-132a7b665d35"
33
authors = ["Guillaume Dalle", "Alexis Montoison"]
4-
version = "0.4.15"
4+
version = "0.4.16"
55

66
[deps]
77
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"

src/order.jl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,17 @@ struct DegreeBuckets{T}
137137
positions::Vector{T}
138138
end
139139

140-
function DegreeBuckets(::Type{T}, degrees::Vector{<:Integer}, dmax::Integer) where {T}
140+
function DegreeBuckets(::Type{T}, degrees::Vector{T}, dmax::Integer) where {T}
141141
# number of vertices per degree class
142142
deg_count = zeros(T, dmax + 1)
143143
for d in degrees
144144
deg_count[d + 1] += 1
145145
end
146146
# bucket limits
147-
bucket_high = cumsum(deg_count)
148-
bucket_low = vcat(zero(T), @view(bucket_high[1:(end - 1)]))
149-
bucket_low .+= 1
147+
bucket_high = accumulate(+, deg_count)
148+
bucket_low = similar(bucket_high)
149+
bucket_low[1] = 1
150+
bucket_low[2:end] .= @view(bucket_high[1:(end - 1)]) .+ 1
150151
# assign each vertex to the correct position inside its degree class
151152
bucket_storage = similar(degrees, T)
152153
positions = similar(degrees, T)
@@ -253,7 +254,7 @@ function vertices(
253254
if degree_increasing(; degtype, direction)
254255
degrees = zeros(T, nb_vertices(g))
255256
else
256-
degrees = [degree(g, v) for v in vertices(g)]
257+
degrees = T[degree(g, v) for v in vertices(g)]
257258
end
258259
db = DegreeBuckets(T, degrees, maximum_degree(g))
259260
π = T[]
@@ -378,3 +379,14 @@ The `elimination_algorithm` must be an instance of `CliqueTrees.EliminationAlgor
378379
struct PerfectEliminationOrder{E} <: AbstractOrder
379380
elimination_algorithm::E
380381
end
382+
383+
function all_orders()
384+
return [
385+
NaturalOrder(),
386+
RandomOrder(),
387+
LargestFirst(),
388+
SmallestLast(),
389+
IncidenceDegree(),
390+
DynamicLargestFirst(),
391+
]
392+
end

test/allocations.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,33 @@ end
132132
test_noallocs_structured_decompression(1000; structure, partition, decompression)
133133
end
134134
end
135+
136+
@testset "Single precision" begin
137+
n, p = 10_000, 0.001
138+
A64 = sparse(Symmetric(sprand(rng, Float32, 100, 100, 0.1)))
139+
A32 = convert(SparseMatrixCSC{Float32,Int32}, A64)
140+
@testset "$structure - $partition - $decompression" for (
141+
structure, partition, decompression
142+
) in [
143+
(:nonsymmetric, :column, :direct),
144+
(:nonsymmetric, :row, :direct),
145+
(:symmetric, :column, :direct),
146+
(:symmetric, :column, :substitution),
147+
(:nonsymmetric, :bidirectional, :direct),
148+
(:nonsymmetric, :bidirectional, :substitution),
149+
]
150+
@testset for order in
151+
(NaturalOrder(), RandomOrder(), LargestFirst(), DynamicLargestFirst())
152+
problem = ColoringProblem(; structure, partition)
153+
algo = GreedyColoringAlgorithm(order; decompression)
154+
b64 = @b fast_coloring(A64, problem, algo)
155+
b32 = @b fast_coloring(A32, problem, algo)
156+
# check that we allocate no more than 50% + epsilon with Int32
157+
if decompression == :direct
158+
@test b32.bytes < 0.6 * b64.bytes
159+
else
160+
@test_broken b32.bytes < 0.6 * b64.bytes
161+
end
162+
end
163+
end
164+
end;

test/type_stability.jl

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ using JET
33
using LinearAlgebra
44
using SparseArrays
55
using SparseMatrixColorings
6-
using SparseMatrixColorings: matrix_versions, respectful_similar
6+
using SparseMatrixColorings: matrix_versions, respectful_similar, all_orders
77
using StableRNGs
88
using Test
99

@@ -178,25 +178,27 @@ end;
178178
(:nonsymmetric, :bidirectional, :direct),
179179
(:nonsymmetric, :bidirectional, :substitution),
180180
]
181-
result = coloring(
182-
A,
183-
ColoringProblem(; structure, partition),
184-
GreedyColoringAlgorithm(; decompression);
185-
)
186-
if partition in (:column, :bidirectional)
187-
@test eltype(column_colors(result)) == Int32
188-
@test eltype(column_groups(result)[1]) == Int32
189-
end
190-
if partition in (:row, :bidirectional)
191-
@test eltype(row_colors(result)) == Int32
192-
@test eltype(row_groups(result)[1]) == Int32
193-
end
194-
if partition == :bidirectional
195-
Br, Bc = compress(A, result)
196-
@test decompress(Br, Bc, result) isa SparseMatrixCSC{Float32,Int32}
197-
else
198-
B = compress(A, result)
199-
@test decompress(B, result) isa SparseMatrixCSC{Float32,Int32}
181+
@testset for order in all_orders()
182+
result = coloring(
183+
A,
184+
ColoringProblem(; structure, partition),
185+
GreedyColoringAlgorithm(order; decompression);
186+
)
187+
if partition in (:column, :bidirectional)
188+
@test eltype(column_colors(result)) == Int32
189+
@test eltype(column_groups(result)[1]) == Int32
190+
end
191+
if partition in (:row, :bidirectional)
192+
@test eltype(row_colors(result)) == Int32
193+
@test eltype(row_groups(result)[1]) == Int32
194+
end
195+
if partition == :bidirectional
196+
Br, Bc = compress(A, result)
197+
@test decompress(Br, Bc, result) isa SparseMatrixCSC{Float32,Int32}
198+
else
199+
B = compress(A, result)
200+
@test decompress(B, result) isa SparseMatrixCSC{Float32,Int32}
201+
end
200202
end
201203
end
202204
end

0 commit comments

Comments
 (0)