Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better functionality for PartitionedGraph #45

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Graphs/partitionedgraphs/abstractpartitionedge.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ abstract type AbstractPartitionEdge{V} <: AbstractNamedEdge{V} end
parent(pe::AbstractPartitionEdge) = not_implemented()
src(pe::AbstractPartitionEdge) = not_implemented()
dst(pe::AbstractPartitionEdge) = not_implemented()
reverse(pe::AbstractPartitionEdge) = not_implemented()

#Don't have the vertices wrapped. But wrap them with source and edge.
83 changes: 43 additions & 40 deletions src/Graphs/partitionedgraphs/abstractpartitionedgraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ abstract type AbstractPartitionedGraph{V,PV} <: AbstractNamedGraph{V} end
#Needed for interface
partitioned_graph(pg::AbstractPartitionedGraph) = not_implemented()
unpartitioned_graph(pg::AbstractPartitionedGraph) = not_implemented()
which_partition(pg::AbstractPartitionedGraph, vertex) = not_implemented()
partitioned_vertices(pg::AbstractPartitionedGraph) = not_implemented()
partitionvertex(pg::AbstractPartitionedGraph, vertex) = not_implemented()
partitionvertices(pg::AbstractPartitionedGraph, verts::Vector) = not_implemented()
partitionvertices(pg::AbstractPartitionedGraph) = not_implemented()
copy(pg::AbstractPartitionedGraph) = not_implemented()
delete_from_vertex_map!(pg::AbstractPartitionedGraph, vertex) = not_implemented()
insert_to_vertex_map!(pg::AbstractPartitionedGraph, vertex) = not_implemented()
partition_edge(pg::AbstractPartitionedGraph, edge) = not_implemented()
function edges(pg::AbstractPartitionedGraph, partition_edge::AbstractPartitionEdge)
partitionedge(pg::AbstractPartitionedGraph, edge) = not_implemented()
function partitionedges(pg::AbstractPartitionedGraph, edges::Vector{<:AbstractEdge})
return not_implemented()
end
partitionedges(pg::AbstractPartitionedGraph) = not_implemented()
function edges(pg::AbstractPartitionedGraph, partitionedge::AbstractPartitionEdge)
return not_implemented()
end
vertices(pg::AbstractPartitionedGraph, pv::AbstractPartitionVertex) = not_implemented()
function vertices(
pg::AbstractPartitionedGraph, partition_verts::Vector{V}
pg::AbstractPartitionedGraph, partitionverts::Vector{V}
) where {V<:AbstractPartitionVertex}
return not_implemented()
end
Expand All @@ -31,22 +36,22 @@ end
edgetype(pg::AbstractPartitionedGraph) = edgetype(unpartitioned_graph(pg))
parent_graph_type(pg::AbstractPartitionedGraph) = parent_graph_type(unpartitioned_graph(pg))
nv(pg::AbstractPartitionedGraph, pv::AbstractPartitionVertex) = length(vertices(pg, pv))
function has_vertex(pg::AbstractPartitionedGraph, partition_vertex::AbstractPartitionVertex)
return has_vertex(partitioned_graph(pg), parent(partition_vertex))
function has_vertex(pg::AbstractPartitionedGraph, partitionvertex::AbstractPartitionVertex)
return has_vertex(partitioned_graph(pg), parent(partitionvertex))
end

function has_edge(pg::AbstractPartitionedGraph, edge::AbstractPartitionEdge)
return has_edge(partitioned_graph(pg), parent(partition_edge))
function has_edge(pg::AbstractPartitionedGraph, partitionedge::AbstractPartitionEdge)
return has_edge(partitioned_graph(pg), parent(partitionedge))
end

function is_boundary_edge(pg::AbstractPartitionedGraph, edge::AbstractEdge)
p_edge = partition_edge(pg, edge)
p_edge = partitionedge(pg, edge)
return src(p_edge) == dst(p_edge)
end

function add_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge)
add_edge!(unpartitioned_graph(pg), edge)
pg_edge = parent(partition_edge(pg, edge))
pg_edge = parent(partitionedge(pg, edge))
if src(pg_edge) != dst(pg_edge)
add_edge!(partitioned_graph(pg), pg_edge)
end
Expand All @@ -55,7 +60,7 @@ function add_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge)
end

function rem_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge)
pg_edge = partition_edge(pg, edge)
pg_edge = partitionedge(pg, edge)
if has_edge(partitioned_graph(pg), pg_edge)
g_edges = edges(pg, pg_edge)
if length(g_edges) == 1
Expand All @@ -65,65 +70,65 @@ function rem_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge)
return rem_edge!(unpartitioned_graph(pg), edge)
end

