Skip to content

Commit 7c2f52e

Browse files
committed
Improve performance of algorithm ND.
1 parent 287a462 commit 7c2f52e

6 files changed

Lines changed: 218 additions & 188 deletions

File tree

ext/LaplaciansExt.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module LaplaciansExt
22

33
using CliqueTrees
4+
using CliqueTrees: simplegraph
45
using Graphs
56
using Laplacians
67
using SparseArrays
@@ -9,7 +10,7 @@ function CliqueTrees.permutation(graph, alg::Spectral)
910
return permutation(BipartiteGraph(graph), alg)
1011
end
1112

12-
function CliqueTrees.permutation(graph::BipartiteGraph{V}, alg::Spectral) where {V}
13+
function CliqueTrees.permutation(graph::AbstractGraph, alg::Spectral)
1314
order = spectralorder(graph; tol = alg.tol)
1415
return order, invperm(order)
1516
end
@@ -19,10 +20,9 @@ end
1920
# Algorithm 1: Spectral Algorithm
2021
#
2122
# Compute the spectral ordering of a graph.
22-
function spectralorder(graph::BipartiteGraph{V}; tol::Float64 = 0.0) where {V}
23+
function spectralorder(graph::AbstractGraph{V}; tol::Float64 = 0.0) where {V}
2324
order = Vector{V}(undef, nv(graph))
24-
matrix = SparseMatrixCSC{Float64}(graph)
25-
fill!(nonzeros(fkeep!((i, j, v) -> i != j, matrix)), 1)
25+
matrix = sparse(Float64, simplegraph(graph))
2626
value, vector = fiedler(matrix; tol)
2727
return sortperm!(order, reshape(vector, size(matrix, 2)))
2828
end

ext/MetisExt.jl

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
module MetisExt
22

3+
using ArgCheck
34
using CliqueTrees
4-
using CliqueTrees: simplegraph
5+
using CliqueTrees: Scalar, View, simplegraph
56
using Graphs
6-
using Metis: Metis
7+
8+
import Metis
79

810
const INT = Metis.idx_t
911

@@ -100,12 +102,14 @@ function CliqueTrees.permutation(graph::AbstractGraph{V}, alg::METIS) where {V}
100102
return order, index
101103
end
102104

103-
function CliqueTrees.separator(weights::AbstractVector, graph::BipartiteGraph{INT, INT}, alg::METISND)
104-
return CliqueTrees.separator(trunc.(INT, weights), graph, alg)
105+
function CliqueTrees.separator!(sepsize::Scalar{INT}, part::Vector{INT}, weights::AbstractVector, graph::BipartiteGraph{INT, INT}, alg::METISND)
106+
return CliqueTrees.separator!(sepsize, part, trunc.(INT, weights), graph, alg)
105107
end
106108

107-
function CliqueTrees.separator(weights::Vector{INT}, graph::BipartiteGraph{INT, INT}, alg::METISND)
109+
function CliqueTrees.separator!(sepsize::Scalar{INT}, part::Vector{INT}, weights::Union{View{INT}, Vector{INT}}, graph::BipartiteGraph{INT, INT}, alg::METISND)
108110
m = ne(graph); n = nv(graph); nn = n + one(INT)
111+
@argcheck n <= length(part)
112+
@argcheck n <= length(weights)
109113

