annotate DEPENDENCIES/generic/include/boost/graph/distributed/depth_first_search.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (C) 2004-2008 The Trustees of Indiana University.
Chris@16 2
Chris@16 3 // Use, modification and distribution is subject to the Boost Software
Chris@16 4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Authors: Douglas Gregor
Chris@16 8 // Andrew Lumsdaine
Chris@16 9 #ifndef BOOST_GRAPH_DISTRIBUTED_DFS_HPP
Chris@16 10 #define BOOST_GRAPH_DISTRIBUTED_DFS_HPP
Chris@16 11
Chris@16 12 #ifndef BOOST_GRAPH_USE_MPI
Chris@16 13 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
Chris@16 14 #endif
Chris@16 15
Chris@16 16 #include <boost/graph/graph_traits.hpp>
Chris@16 17 #include <boost/property_map/property_map.hpp>
Chris@16 18 #include <boost/graph/overloading.hpp>
Chris@16 19 #include <boost/graph/properties.hpp>
Chris@16 20 #include <boost/graph/distributed/concepts.hpp>
Chris@16 21 #include <boost/static_assert.hpp>
Chris@16 22 #include <boost/assert.hpp>
Chris@16 23 #include <boost/graph/parallel/process_group.hpp>
Chris@16 24 #include <boost/graph/parallel/container_traits.hpp>
Chris@16 25
Chris@16 26 namespace boost {
Chris@16 27 namespace graph { namespace distributed { namespace detail {
Chris@16 28 template<typename DistributedGraph, typename ColorMap, typename ParentMap,
Chris@16 29 typename ExploreMap, typename VertexIndexMap, typename DFSVisitor>
Chris@16 30 class parallel_dfs
Chris@16 31 {
Chris@16 32 typedef typename graph_traits<DistributedGraph>::vertex_iterator
Chris@16 33 vertex_iterator;
Chris@16 34 typedef typename graph_traits<DistributedGraph>::vertex_descriptor
Chris@16 35 vertex_descriptor;
Chris@16 36 typedef typename graph_traits<DistributedGraph>::out_edge_iterator
Chris@16 37 out_edge_iterator;
Chris@16 38
Chris@16 39 typedef typename boost::graph::parallel::process_group_type<DistributedGraph>
Chris@16 40 ::type process_group_type;
Chris@16 41 typedef typename process_group_type::process_id_type process_id_type;
Chris@16 42
Chris@16 43 /**
Chris@16 44 * The first vertex in the pair is the local node (i) and the
Chris@16 45 * second vertex in the pair is the (possibly remote) node (j).
Chris@16 46 */
Chris@16 47 typedef boost::parallel::detail::untracked_pair<vertex_descriptor, vertex_descriptor> vertex_pair;
Chris@16 48
Chris@16 49 typedef typename property_traits<ColorMap>::value_type color_type;
Chris@16 50 typedef color_traits<color_type> Color;
Chris@16 51
Chris@16 52 // Message types
Chris@16 53 enum { discover_msg = 10, return_msg = 50, visited_msg = 100 , done_msg = 150};
Chris@16 54
Chris@16 55
Chris@16 56 public:
Chris@16 57 parallel_dfs(const DistributedGraph& g, ColorMap color,
Chris@16 58 ParentMap parent, ExploreMap explore,
Chris@16 59 VertexIndexMap index_map, DFSVisitor vis)
Chris@16 60 : g(g), color(color), parent(parent), explore(explore),
Chris@16 61 index_map(index_map), vis(vis), pg(process_group(g)),
Chris@16 62 owner(get(vertex_owner, g)), next_out_edge(num_vertices(g))
Chris@16 63 { }
Chris@16 64
Chris@16 65 void run(vertex_descriptor s)
Chris@16 66 {
Chris@16 67 vertex_iterator vi, vi_end;
Chris@16 68 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
Chris@16 69 put(color, *vi, Color::white());
Chris@16 70 put(parent, *vi, *vi);
Chris@16 71 put(explore, *vi, *vi);
Chris@16 72 next_out_edge[get(index_map, *vi)] = out_edges(*vi, g).first;
Chris@16 73 vis.initialize_vertex(*vi, g);
Chris@16 74 }
Chris@16 75
Chris@16 76 vis.start_vertex(s, g);
Chris@16 77
Chris@16 78 if (get(owner, s) == process_id(pg)) {
Chris@16 79 send_oob(pg, get(owner, s), discover_msg, vertex_pair(s, s));
Chris@16 80 }
Chris@16 81
Chris@16 82 bool done = false;
Chris@16 83 while (!done) {
Chris@16 84 std::pair<process_id_type, int> msg = *pg.poll(true);
Chris@16 85
Chris@16 86 switch (msg.second) {
Chris@16 87 case discover_msg:
Chris@16 88 {
Chris@16 89 vertex_pair p;
Chris@16 90 receive_oob(pg, msg.first, msg.second, p);
Chris@16 91
Chris@16 92 if (p.first != p.second) {
Chris@16 93 // delete j from nomessage(j)
Chris@16 94 if (get(color, p.second) != Color::black())
Chris@16 95 local_put(color, p.second, Color::gray());
Chris@16 96
Chris@16 97 if (recover(p)) break;
Chris@16 98 }
Chris@16 99
Chris@16 100 if (get(color, p.first) == Color::white()) {
Chris@16 101 put(color, p.first, Color::gray());
Chris@16 102 put(parent, p.first, p.second);
Chris@16 103
Chris@16 104 vis.discover_vertex(p.first, g);
Chris@16 105
Chris@16 106 if (shift_center_of_activity(p.first)) break;
Chris@16 107
Chris@16 108 out_edge_iterator ei, ei_end;
Chris@16 109 for (boost::tie(ei,ei_end) = out_edges(p.first, g); ei != ei_end; ++ei)
Chris@16 110 {
Chris@16 111 // Notify everyone who may not know that the source
Chris@16 112 // vertex has been visited. They can then mark the
Chris@16 113 // corresponding color map entry gray.
Chris@16 114 if (get(parent, p.first) != target(*ei, g)
Chris@16 115 && get(explore, p.first) != target(*ei, g)) {
Chris@16 116 vertex_pair visit(target(*ei, g), p.first);
Chris@16 117
Chris@16 118 send_oob(pg, get(owner, target(*ei, g)), visited_msg, visit);
Chris@16 119 }
Chris@16 120 }
Chris@16 121 }
Chris@16 122 }
Chris@16 123 break;
Chris@16 124
Chris@16 125 case visited_msg:
Chris@16 126 {
Chris@16 127 vertex_pair p;
Chris@16 128 receive_oob(pg, msg.first, msg.second, p);
Chris@16 129
Chris@16 130 // delete j from nomessage(j)
Chris@16 131 if (get(color, p.second) != Color::black())
Chris@16 132 local_put(color, p.second, Color::gray());
Chris@16 133
Chris@16 134 recover(p);
Chris@16 135 }
Chris@16 136 break;
Chris@16 137
Chris@16 138 case return_msg:
Chris@16 139 {
Chris@16 140 vertex_pair p;
Chris@16 141 receive_oob(pg, msg.first, msg.second, p);
Chris@16 142
Chris@16 143 // delete j from nomessage(i)
Chris@16 144 local_put(color, p.second, Color::black());
Chris@16 145
Chris@16 146 shift_center_of_activity(p.first);
Chris@16 147 }
Chris@16 148 break;
Chris@16 149
Chris@16 150 case done_msg:
Chris@16 151 {
Chris@16 152 receive_oob(pg, msg.first, msg.second, done);
Chris@16 153
Chris@16 154 // Propagate done message downward in tree
Chris@16 155 done = true;
Chris@16 156 process_id_type id = process_id(pg);
Chris@16 157 process_id_type left = 2*id + 1;
Chris@16 158 process_id_type right = left + 1;
Chris@16 159 if (left < num_processes(pg))
Chris@16 160 send_oob(pg, left, done_msg, done);
Chris@16 161 if (right < num_processes(pg))
Chris@16 162 send_oob(pg, right, done_msg, done);
Chris@16 163 }
Chris@16 164 break;
Chris@16 165
Chris@16 166 default:
Chris@16 167 BOOST_ASSERT(false);
Chris@16 168 }
Chris@16 169 }
Chris@16 170 }
Chris@16 171
Chris@16 172 private:
Chris@16 173 bool recover(const vertex_pair& p)
Chris@16 174 {
Chris@16 175 if (get(explore, p.first) == p.second) {
Chris@16 176 return shift_center_of_activity(p.first);
Chris@16 177 }
Chris@16 178 else
Chris@16 179 return false;
Chris@16 180 }
Chris@16 181
Chris@16 182 bool shift_center_of_activity(vertex_descriptor i)
Chris@16 183 {
Chris@16 184 for (out_edge_iterator ei = next_out_edge[get(index_map, i)],
Chris@16 185 ei_end = out_edges(i, g).second;
Chris@16 186 ei != ei_end; ++ei) {
Chris@16 187 vis.examine_edge(*ei, g);
Chris@16 188
Chris@16 189 vertex_descriptor k = target(*ei, g);
Chris@16 190 color_type target_color = get(color, k);
Chris@16 191 if (target_color == Color::black()) vis.forward_or_cross_edge(*ei, g);
Chris@16 192 else if (target_color == Color::gray()) vis.back_edge(*ei, g);
Chris@16 193 else {
Chris@16 194 put(explore, i, k);
Chris@16 195 vis.tree_edge(*ei, g);
Chris@16 196 vertex_pair p(k, i);
Chris@16 197 send_oob(pg, get(owner, k), discover_msg, p);
Chris@16 198 next_out_edge[get(index_map, i)] = ++ei;
Chris@16 199 return false;
Chris@16 200 }
Chris@16 201 }
Chris@16 202
Chris@16 203 next_out_edge[get(index_map, i)] = out_edges(i, g).second;
Chris@16 204 put(explore, i, i);
Chris@16 205 put(color, i, Color::black());
Chris@16 206 vis.finish_vertex(i, g);
Chris@16 207
Chris@16 208 if (get(parent, i) == i) {
Chris@16 209 send_oob(pg, 0, done_msg, true);
Chris@16 210 return true;
Chris@16 211 }
Chris@16 212 else {
Chris@16 213 vertex_pair ret(get(parent, i), i);
Chris@16 214 send_oob(pg, get(owner, ret.first), return_msg, ret);
Chris@16 215 }
Chris@16 216 return false;
Chris@16 217 }
Chris@16 218
Chris@16 219 const DistributedGraph& g;
Chris@16 220 ColorMap color;
Chris@16 221 ParentMap parent;
Chris@16 222 ExploreMap explore;
Chris@16 223 VertexIndexMap index_map;
Chris@16 224 DFSVisitor vis;
Chris@16 225 process_group_type pg;
Chris@16 226 typename property_map<DistributedGraph, vertex_owner_t>::const_type owner;
Chris@16 227 std::vector<out_edge_iterator> next_out_edge;
Chris@16 228 };
Chris@16 229 } // end namespace detail
Chris@16 230
Chris@16 231 template<typename DistributedGraph, typename ColorMap, typename ParentMap,
Chris@16 232 typename ExploreMap, typename VertexIndexMap, typename DFSVisitor>
Chris@16 233 void
Chris@16 234 tsin_depth_first_visit
Chris@16 235 (const DistributedGraph& g,
Chris@16 236 typename graph_traits<DistributedGraph>::vertex_descriptor s,
Chris@16 237 DFSVisitor vis, ColorMap color, ParentMap parent, ExploreMap explore,
Chris@16 238 VertexIndexMap index_map)
Chris@16 239 {
Chris@16 240 typedef typename graph_traits<DistributedGraph>::directed_category
Chris@16 241 directed_category;
Chris@16 242 BOOST_STATIC_ASSERT(
Chris@16 243 (is_convertible<directed_category, undirected_tag>::value));
Chris@16 244
Chris@16 245 set_property_map_role(vertex_color, color);
Chris@16 246 graph::distributed::detail::parallel_dfs
Chris@16 247 <DistributedGraph, ColorMap, ParentMap, ExploreMap, VertexIndexMap,
Chris@16 248 DFSVisitor> do_dfs(g, color, parent, explore, index_map, vis);
Chris@16 249 do_dfs.run(s);
Chris@16 250
Chris@16 251 using boost::graph::parallel::process_group;
Chris@16 252 synchronize(process_group(g));
Chris@16 253 }
Chris@16 254
Chris@16 255 template<typename DistributedGraph, typename DFSVisitor,
Chris@16 256 typename VertexIndexMap>
Chris@16 257 void
Chris@16 258 tsin_depth_first_visit
Chris@16 259 (const DistributedGraph& g,
Chris@16 260 typename graph_traits<DistributedGraph>::vertex_descriptor s,
Chris@16 261 DFSVisitor vis,
Chris@16 262 VertexIndexMap index_map)
Chris@16 263 {
Chris@16 264 typedef typename graph_traits<DistributedGraph>::vertex_descriptor
Chris@16 265 vertex_descriptor;
Chris@16 266
Chris@16 267 std::vector<default_color_type> colors(num_vertices(g));
Chris@16 268 std::vector<vertex_descriptor> parent(num_vertices(g));
Chris@16 269 std::vector<vertex_descriptor> explore(num_vertices(g));
Chris@16 270 tsin_depth_first_visit
Chris@16 271 (g, s,
Chris@16 272 vis,
Chris@16 273 make_iterator_property_map(colors.begin(), index_map),
Chris@16 274 make_iterator_property_map(parent.begin(), index_map),
Chris@16 275 make_iterator_property_map(explore.begin(), index_map),
Chris@16 276 index_map);
Chris@16 277 }
Chris@16 278
Chris@16 279 template<typename DistributedGraph, typename DFSVisitor,
Chris@16 280 typename VertexIndexMap>
Chris@16 281 void
Chris@16 282 tsin_depth_first_visit
Chris@16 283 (const DistributedGraph& g,
Chris@16 284 typename graph_traits<DistributedGraph>::vertex_descriptor s,
Chris@16 285 DFSVisitor vis)
Chris@16 286 {
Chris@16 287 tsin_depth_first_visit(g, s, vis, get(vertex_index, g));
Chris@16 288 }
Chris@16 289 } // end namespace distributed
Chris@16 290
Chris@16 291 using distributed::tsin_depth_first_visit;
Chris@16 292
Chris@16 293 } // end namespace graph
Chris@16 294
Chris@16 295 template<typename DistributedGraph, typename DFSVisitor>
Chris@16 296 void
Chris@16 297 depth_first_visit
Chris@16 298 (const DistributedGraph& g,
Chris@16 299 typename graph_traits<DistributedGraph>::vertex_descriptor s,
Chris@16 300 DFSVisitor vis)
Chris@16 301 {
Chris@16 302 graph::tsin_depth_first_visit(g, s, vis, get(vertex_index, g));
Chris@16 303 }
Chris@16 304
Chris@16 305 } // end namespace boost
Chris@16 306
Chris@16 307 #endif // BOOST_GRAPH_DISTRIBUTED_DFS_HPP