function rem_edge!(pg::AbstractPartitionedGraph, partition_edge::AbstractPartitionEdge)
return rem_edges!(pg, edges(pg, parent(partition_edge)))
function rem_edge!(pg::AbstractPartitionedGraph, partitionedge::AbstractPartitionEdge)
return rem_edges!(pg, edges(pg, parent(partitionedge)))
end

function rem_edge(pg::AbstractPartitionedGraph, partition_edge::AbstractPartitionEdge)
function rem_edge(pg::AbstractPartitionedGraph, partitionedge::AbstractPartitionEdge)
pg_new = copy(pg)
rem_edge!(pg_new, partition_edge)
rem_edge!(pg_new, partitionedge)
return pg_new
end

function rem_edges!(
pg::AbstractPartitionedGraph, partition_edges::Vector{<:AbstractPartitionEdge}
pg::AbstractPartitionedGraph, partitionedges::Vector{<:AbstractPartitionEdge}
)
for pe in partition_edges
for pe in partitionedges
rem_edge!(pg, pe)
end
return pg
end

function rem_edges(
pg::AbstractPartitionedGraph, partition_edges::Vector{<:AbstractPartitionEdge}
pg::AbstractPartitionedGraph, partitionedges::Vector{<:AbstractPartitionEdge}
)
pg_new = copy(pg)
rem_edges!(pg_new, partition_edges)
rem_edges!(pg_new, partitionedges)
return pg_new
end

#Vertex addition and removal. I think it's important not to allow addition of a vertex without specification of PV
function add_vertex!(
pg::AbstractPartitionedGraph, vertex, partition_vertex::AbstractPartitionVertex
pg::AbstractPartitionedGraph, vertex, partitionvertex::AbstractPartitionVertex
)
add_vertex!(unpartitioned_graph(pg), vertex)
add_vertex!(partitioned_graph(pg), parent(partition_vertex))
insert_to_vertex_map!(pg, vertex, partition_vertex)
add_vertex!(partitioned_graph(pg), parent(partitionvertex))
insert_to_vertex_map!(pg, vertex, partitionvertex)
return pg
end

function add_vertices!(
pg::AbstractPartitionedGraph,
vertices::Vector,
partition_vertices::Vector{<:AbstractPartitionVertex},
partitionvertices::Vector{<:AbstractPartitionVertex},
)
@assert length(vertices) == length(partition_vertices)
for (v, pv) in zip(vertices, partition_vertices)
@assert length(vertices) == length(partitionvertices)
for (v, pv) in zip(vertices, partitionvertices)
add_vertex!(pg, v, pv)
end

return pg
end

function add_vertices!(
pg::AbstractPartitionedGraph, vertices::Vector, partition_vertex::AbstractPartitionVertex
pg::AbstractPartitionedGraph, vertices::Vector, partitionvertex::AbstractPartitionVertex
)
add_vertices!(pg, vertices, fill(partition_vertex, length(vertices)))
add_vertices!(pg, vertices, fill(partitionvertex, length(vertices)))
return pg
end

function rem_vertex!(pg::AbstractPartitionedGraph, vertex)
pv = which_partition(pg, vertex)
pv = partitionvertex(pg, vertex)
delete_from_vertex_map!(pg, pv, vertex)
rem_vertex!(unpartitioned_graph(pg), vertex)
if !haskey(partitioned_vertices(pg), parent(pv))
Expand All @@ -132,16 +137,14 @@ function rem_vertex!(pg::AbstractPartitionedGraph, vertex)
return pg
end

function rem_vertex!(
pg::AbstractPartitionedGraph, partition_vertex::AbstractPartitionVertex
)
rem_vertices!(pg, vertices(pg, partition_vertex))
function rem_vertex!(pg::AbstractPartitionedGraph, partitionvertex::AbstractPartitionVertex)
rem_vertices!(pg, vertices(pg, partitionvertex))
return pg
end

function rem_vertex(pg::AbstractPartitionedGraph, partition_vertex::AbstractPartitionVertex)
function rem_vertex(pg::AbstractPartitionedGraph, partitionvertex::AbstractPartitionVertex)
pg_new = copy(pg)
rem_vertex!(pg_new, partition_vertex)
rem_vertex!(pg_new, partitionvertex)
return pg_new
end

Expand All @@ -155,19 +158,19 @@ function (pg1::AbstractPartitionedGraph == pg2::AbstractPartitionedGraph)
return false
end
for v in vertices(pg1)
if which_partition(pg1, v) != which_partition(pg2, v)
if partitionvertex(pg1, v) != partitionvertex(pg2, v)
return false
end
end
return true
end

function subgraph(pg::AbstractPartitionedGraph, partition_vertex::AbstractPartitionVertex)
return first(induced_subgraph(unpartitioned_graph(pg), vertices(pg, [partition_vertex])))
function subgraph(pg::AbstractPartitionedGraph, partitionvertex::AbstractPartitionVertex)
return first(induced_subgraph(unpartitioned_graph(pg), vertices(pg, [partitionvertex])))
end