110114
# construct options
111115
options = Vector{INT}(undef, Metis.METIS_NOPTIONS)
@@ -115,14 +119,11 @@ function CliqueTrees.separator(weights::Vector{INT}, graph::BipartiteGraph{INT,
115119
options[Metis.METIS_OPTION_UFACTOR + 1] = alg.ufactor
116120

117121
# construct METIS graph
118-
xadj = pointers(graph) .- one(INT)
119-
adjncy = targets(graph) .- one(INT)
122+
xadj = pointers(graph); xadj .-= one(INT)
123+
adjncy = targets(graph); adjncy .-= one(INT)
120124
vwght = weights
121125

122126
# construct separator
123-
part = Vector{INT}(undef, n)
124-
sepsize = fill(zero(INT), 1)
125-
126127
Metis.@check Metis.METIS_ComputeVertexSeparator(
127128
Ref{INT}(n),
128129
xadj,
@@ -133,7 +134,9 @@ function CliqueTrees.separator(weights::Vector{INT}, graph::BipartiteGraph{INT,
133134
part,
134135
)
135136

136-
return part
137+
xadj .+= one(INT)
138+
adjncy .+= one(INT)
139+
return
137140
end
138141

139142
end

src/bipartite_graphs.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# A simple bipartite graph (U, V, E). If U = V, then you can think of this as a directed graph.
22
# This type implements the abstract graph interface.
3-
struct BipartiteGraph{V <: Signed, E <: Signed, Ptr <: AbstractVector{E}, Tgt <: AbstractVector{V}} <:
3+
struct BipartiteGraph{V <: Integer, E <: Integer, Ptr <: AbstractVector{E}, Tgt <: AbstractVector{V}} <:
44
AbstractGraph{V}
55
nov::V
66
ptr::Ptr
@@ -322,6 +322,10 @@ function Base.reverse!(count::Vector{E}, result::BipartiteGraph{V, E}, graph::Ab
322322
return result
323323
end
324324

325+
function simplegraph(::Type{V}, ::Type{E}, graph) where {V, E}
326+
return simplegraph(V, E, BipartiteGraph(graph))
327+
end
328+
325329
function simplegraph(::Type{V}, ::Type{E}, graph::AbstractGraph{VV}) where {V, E, VV}
326330
m = de(graph); n = nv(graph)
327331
simple = BipartiteGraph{V, E}(n, n, m)
@@ -344,10 +348,18 @@ function simplegraph(::Type{V}, ::Type{E}, graph::AbstractGraph{VV}) where {V, E
344348
return simple
345349
end
346350

351+
function simplegraph(::Type{V}, graph) where {V}
352+
return simplegraph(V, BipartiteGraph(graph))
353+
end
354+
347355
function simplegraph(::Type{V}, graph::AbstractGraph) where {V}
348356
return simplegraph(V, etype(graph), graph)
349357
end
350358

359+
function simplegraph(graph)
360+
return simplegraph(BipartiteGraph(graph))
361+
end
362+
351363
function simplegraph(graph::AbstractGraph{V}) where {V}
352364
return simplegraph(V, graph)
353365
end
@@ -393,7 +405,7 @@ function Base.copy!(dst::BipartiteGraph, src::BipartiteGraph)
393405
return dst
394406
end
395407

396-
function Base.copy!(dst::BipartiteGraph{V, E, Ptr, OneTo{V}}, src::BipartiteGraph) where {V <: Signed, E <: Signed, Ptr <: AbstractVector{E}}
408+
function Base.copy!(dst::BipartiteGraph{V, E, Ptr, OneTo{V}}, src::BipartiteGraph) where {V <: Integer, E <: Integer, Ptr <: AbstractVector{E}}
397409
@argcheck nov(dst) == nov(src)
398410
@argcheck targets(dst) == targets(src)
399411
copy!(pointers(dst), pointers(src))

src/dissection_algorithms.jl

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ abstract type DissectionAlgorithm end
88
"""
99
METISND <: DissectionAlgorithm
1010
11-
Compute a vertex separator using METIS.
11+
Compute a vertex separator using `METIS_computeVertexSeparator`.
1212
"""
1313
@kwdef struct METISND <: DissectionAlgorithm
1414
ufactor::Int = -1
@@ -23,12 +23,8 @@ end
2323
# project(i) = 0 iff i ∈ W - B
2424
# project(i) = 1 iff i ∈ B - W
2525
# project(i) = 2 iff i ∈ W ∩ B
26-
function separator(weights::AbstractVector, graph::AbstractGraph, alg::DissectionAlgorithm)
27-
throw(
28-
ArgumentError(
29-
"Algorithm $alg not implemented. You may need to load an additional package."
30-
),
31-
)
26+
function separator!(sepsize::AbstractScalar, part::AbstractVector, weights::AbstractVector, graph::AbstractGraph, alg::DissectionAlgorithm)
27+
throw(ArgumentError("Algorithm $alg not implemented. You may need to load an additional package."))
3228
end
3329

3430
function Base.show(io::IO, ::MIME"text/plain", alg::METISND)

0 commit comments

Comments
 (0)