Skip to content

Commit 60d340a

Browse files
Subgraph compact sparse graph (#65)
* subgraph for compact sparse graph * tests and fixes for subgraph implementation * -Wshadow fix
1 parent 710d7b9 commit 60d340a

File tree

5 files changed

+187
-9
lines changed

5 files changed

+187
-9
lines changed

include/osp/graph_algorithms/directed_graph_edge_view.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ class edge_view {
7777
DirectedEdgeIterator &operator=(const DirectedEdgeIterator &other) = default;
7878
DirectedEdgeIterator &operator=(DirectedEdgeIterator &&other) noexcept = default;
7979

80-
explicit DirectedEdgeIterator(const Graph_t &graph) : graph_(&graph), currentVertex_(0), currentEdgeIdx_(0) {
80+
explicit DirectedEdgeIterator(const Graph_t &graph1) : graph_(&graph1), currentVertex_(0), currentEdgeIdx_(0) {
8181
advanceToValid();
8282
}
8383

84-
DirectedEdgeIterator(const vertex_idx_t<Graph_t> edge_idx, const Graph_t &graph)
85-
: graph_(&graph), currentVertex_(0), currentEdgeIdx_(edge_idx) {
84+
DirectedEdgeIterator(const vertex_idx_t<Graph_t> edge_idx, const Graph_t &graph1)
85+
: graph_(&graph1), currentVertex_(0), currentEdgeIdx_(edge_idx) {
8686

8787
if (currentEdgeIdx_ >= graph_->num_edges()) {
8888
currentEdgeIdx_ = graph_->num_edges();
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Copyright 2024 Huawei Technologies Co., Ltd.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
@author Toni Boehnlein, Benjamin Lozes, Pal Andras Papp, Raphael S. Steiner
17+
*/
18+
19+
#pragma once
20+
21+
#include "osp/concepts/graph_traits.hpp"
22+
#include "osp/graph_algorithms/directed_graph_top_sort.hpp"
23+
#include "osp/graph_algorithms/subgraph_algorithms.hpp"
24+
#include "osp/graph_implementations/adj_list_impl/compact_sparse_graph.hpp"
25+
26+
namespace osp {
27+
28+
template<typename Graph_t_in, typename vert_t, typename edge_t, typename work_weight_type, typename comm_weight_type, typename mem_weight_type, typename vertex_type_template_type>
29+
std::unordered_map<vertex_idx_t<Graph_t_in>, vertex_idx_t<Graph_t_in>> create_induced_subgraph_map(const Graph_t_in &dag, Compact_Sparse_Graph<true, true, true, true, true, vert_t, edge_t, work_weight_type, comm_weight_type, mem_weight_type, vertex_type_template_type> &dag_out,
30+
const std::vector<vertex_idx_t<Graph_t_in>> &selected_nodes) {
31+
32+
using Graph_t_out = Compact_Sparse_Graph<true, true, true, true, true, vert_t, edge_t, work_weight_type, comm_weight_type, mem_weight_type, vertex_type_template_type>;
33+
34+
static_assert(std::is_same_v<vertex_idx_t<Graph_t_in>, vertex_idx_t<Graph_t_out>>,
35+
"Graph_t_in and out must have the same vertex_idx types");
36+
37+
const std::vector<vertex_idx_t<Graph_t_in>> topOrder = GetTopOrder(dag);
38+
std::vector<vertex_idx_t<Graph_t_in>> topOrderPosition(topOrder.size());
39+
for (vertex_idx_t<Graph_t_in> pos = 0; pos < dag.num_vertices(); ++pos) {
40+
topOrderPosition[topOrder[pos]] = pos;
41+
}
42+
43+
auto topCmp = [&topOrderPosition](const vertex_idx_t<Graph_t_in> &lhs, const vertex_idx_t<Graph_t_in> &rhs) { return topOrderPosition[lhs] < topOrderPosition[rhs]; };
44+
45+
std::set<vertex_idx_t<Graph_t_in>, decltype(topCmp)> selectedVerticesOrdered(selected_nodes.begin(), selected_nodes.end(), topCmp);
46+
47+
std::unordered_map<vertex_idx_t<Graph_t_in>, vertex_idx_t<Graph_t_in>> local_idx;
48+
local_idx.reserve(selected_nodes.size());
49+
50+
vertex_idx_t<Graph_t_in> nodeCntr = 0;
51+
for (const auto &node : selectedVerticesOrdered) {
52+
local_idx[node] = nodeCntr++;
53+
}
54+
55+
std::vector<std::pair<vertex_idx_t<Graph_t_in>, vertex_idx_t<Graph_t_in>>> edges;
56+
for (const auto &node : selectedVerticesOrdered) {
57+
for (const auto &chld : dag.children(node)) {
58+
if (selectedVerticesOrdered.find(chld) != selectedVerticesOrdered.end()) {
59+
edges.emplace_back(local_idx.at(node), local_idx.at(chld));
60+
}
61+
}
62+
}
63+
64+
dag_out = Graph_t_out(nodeCntr, edges);
65+
66+
for (const auto &[oriVert, outVert] : local_idx) {
67+
dag_out.set_vertex_work_weight(outVert, dag.vertex_work_weight(oriVert));
68+
dag_out.set_vertex_comm_weight(outVert, dag.vertex_comm_weight(oriVert));
69+
dag_out.set_vertex_mem_weight(outVert, dag.vertex_mem_weight(oriVert));
70+
dag_out.set_vertex_type(outVert, dag.vertex_type(oriVert));
71+
}
72+
73+
return local_idx;
74+
}
75+
76+
} // end namespace osp

include/osp/graph_algorithms/subgraph_algorithms.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ limitations under the License.
2222
#include "osp/concepts/directed_graph_concept.hpp"
2323
#include <map>
2424
#include <set>
25+
#include <unordered_map>
2526
#include <vector>
2627

2728
namespace osp {
@@ -91,14 +92,12 @@ void create_induced_subgraph(const Graph_t_in &dag, Graph_t_out &dag_out,
9192
}
9293
}
9394

94-
9595
template<typename Graph_t_in, typename Graph_t_out>
9696
void create_induced_subgraph(const Graph_t_in &dag, Graph_t_out &dag_out,
9797
const std::vector<vertex_idx_t<Graph_t_in>> &selected_nodes) {
9898
return create_induced_subgraph(dag, dag_out, std::set<vertex_idx_t<Graph_t_in>>(selected_nodes.begin(), selected_nodes.end()));
9999
}
100100

101-
102101
template<typename Graph_t>
103102
bool checkOrderedIsomorphism(const Graph_t &first, const Graph_t &second) {
104103

@@ -170,8 +169,6 @@ std::vector<Graph_t_out> create_induced_subgraphs(const Graph_t_in &dag_in,
170169
static_assert(is_constructable_cdag_edge_v<Graph_t_out>,
171170
"Graph_t_out must satisfy the constructable_cdag_edge concept");
172171

173-
174-
175172
unsigned number_of_parts = 0;
176173
for (const auto id : partition_IDs)
177174
number_of_parts = std::max(number_of_parts, id + 1);
@@ -202,7 +199,7 @@ std::vector<Graph_t_out> create_induced_subgraphs(const Graph_t_in &dag_in,
202199

203200
if (partition_IDs[node] == partition_IDs[succ])
204201
split_dags[partition_IDs[node]].add_edge(local_idx[node], local_idx[succ],
205-
dag_in.edge_comm_weight(out_edge));
202+
dag_in.edge_comm_weight(out_edge));
206203
}
207204
}
208205
} else {
@@ -220,7 +217,7 @@ std::vector<Graph_t_out> create_induced_subgraphs(const Graph_t_in &dag_in,
220217

221218
template<typename Graph_t_in, typename Graph_t_out>
222219
std::unordered_map<vertex_idx_t<Graph_t_in>, vertex_idx_t<Graph_t_in>> create_induced_subgraph_map(const Graph_t_in &dag, Graph_t_out &dag_out,
223-
const std::vector<vertex_idx_t<Graph_t_in>> &selected_nodes) {
220+
const std::vector<vertex_idx_t<Graph_t_in>> &selected_nodes) {
224221

225222
static_assert(std::is_same_v<vertex_idx_t<Graph_t_in>, vertex_idx_t<Graph_t_out>>,
226223
"Graph_t_in and out must have the same vertex_idx types");

tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ _add_test( maxbsp_converter_and_hc )
162162

163163
_add_test( cost_evaluation )
164164

165+
_add_test( subgraph )
166+
165167
## pebbling ILPs
166168

167169
if (COPT_FOUND)

tests/subgraph.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
Copyright 2024 Huawei Technologies Co., Ltd.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
@author Toni Boehnlein, Pal Andras Papp, Raphael S. Steiner, Christos Konstantinos Matzoros
17+
*/
18+
19+
#define BOOST_TEST_MODULE SubGraphs
20+
#include <boost/test/unit_test.hpp>
21+
22+
#include "osp/graph_algorithms/specialised_graph_algorithms/subgraph_algorithms.hpp"
23+
#include "osp/graph_implementations/adj_list_impl/cdag_vertex_impl.hpp"
24+
#include "osp/graph_implementations/adj_list_impl/computational_dag_vector_impl.hpp"
25+
26+
using namespace osp;
27+
28+
BOOST_AUTO_TEST_CASE(SubGraphCompactSparseGraph) {
29+
const std::vector<std::pair<std::size_t, std::size_t>> edges({{0, 1}, {2, 3}, {6, 10}, {7, 9}, {0, 2}, {4, 6}, {1, 6}, {6, 7}, {5, 6}, {3, 7}, {1, 2}});
30+
Compact_Sparse_Graph<true, true, true, true, true> graph(11, edges);
31+
Compact_Sparse_Graph<true, true, true, true, true> subGraph;
32+
33+
unsigned cntr = 0;
34+
for (const auto &vert : graph.vertices()) {
35+
graph.set_vertex_work_weight(vert, cntr++);
36+
graph.set_vertex_comm_weight(vert, cntr++);
37+
graph.set_vertex_mem_weight(vert, cntr++);
38+
graph.set_vertex_type(vert, cntr++);
39+
}
40+
41+
const std::vector<vertex_idx_t<Compact_Sparse_Graph<true, true, true, true, true>>> selectVert({2, 3, 10, 6, 7});
42+
const auto vertCorrespondence = create_induced_subgraph_map(graph, subGraph, selectVert);
43+
BOOST_CHECK_EQUAL(subGraph.num_vertices(), selectVert.size());
44+
BOOST_CHECK_EQUAL(subGraph.num_edges(), 4);
45+
46+
for (const auto &vert : selectVert) {
47+
BOOST_CHECK_LT(vertCorrespondence.at(vert), selectVert.size());
48+
49+
for (const auto &otherVert : selectVert) {
50+
if (vertCorrespondence.at(vert) == vertCorrespondence.at(otherVert)) {
51+
BOOST_CHECK_EQUAL(vert, otherVert);
52+
}
53+
}
54+
}
55+
56+
for (const auto &vert : selectVert) {
57+
BOOST_CHECK_EQUAL(graph.vertex_work_weight(vert), subGraph.vertex_work_weight(vertCorrespondence.at(vert)));
58+
BOOST_CHECK_EQUAL(graph.vertex_comm_weight(vert), subGraph.vertex_comm_weight(vertCorrespondence.at(vert)));
59+
BOOST_CHECK_EQUAL(graph.vertex_mem_weight(vert), subGraph.vertex_mem_weight(vertCorrespondence.at(vert)));
60+
BOOST_CHECK_EQUAL(graph.vertex_type(vert), subGraph.vertex_type(vertCorrespondence.at(vert)));
61+
}
62+
}
63+
64+
BOOST_AUTO_TEST_CASE(SubGraphDagVectorImpl) {
65+
using v_impl = cdag_vertex_impl<std::size_t, unsigned, unsigned, unsigned, unsigned>;
66+
67+
computational_dag_vector_impl<v_impl> graph;
68+
computational_dag_vector_impl<v_impl> subGraph;
69+
70+
const std::size_t numVert = 11;
71+
const std::vector<std::pair<std::size_t, std::size_t>> edges({{0, 1}, {2, 3}, {6, 10}, {7, 9}, {0, 2}, {4, 6}, {1, 6}, {6, 7}, {5, 6}, {3, 7}, {1, 2}});
72+
73+
unsigned cntr = 0;
74+
for (std::size_t i = 0U; i < numVert; ++i) {
75+
graph.add_vertex(cntr, cntr + 1U, cntr + 2U, cntr + 3U);
76+
cntr += 4U;
77+
}
78+
for (const auto &[src, tgt] : edges) {
79+
graph.add_edge(src, tgt);
80+
}
81+
82+
const std::vector<vertex_idx_t<computational_dag_vector_impl<v_impl>>> selectVert({2, 3, 10, 6, 7});
83+
const auto vertCorrespondence = create_induced_subgraph_map(graph, subGraph, selectVert);
84+
BOOST_CHECK_EQUAL(subGraph.num_vertices(), selectVert.size());
85+
BOOST_CHECK_EQUAL(subGraph.num_edges(), 4);
86+
87+
for (const auto &vert : selectVert) {
88+
BOOST_CHECK_LT(vertCorrespondence.at(vert), selectVert.size());
89+
90+
for (const auto &otherVert : selectVert) {
91+
if (vertCorrespondence.at(vert) == vertCorrespondence.at(otherVert)) {
92+
BOOST_CHECK_EQUAL(vert, otherVert);
93+
}
94+
}
95+
}
96+
97+
for (const auto &vert : selectVert) {
98+
BOOST_CHECK_EQUAL(graph.vertex_work_weight(vert), subGraph.vertex_work_weight(vertCorrespondence.at(vert)));
99+
BOOST_CHECK_EQUAL(graph.vertex_comm_weight(vert), subGraph.vertex_comm_weight(vertCorrespondence.at(vert)));
100+
BOOST_CHECK_EQUAL(graph.vertex_mem_weight(vert), subGraph.vertex_mem_weight(vertCorrespondence.at(vert)));
101+
BOOST_CHECK_EQUAL(graph.vertex_type(vert), subGraph.vertex_type(vertCorrespondence.at(vert)));
102+
}
103+
}

0 commit comments

Comments
 (0)