function induced_subgraph(
pg::AbstractPartitionedGraph, partition_vertex::AbstractPartitionVertex
pg::AbstractPartitionedGraph, partitionvertex::AbstractPartitionVertex
)
return subgraph(pg, partition_vertex), nothing
return subgraph(pg, partitionvertex), nothing
end
4 changes: 3 additions & 1 deletion src/Graphs/partitionedgraphs/partitionedge.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
struct PartitionEdge{V,E<:AbstractEdge{V}} <: AbstractPartitionEdge{V}
struct PartitionEdge{V,E<:AbstractEdge{<:V}} <: AbstractPartitionEdge{V}
edge::E
end

parent(pe::PartitionEdge) = getfield(pe, :edge)
src(pe::PartitionEdge) = PartitionVertex(src(parent(pe)))
dst(pe::PartitionEdge) = PartitionVertex(dst(parent(pe)))
PartitionEdge(p::Pair) = PartitionEdge(NamedEdge(first(p) => last(p)))
PartitionEdge(vsrc, vdst) = PartitionEdge(vsrc => vdst)
reverse(pe::PartitionEdge) = PartitionEdge(reverse(parent(pe)))
59 changes: 40 additions & 19 deletions src/Graphs/partitionedgraphs/partitionedgraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ function PartitionedGraph(partitioned_vertices)
end

function PartitionedGraph(g::AbstractGraph; kwargs...)
partitioned_vertices = partition_vertices(g; kwargs...)
return PartitionedGraph(g, partitioned_vertices)
partitioned_verts = partitioned_vertices(g; kwargs...)
return PartitionedGraph(g, partitioned_verts)
end

#Needed for interface
Expand All @@ -43,57 +43,78 @@ unpartitioned_graph(pg::PartitionedGraph) = getfield(pg, :graph)
partitioned_vertices(pg::PartitionedGraph) = getfield(pg, :partitioned_vertices)
which_partition(pg::PartitionedGraph) = getfield(pg, :which_partition)
parent_graph_type(PG::Type{<:PartitionedGraph}) = fieldtype(PG, :graph)
function vertices(pg::PartitionedGraph, partition_vert::PartitionVertex)
return partitioned_vertices(pg)[parent(partition_vert)]
function vertices(pg::PartitionedGraph, partitionvert::PartitionVertex)
return partitioned_vertices(pg)[parent(partitionvert)]
end
function vertices(pg::PartitionedGraph, partition_verts::Vector{<:PartitionVertex})
return unique(reduce(vcat, [vertices(pg, pv) for pv in partition_verts]))
function vertices(pg::PartitionedGraph, partitionverts::Vector{<:PartitionVertex})
return unique(reduce(vcat, [vertices(pg, pv) for pv in partitionverts]))
end
function which_partition(pg::PartitionedGraph, vertex)
function partitionvertex(pg::PartitionedGraph, vertex)
return PartitionVertex(which_partition(pg)[vertex])
end

function partition_edge(pg::PartitionedGraph, edge::AbstractEdge)
function partitionvertices(pg::PartitionedGraph, verts::Vector)
return unique(partitionvertex(pg, v) for v in verts)
end

function partitionvertices(pg::PartitionedGraph)
return PartitionVertex.(vertices(partitioned_graph(pg)))
end

function partitionedge(pg::PartitionedGraph, edge::AbstractEdge)
return PartitionEdge(
parent(which_partition(pg, src(edge))) => parent(which_partition(pg, dst(edge)))
parent(partitionvertex(pg, src(edge))) => parent(partitionvertex(pg, dst(edge)))
)
end

function partition_edges(pg::PartitionedGraph, partition_edge::PartitionEdge)
psrc_vs = vertices(pg, PartitionVertex(src(partition_edge)))
pdst_vs = vertices(pg, PartitionVertex(dst(partition_edge)))
#Lets filter out any self-edges from this. Although this makes it a bit consistent with partitionedge
function partitionedges(pg::PartitionedGraph, edges::Vector{<:AbstractEdge})
return filter(e -> src(e) != dst(e), unique([partitionedge(pg, e) for e in edges]))
end

function partitionedges(pg::PartitionedGraph)
return PartitionEdge.(edges(partitioned_graph(pg)))
end

function edges(pg::PartitionedGraph, partitionedge::PartitionEdge)
psrc_vs = vertices(pg, PartitionVertex(src(partitionedge)))
pdst_vs = vertices(pg, PartitionVertex(dst(partitionedge)))
psrc_subgraph = subgraph(unpartitioned_graph(pg), psrc_vs)
pdst_subgraph = subgraph(pg, pdst_vs)
full_subgraph = subgraph(pg, vcat(psrc_vs, pdst_vs))

