Skip to content

Fix coloring with empty matrix as input#300

Open
blegat wants to merge 6 commits intogdalle:mainfrom
blegat:empty_coloring
Open

Fix coloring with empty matrix as input#300
blegat wants to merge 6 commits intogdalle:mainfrom
blegat:empty_coloring

Conversation

@blegat
Copy link
Contributor

@blegat blegat commented Jan 19, 2026

The change to _coloring fixes the following error:

julia> problem = ColoringProblem(; structure = :symmetric, partition = :column)
ColoringProblem{:symmetric, :column}()

julia> algo = GreedyColoringAlgorithm(; decompression = :substitution)
GreedyColoringAlgorithm{:substitution, 1, Tuple{NaturalOrder}}((NaturalOrder(),), false)

julia> S = spzeros(Int, 0, 0)
0×0 SparseMatrixCSC{Int64, Int64} with 0 stored entries

julia> coloring(S, problem, algo)
ERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Stacktrace:
  [1] _empty_reduce_error()
    @ Base ./reduce.jl:311
  [2] reduce_empty(f::Function, T::Type)
    @ Base ./reduce.jl:312
  [3] mapreduce_empty(::typeof(identity), op::Function, T::Type)
    @ Base ./reduce.jl:361
  [4] reduce_empty(op::Base.MappingRF{typeof(identity), typeof(max)}, ::Type{Int64})
    @ Base ./reduce.jl:350
  [5] reduce_empty_iter
    @ ./reduce.jl:373 [inlined]
  [6] mapreduce_empty_iter(f::Function, op::Function, itr::Vector{Int64}, ItrEltype::Base.HasEltype)
    @ Base ./reduce.jl:369
  [7] _mapreduce
    @ ./reduce.jl:421 [inlined]
  [8] _mapreduce_dim
    @ ./reducedim.jl:334 [inlined]
  [9] mapreduce
    @ ./reducedim.jl:326 [inlined]
 [10] _maximum
    @ ./reducedim.jl:984 [inlined]
 [11] _maximum
    @ ./reducedim.jl:983 [inlined]
 [12] maximum
    @ ./reducedim.jl:979 [inlined]
 [13] call_composed
    @ ./operators.jl:1099 [inlined]
 [14] ComposedFunction
    @ ./operators.jl:1096 [inlined]
 [15] #argmin##0
    @ ./reduce.jl:1020 [inlined]
 [16] MappingRF
    @ ./reduce.jl:92 [inlined]
 [17] afoldl
    @ ./operators.jl:599 [inlined]
 [18] _foldl_impl
    @ ./reduce.jl:60 [inlined]
 [19] foldl_impl
    @ ./reduce.jl:40 [inlined]
 [20] mapfoldl_impl
    @ ./reduce.jl:36 [inlined]
 [21] mapfoldl
    @ ./reduce.jl:167 [inlined]
 [22] argmin
    @ ./reduce.jl:1020 [inlined]
 [23] _coloring(speed_setting::SparseMatrixColorings.WithResult, A::SparseMatrixCSC{…}, ::ColoringProblem{…}, algo::GreedyColoringAlgorithm{…}, decompression_eltype::Type{…}, symmetric_pattern::Bool)
    @ SparseMatrixColorings ~/.julia/dev/SparseMatrixColorings/src/interface.jl:311
 [24] #coloring#28
    @ ~/.julia/dev/SparseMatrixColorings/src/interface.jl:196 [inlined]
 [25] coloring(A::SparseMatrixCSC{…}, problem::ColoringProblem{…}, algo::GreedyColoringAlgorithm{…})
    @ SparseMatrixColorings ~/.julia/dev/SparseMatrixColorings/src/interface.jl:189
 [26] top-level scope
    @ REPL[22]:1
Some type information was truncated. Use `show(err)` to see complete types.

After this, we have the following error that is fixed by the change in group_by_color:

julia> coloring(S, problem, algo)
ERROR: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Stacktrace:
  [1] _empty_reduce_error()
    @ Base ./reduce.jl:311
  [2] mapreduce_empty(f::Function, op::Function, T::Type)
    @ Base ./reduce.jl:313
  [3] reduce_empty(op::Base.MappingRF{Base.ExtremaMap{typeof(identity)}, typeof(Base._extrema_rf)}, ::Type{Int64})
    @ Base ./reduce.jl:350
  [4] reduce_empty_iter
    @ ./reduce.jl:373 [inlined]
  [5] mapreduce_empty_iter(f::Function, op::Function, itr::Vector{Int64}, ItrEltype::Base.HasEltype)
    @ Base ./reduce.jl:369
  [6] _mapreduce
    @ ./reduce.jl:421 [inlined]
  [7] _mapreduce_dim
    @ ./reducedim.jl:334 [inlined]
  [8] mapreduce
    @ ./reducedim.jl:326 [inlined]
  [9] _extrema
    @ ./reducedim.jl:984 [inlined]
 [10] _extrema
    @ ./reducedim.jl:983 [inlined]
 [11] extrema
    @ ./reducedim.jl:979 [inlined]
 [12] group_by_color(::Type{Int64}, color::Vector{Int64})
    @ SparseMatrixColorings ~/.julia/dev/SparseMatrixColorings/src/result.jl:88
 [13] SparseMatrixColorings.TreeSetColoringResult(A::SparseMatrixCSC{…}, ag::SparseMatrixColorings.AdjacencyGraph{…}, color::Vector{…}, tree_set::SparseMatrixColorings.TreeSet{…}, decompression_eltype::Type{…})
    @ SparseMatrixColorings ~/.julia/dev/SparseMatrixColorings/src/result.jl:409
 [14] _coloring(speed_setting::SparseMatrixColorings.WithResult, A::SparseMatrixCSC{…}, ::ColoringProblem{…}, algo::GreedyColoringAlgorithm{…}, decompression_eltype::Type{…}, symmetric_pattern::Bool)
    @ SparseMatrixColorings ~/.julia/dev/SparseMatrixColorings/src/interface.jl:318
 [15] #coloring#28
    @ ~/.julia/dev/SparseMatrixColorings/src/interface.jl:196 [inlined]
 [16] coloring(A::SparseMatrixCSC{…}, problem::ColoringProblem{…}, algo::GreedyColoringAlgorithm{…})
    @ SparseMatrixColorings ~/.julia/dev/SparseMatrixColorings/src/interface.jl:189
 [17] top-level scope
    @ REPL[22]:1
Some type information was truncated. Use `show(err)` to see complete types.

Will add tests if this changes looks reasonable.

@codecov
Copy link

codecov bot commented Jan 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (921c7a0) to head (9caca0f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #300   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           20        20           
  Lines         2139      2143    +4     
=========================================
+ Hits          2139      2143    +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Owner

@gdalle gdalle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is acyclic coloring the only kind where empty matrices are problematic? What happens if only one dimension of the matrix is zero?
The fix is welcome (even though its usefulness isn't obvious to me), but then we may want to fix everything at once

blegat and others added 2 commits January 29, 2026 10:08
Co-authored-by: Guillaume Dalle <22795598+gdalle@users.noreply.github.com>
Copy link
Owner

@gdalle gdalle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Let's merge if the tests pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants