From 4e1f9408ae6fc410d1c7b44af298636af00eeebd Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Tue, 11 Jun 2024 00:00:27 -0400 Subject: [PATCH] Use ColPack_jll.jl v0.4.0 --- examples/coloring.jl | 27 ++++++ src/ColPack.jl | 8 +- src/colpack_bicoloring.jl | 73 ++++++++++++++ ...colpackcoloring.jl => colpack_coloring.jl} | 15 ++- src/colpack_partial_coloring.jl | 97 +++++++++++++++++++ src/libcolpack.jl | 53 +++++----- src/method.jl | 32 ++++++ test/functionality.jl | 20 +++- 8 files changed, 287 insertions(+), 38 deletions(-) create mode 100644 src/colpack_bicoloring.jl rename src/{colpackcoloring.jl => colpack_coloring.jl} (87%) create mode 100644 src/colpack_partial_coloring.jl diff --git a/examples/coloring.jl b/examples/coloring.jl index 8a03344..b5a4872 100644 --- a/examples/coloring.jl +++ b/examples/coloring.jl @@ -35,3 +35,30 @@ end colors_colpack = get_colors(colpack_coloring) ncolors_colpack = maximum(colors_colpack) + +method = row_partial_d2_coloring() +@time colpack_partial_coloring1 = ColPackPartialColoring(paths[1], method, natural_ordering(); verbose) +colors_row = get_colors(colpack_partial_coloring1) +maximum(colors_row) + +method = column_partial_d2_coloring() +@time colpack_partial_coloring2 = ColPackPartialColoring(paths[1], method, natural_ordering(); verbose) +colors_column = get_colors(colpack_partial_coloring2) +maximum(colors_column) + +method = row_partial_d2_coloring() +@time colpack_partial_coloring1 = ColPackPartialColoring(A, method, natural_ordering(); verbose) +colors_row2 = get_colors(colpack_partial_coloring1) +maximum(colors_row2) + +method = column_partial_d2_coloring() +@time colpack_partial_coloring2 = ColPackPartialColoring(A, method, natural_ordering(); verbose) +colors_column2 = get_colors(colpack_partial_coloring2) +maximum(colors_column2) + +method = implicit_star_bicoloring() +# method = explicit_star_bicoloring() +# method = explicit_modified_star_bicoloring() +# method = implicit_greedy_star_bicoloring() +@time colpack_bicoloring = ColPackBiColoring(paths[1], method, random_ordering(); verbose) +colors1, colors2 = get_colors(colpack_bicoloring) diff --git a/src/ColPack.jl b/src/ColPack.jl index 2a69a8d..03f120d 100644 --- a/src/ColPack.jl +++ b/src/ColPack.jl @@ -12,12 +12,16 @@ include("libcolpack.jl") include("method.jl") include("order.jl") include("utils.jl") -include("colpackcoloring.jl") +include("colpack_coloring.jl") +include("colpack_partial_coloring.jl") +include("colpack_bicoloring.jl") # Exports export ColoringMethod export d1_coloring, d2_coloring, acyclic_coloring, star_coloring +export row_partial_d2_coloring, column_partial_d2_coloring +export implicit_star_bicoloring, explicit_star_bicoloring, explicit_modified_star_bicoloring, implicit_greedy_star_bicoloring export ColoringOrder export natural_ordering, largest_first_ordering, dynamic_largest_first_ordering, distance_two_largest_first_ordering @@ -26,6 +30,6 @@ export random_ordering export matrix2adjmatrix -export ColPackColoring, get_colors +export ColPackColoring, ColPackPartialColoring, ColPackBiColoring, get_colors end #module diff --git a/src/colpack_bicoloring.jl b/src/colpack_bicoloring.jl new file mode 100644 index 0000000..5f5335c --- /dev/null +++ b/src/colpack_bicoloring.jl @@ -0,0 +1,73 @@ +""" + ColPackBiColoring + +Struct holding the parameters of a bicoloring as well as its results (which can be queried with [`get_colors`](@ref)). + +# Fields + +The fields of this struct are not part of the public API, they are only useful to interface with the C++ library [ColPack](https://github.com/CSCsw/ColPack). + +# Constructors + + ColPackBiColoring( + filename::AbstractString, + method::ColoringMethod, + order::ColoringOrder; + verbose::Bool=false + ) + + ColPackBiColoring( + M::SparseMatrixCSC, + method::ColoringMethod, + order::ColoringOrder; + verbose::Bool=false + ) + +Perform the coloring of a matrix that is either given directly or read from a file. + +The users needs to specify a bicoloring `method` and an `order` on the vertices. + +# See also + +- [`ColoringMethod`](@ref) +- [`ColoringOrder`](@ref) +""" +mutable struct ColPackBiColoring + refColPack::Base.RefValue{Ptr{Cvoid}} + coloring1::Vector{Cint} + coloring2::Vector{Cint} + method::ColoringMethod + order::ColoringOrder +end + +Base.unsafe_convert(::Type{Ptr{Cvoid}}, coloring::ColPackBiColoring) = coloring.refColPack[] + +function ColPackBiColoring( + filename::AbstractString, + method::ColoringMethod, + order::ColoringOrder; + verbose::Bool=false, +) + refColPack = Ref{Ptr{Cvoid}}(C_NULL) + reflen1 = Ref{Cint}(0) + reflen2 = Ref{Cint}(0) + ret = build_bicoloring_from_file(refColPack, reflen1, reflen2, filename, method.method, order.order, verbose) + (ret == 0) && error("ColPack bicoloring failed.") + coloring1 = zeros(Cint, reflen1[]) + coloring2 = zeros(Cint, reflen2[]) + g = ColPackBiColoring(refColPack, coloring1, coloring2, method, order) + finalizer(free_bicoloring, g) + return g +end + +""" + get_colors(coloring::ColPackBiColoring) + +Retrieve the colors from a [`ColPackBiColoring`](@ref) as vectors of integers. +""" +function get_colors(coloring::ColPackBiColoring) + get_bicoloring(coloring.refColPack[], coloring.coloring1, coloring.coloring2) + coloring.coloring1 .+= Cint(1) + coloring.coloring2 .+= Cint(1) + return coloring.coloring1, coloring.coloring2 +end diff --git a/src/colpackcoloring.jl b/src/colpack_coloring.jl similarity index 87% rename from src/colpackcoloring.jl rename to src/colpack_coloring.jl index f70681a..44e0841 100644 --- a/src/colpackcoloring.jl +++ b/src/colpack_coloring.jl @@ -37,7 +37,6 @@ mutable struct ColPackColoring coloring::Vector{Cint} method::ColoringMethod order::ColoringOrder - csr::Union{Vector{Ptr{Cuint}},Nothing} end Base.unsafe_convert(::Type{Ptr{Cvoid}}, coloring::ColPackColoring) = coloring.refColPack[] @@ -53,18 +52,18 @@ function ColPackColoring( ret = build_coloring_from_file(refColPack, reflen, filename, method.method, order.order, verbose) (ret == 0) && error("ColPack coloring failed.") coloring = zeros(Cint, reflen[]) - g = ColPackColoring(refColPack, coloring, method, order, nothing) + g = ColPackColoring(refColPack, coloring, method, order) finalizer(free_coloring, g) return g end function ColPackColoring( - M::SparseMatrixCSC{VT,IT}, + M::SparseMatrixCSC, method::ColoringMethod, order::ColoringOrder; - verbose::Bool=false, -) where {VT,IT} - @assert issymmetric(M) + verbose::Bool=false +) + # We expect M to be symmetric. csr = Vector{Ref{Cuint}}() csr_mem = Vector{Vector{Cuint}}() for i in 1:(length(M.colptr) - 1) @@ -80,11 +79,11 @@ function ColPackColoring( nrows = size(M, 2) reflen = Ref{Cint}(0) refColPack = Ref{Ptr{Cvoid}}(C_NULL) - ret = build_coloring_from_csr(refColPack, reflen, csr, nrows, method.method, order.order, verbose) + ret = build_coloring_from_adolc(refColPack, reflen, csr, nrows, method.method, order.order, verbose) (ret == 0) && error("ColPack coloring failed.") coloring = zeros(Cint, reflen[]) - g = ColPackColoring(refColPack, coloring, method, order, csr) + g = ColPackColoring(refColPack, coloring, method, order) finalizer(free_coloring, g) return g end diff --git a/src/colpack_partial_coloring.jl b/src/colpack_partial_coloring.jl new file mode 100644 index 0000000..9a3530a --- /dev/null +++ b/src/colpack_partial_coloring.jl @@ -0,0 +1,97 @@ +""" + ColPackPartialColoring + +Struct holding the parameters of a partial coloring as well as its results (which can be queried with [`get_colors`](@ref)). + +# Fields + +The fields of this struct are not part of the public API, they are only useful to interface with the C++ library [ColPack](https://github.com/CSCsw/ColPack). + +# Constructors + + ColPackPartialColoring( + filename::AbstractString, + method::ColoringMethod, + order::ColoringOrder; + verbose::Bool=false + ) + + ColPackPartialColoring( + M::SparseMatrixCSC, + method::ColoringMethod, + order::ColoringOrder; + verbose::Bool=false + ) + +Perform the partial coloring of a matrix that is either given directly or read from a file. + +The users needs to specify a partial coloring `method` and an `order` on the vertices. + +# See also + +- [`ColoringMethod`](@ref) +- [`ColoringOrder`](@ref) +""" +mutable struct ColPackPartialColoring + refColPack::Base.RefValue{Ptr{Cvoid}} + coloring::Vector{Cint} + method::ColoringMethod + order::ColoringOrder +end + +Base.unsafe_convert(::Type{Ptr{Cvoid}}, coloring::ColPackPartialColoring) = coloring.refColPack[] + +function ColPackPartialColoring( + filename::AbstractString, + method::ColoringMethod, + order::ColoringOrder; + verbose::Bool=false, +) + refColPack = Ref{Ptr{Cvoid}}(C_NULL) + reflen = Ref{Cint}(0) + ret = build_partial_coloring_from_file(refColPack, reflen, filename, method.method, order.order, verbose) + (ret == 0) && error("ColPack partial coloring failed.") + coloring = zeros(Cint, reflen[]) + g = ColPackPartialColoring(refColPack, coloring, method, order) + finalizer(free_partial_coloring, g) + return g +end + +function ColPackPartialColoring( + M::SparseMatrixCSC, + method::ColoringMethod, + order::ColoringOrder; + verbose::Bool=false, +) + reflen = Ref{Cint}(0) + refColPack = Ref{Ptr{Cvoid}}(C_NULL) + nrows, ncols = size(M) + + # The CSC format of M is the CSR format of Máµ€. + Mt_cols = Cint.(M.rowval) + Mt_rows = Cint.(M.colptr) + + # ColPack expects sparse CSR matrices with 0-based indexing. + Mt_cols .-= Cint(1) + Mt_rows .-= Cint(1) + + (method.method == "ROW_PARTIAL_DISTANCE_TWO") && (colpack_method = "COLUMN_PARTIAL_DISTANCE_TWO") + (method.method == "COLUMN_PARTIAL_DISTANCE_TWO") && (colpack_method = "ROW_PARTIAL_DISTANCE_TWO") + ret = build_partial_coloring_from_csr(refColPack, reflen, Mt_rows, Mt_cols, ncols, nrows, colpack_method, order.order, verbose) + (ret == 0) && error("ColPack partial coloring failed.") + coloring = zeros(Cint, reflen[]) + g = ColPackPartialColoring(refColPack, coloring, ColoringMethod(colpack_method), order) + finalizer(free_partial_coloring, g) + return g +end + +""" + get_colors(coloring::ColPackPartialColoring) + +Retrieve the colors from a [`ColPackPartialColoring`](@ref) as a vector of integers. +""" +function get_colors(coloring::ColPackPartialColoring) + get_partial_coloring(coloring.refColPack[], coloring.coloring) + coloring.coloring .+= Cint(1) + return coloring.coloring +end diff --git a/src/libcolpack.jl b/src/libcolpack.jl index 4103e31..300f33a 100644 --- a/src/libcolpack.jl +++ b/src/libcolpack.jl @@ -1,53 +1,58 @@ function build_coloring_from_file(ref, len, _filename, _method, _order, verbose) - @ccall libcolpack.build_coloring_from_file(ref::Ptr{Ptr{Cvoid}}, len::Ptr{Cint}, _filename::Cstring, - _method::Cstring, _order::Cstring, verbose::Cint)::Cint + @ccall libcolpack.build_coloring_from_file(ref::Ptr{Ptr{Cvoid}}, len::Ptr{Cint}, _filename::Ptr{Cchar}, + _method::Ptr{Cchar}, _order::Ptr{Cchar}, verbose::Cint)::Cint +end + +function build_partial_coloring_from_file(ref, len, _filename, _method, _order, verbose) + @ccall libcolpack.build_partial_coloring_from_file(ref::Ptr{Ptr{Cvoid}}, len::Ptr{Cint}, _filename::Ptr{Cchar}, + _method::Ptr{Cchar}, _order::Ptr{Cchar}, verbose::Cint)::Cint end function build_bicoloring_from_file(ref, len1, len2, _filename, _method, _order, verbose) - @ccall libcolpack.build_bicoloring_from_file(ref::Ptr{Ptr{Cvoid}}, len1::Ptr{Cint}, len2::Ptr{Cint}, _filename::Cstring, - _method::Cstring, _order::Cstring, verbose::Cint)::Cint + @ccall libcolpack.build_bicoloring_from_file(ref::Ptr{Ptr{Cvoid}}, len1::Ptr{Cint}, len2::Ptr{Cint}, _filename::Ptr{Cchar}, + _method::Ptr{Cchar}, _order::Ptr{Cchar}, verbose::Cint)::Cint end -function build_partial_coloring_from_file(ref, len1, len2, _filename, _method, _order, verbose) - @ccall libcolpack.build_partial_coloring_from_file(ref::Ptr{Ptr{Cvoid}}, len1::Ptr{Cint}, len2::Ptr{Cint}, _filename::Cstring, - _method::Cstring, _order::Cstring, verbose::Cint)::Cint +function build_coloring_from_adolc(ref, len, adolc, rowcount, _method, _order, verbose) + @ccall libcolpack.build_coloring_from_adolc(ref::Ptr{Ptr{Cvoid}}, len::Ptr{Cint}, adolc::Ptr{Ptr{Cuint}}, + rowcount::Cint, _method::Ptr{Cchar}, _order::Ptr{Cchar}, verbose::Cint)::Cint end -function build_coloring_from_csr(ref, len, csr, rowcount, _method, _order, verbose) - @ccall libcolpack.build_coloring_from_csr(ref::Ptr{Ptr{Cvoid}}, len::Ptr{Cint}, csr::Ptr{Ptr{Cuint}}, - rowcount::Cint, _method::Cstring, _order::Cstring, verbose::Cint)::Cint +function build_partial_coloring_from_adolc(ref, len, adolc, rowcount, colcount, _method, _order, verbose) + @ccall libcolpack.build_partial_coloring_from_adolc(ref::Ptr{Ptr{Cvoid}}, len::Ptr{Cint}, adolc::Ptr{Ptr{Cuint}}, + rowcount::Cint, colcount::Cint, _method::Ptr{Cchar}, _order::Ptr{Cchar}, verbose::Cint)::Cint end -function build_bicoloring_from_csr(ref, len1, len2, csr, rowcount, colcount, _method, _order, verbose) - @ccall libcolpack.build_bicoloring_from_csr(ref::Ptr{Ptr{Cvoid}}, len1::Ptr{Cint}, len2::Ptr{Cint}, csr::Ptr{Ptr{Cuint}}, - rowcount::Cint, colcount::Cint, _method::Cstring, _order::Cstring, verbose::Cint)::Cint +function build_bicoloring_from_adolc(ref, len1, len2, adolc, rowcount, colcount, _method, _order, verbose) + @ccall libcolpack.build_bicoloring_from_adolc(ref::Ptr{Ptr{Cvoid}}, len1::Ptr{Cint}, len2::Ptr{Cint}, adolc::Ptr{Ptr{Cuint}}, + rowcount::Cint, colcount::Cint, _method::Ptr{Cchar}, _order::Ptr{Cchar}, verbose::Cint)::Cint end -function build_partial_coloring_from_csr(ref, len1, len2, csr, rowcount, colcount, _method, _order, verbose) - @ccall libcolpack.build_partial_coloring_from_csr(ref::Ptr{Ptr{Cvoid}}, len1::Ptr{Cint}, len2::Ptr{Cint}, csr::Ptr{Ptr{Cuint}}, - rowcount::Cint, colcount::Cint, _method::Cstring, _order::Cstring, verbose::Cint)::Cint +function build_partial_coloring_from_csr(ref, len, rows, cols, rowcount, colcount, _method, _order, verbose) + @ccall libcolpack.build_partial_coloring_from_csr(ref::Ptr{Ptr{Cvoid}}, len::Ptr{Cint}, rows::Ptr{Cint}, cols::Ptr{Cint}, + rowcount::Cint, colcount::Cint, _method::Ptr{Cchar}, _order::Ptr{Cchar}, verbose::Cint)::Cint end function get_coloring(ref, coloring) @ccall libcolpack.get_coloring(ref::Ptr{Cvoid}, coloring::Ptr{Cint})::Cvoid end -function get_bicoloring(ref, left_coloring, right_coloring) - @ccall libcolpack.get_bicoloring(ref::Ptr{Cvoid}, left_coloring::Ptr{Cint}, right_coloring::Ptr{Cint})::Cvoid +function get_partial_coloring(ref, coloring) + @ccall libcolpack.get_partial_coloring(ref::Ptr{Cvoid}, coloring::Ptr{Cint})::Cvoid end -function get_partial_coloring(ref, left_coloring, right_coloring) - @ccall libcolpack.get_partial_coloring(ref::Ptr{Cvoid}, left_coloring::Ptr{Cint}, right_coloring::Ptr{Cint})::Cvoid +function get_bicoloring(ref, left_coloring, right_coloring) + @ccall libcolpack.get_bicoloring(ref::Ptr{Cvoid}, left_coloring::Ptr{Cint}, right_coloring::Ptr{Cint})::Cvoid end function free_coloring(ref) @ccall libcolpack.free_coloring(ref::Ptr{Cvoid})::Cvoid end -function free_bicoloring(ref) - @ccall libcolpack.free_bicoloring(ref::Ptr{Cvoid})::Cvoid -end - function free_partial_coloring(ref) @ccall libcolpack.free_partial_coloring(ref::Ptr{Cvoid})::Cvoid end + +function free_bicoloring(ref) + @ccall libcolpack.free_bicoloring(ref::Ptr{Cvoid})::Cvoid +end diff --git a/src/method.jl b/src/method.jl index ba0ce72..08115a6 100644 --- a/src/method.jl +++ b/src/method.jl @@ -15,6 +15,10 @@ Represent a [ColPack](https://github.com/CSCsw/ColPack)-compatible [coloring met - [`star_coloring()`](@ref) - [`row_partial_d2_coloring()`](@ref) - [`column_partial_d2_coloring()`](@ref) +- [`implicit_star_bicoloring()`](@ref) +- [`explicit_star_bicoloring()`](@ref) +- [`explicit_modified_star_bicoloring()`](@ref) +- [`implicit_greedy_star_bicoloring()`](@ref) """ struct ColoringMethod method::String @@ -61,3 +65,31 @@ row_partial_d2_coloring() = ColoringMethod("ROW_PARTIAL_DISTANCE_TWO") Shortcut for `ColoringMethod("COLUMN_PARTIAL_DISTANCE_TWO")`. """ column_partial_d2_coloring() = ColoringMethod("COLUMN_PARTIAL_DISTANCE_TWO") + +""" + implicit_star_bicoloring() + +Shortcut for `ColoringMethod("IMPLICIT_COVERING__STAR_BICOLORING")`. +""" +implicit_star_bicoloring() = ColoringMethod("IMPLICIT_COVERING__STAR_BICOLORING") + +""" + explicit_star_bicoloring() + +Shortcut for `ColoringMethod("EXPLICIT_COVERING__STAR_BICOLORING")`. +""" +explicit_star_bicoloring() = ColoringMethod("EXPLICIT_COVERING__STAR_BICOLORING") + +""" + explicit_modified_star_bicoloring() + +Shortcut for `ColoringMethod("EXPLICIT_COVERING__MODIFIED_STAR_BICOLORING")`. +""" +explicit_modified_star_bicoloring() = ColoringMethod("EXPLICIT_COVERING__MODIFIED_STAR_BICOLORING") + +""" + implicit_greedy_star_bicoloring() + +Shortcut for `ColoringMethod(IMPLICIT_COVERING__GREEDY_STAR_BICOLORING")`. +""" +implicit_greedy_star_bicoloring() = ColoringMethod("IMPLICIT_COVERING__GREEDY_STAR_BICOLORING") diff --git a/test/functionality.jl b/test/functionality.jl index 3921d20..696acf3 100644 --- a/test/functionality.jl +++ b/test/functionality.jl @@ -43,16 +43,28 @@ MatrixMarket.mmwrite(filename, A) verbose = false @testset "MatrixMarket API" begin - @testset "$ordering" for (i, ordering) in enumerate(orderings) + @testset "Coloring -- $ordering" for (i, ordering) in enumerate(orderings) coloring = ColPackColoring(filename, d1_coloring(), ordering; verbose=verbose) - @test length(unique(get_colors(coloring))) == ncolors[i] + @test maximum(get_colors(coloring)) == ncolors[i] + end + + @testset "Partial coloring -- $ordering" for (i, ordering) in enumerate(orderings) + row_coloring = ColPackPartialColoring(filename, row_partial_d2_coloring(), ordering; verbose=verbose) + column_coloring = ColPackPartialColoring(filename, column_partial_d2_coloring(), ordering; verbose=verbose) end end @testset "ADOL-C Compressed Row Storage" begin - @testset "$ordering" for (i, ordering) in enumerate(orderings) + @testset "Coloring -- $ordering" for (i, ordering) in enumerate(orderings) coloring = ColPackColoring(A, d1_coloring(), ordering; verbose=verbose) - @test length(unique(get_colors(coloring))) == ncolors[i] + @test maximum(get_colors(coloring)) == ncolors[i] + end +end + +@testset "CSR Storage" begin + @testset "Partial coloring -- $ordering" for (i, ordering) in enumerate(orderings) + row_coloring = ColPackPartialColoring(A, row_partial_d2_coloring(), ordering; verbose=verbose) + column_coloring = ColPackPartialColoring(A, column_partial_d2_coloring(), ordering; verbose=verbose) end end