return setdiff(edges(full_subgraph), vcat(edges(psrc_subgraph), edges(pdst_subgraph)))
end

function edges(pg::PartitionedGraph, partitionedges::Vector{<:PartitionEdge})
return unique(reduce(vcat, [edges(pg, pe) for pe in partitionedges]))
end

function copy(pg::PartitionedGraph)
return PartitionedGraph(
copy(unpartitioned_graph(pg)),
copy(partitioned_graph(pg)),
copy_keys_values(partitioned_vertices(pg)),
copy_keys_values(which_partition(pg)),
copy_keys_values(partitionvertex(pg)),
)
end

function insert_to_vertex_map!(
pg::PartitionedGraph, vertex, partition_vertex::PartitionVertex
pg::PartitionedGraph, vertex, partitionvertex::PartitionVertex
)
pv = parent(partition_vertex)
pv = parent(partitionvertex)
if pv ∉ keys(partitioned_vertices(pg))
insert!(partitioned_vertices(pg), pv, [vertex])
else
partitioned_vertices(pg)[pv] = unique(vcat(vertices(pg, partition_vertex), [vertex]))
partitioned_vertices(pg)[pv] = unique(vcat(vertices(pg, partitionvertex), [vertex]))
end

insert!(which_partition(pg), vertex, pv)
return pg
end

function delete_from_vertex_map!(pg::PartitionedGraph, vertex)
pv = which_partition(pg, vertex)
pv = partitionvertex(pg, vertex)
return delete_from_vertex_map!(pg, pv, vertex)
end

Expand Down Expand Up @@ -127,7 +148,7 @@ function induced_subgraph(pg::PartitionedGraph, vertices::Vector)
end

function induced_subgraph(
pg::PartitionedGraph, partition_verts::Vector{V}
pg::PartitionedGraph, partitionverts::Vector{V}
) where {V<:PartitionVertex}
return induced_subgraph(pg, vertices(pg, partition_verts))
return induced_subgraph(pg, vertices(pg, partitionverts))
end
8 changes: 4 additions & 4 deletions src/Graphs/partitionedgraphs/partitioning.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function _npartitions(
return error("Must specify either `npartitions` or `nvertices_per_partition`")
end

function partition_vertices(
function partitioned_vertices(
g::Graph;
npartitions=nothing,
nvertices_per_partition=nothing,
Expand All @@ -84,15 +84,15 @@ function partition_vertices(
return group(v -> 1, collect(vertices(g)))
end

return partition_vertices(
return partitioned_vertices(
Backend(backend), g, _npartitions(g, npartitions, nvertices_per_partition); kwargs...
)
end

function partition_vertices(
function partitioned_vertices(
g::AbstractNamedGraph; npartitions=nothing, nvertices_per_partition=nothing, kwargs...
)
vertex_partitions = partition_vertices(
vertex_partitions = partitioned_vertices(
parent_graph(g); npartitions, nvertices_per_partition, kwargs...
)
#[inv(vertex_to_parent_vertex(g))[v] for v in partitions]
Expand Down
5 changes: 5 additions & 0 deletions src/NamedGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ export NamedGraph,
neighbors,
nv,
partitioned_graph,
partitionedge,
partitionedges,
partitionvertex,
partitionvertices,
partitioned_vertices,
path_digraph,
path_graph,
periphery,
Expand Down
8 changes: 4 additions & 4 deletions src/requires/kahypar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ set_partitioning_backend!(Backend"KaHyPar"())
KaHyPar.HyperGraph(g::SimpleGraph) = incidence_matrix(g)

"""
partition_vertices(::Backend"KaHyPar", g::Graph, npartiations::Integer; objective="edge_cut", alg="kway", kwargs...)
partitioned_vertices(::Backend"KaHyPar", g::Graph, npartiations::Integer; objective="edge_cut", alg="kway", kwargs...)

- default_configuration => "cut_kKaHyPar_sea20.ini"
- :edge_cut => "cut_kKaHyPar_sea20.ini"
- :connectivity => "km1_kKaHyPar_sea20.ini"
- imbalance::Number=0.03
"""
function partition_vertices(
function partitioned_vertices(
::Backend"KaHyPar",
g::SimpleGraph,
npartitions::Integer;
Expand All @@ -28,6 +28,6 @@ function partition_vertices(
kahypar_configurations[(objective=objective, alg=alg)],
)
end
partitions = @suppress KaHyPar.partition(g, npartitions; configuration, kwargs...)
return groupfind(partitions .+ 1)
partitioned_verts = @suppress KaHyPar.partition(g, npartitions; configuration, kwargs...)
return groupfind(partitioned_verts .+ 1)
end
Loading
Loading