Chris@16
|
1 // Copyright 2004 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_PARALLEL_BFS_HPP
|
Chris@16
|
10 #define BOOST_GRAPH_PARALLEL_BFS_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/breadth_first_search.hpp>
|
Chris@16
|
17 #include <boost/graph/overloading.hpp>
|
Chris@16
|
18 #include <boost/graph/distributed/concepts.hpp>
|
Chris@16
|
19 #include <boost/graph/distributed/detail/filtered_queue.hpp>
|
Chris@16
|
20 #include <boost/graph/distributed/queue.hpp>
|
Chris@16
|
21 #include <boost/dynamic_bitset.hpp>
|
Chris@16
|
22 #include <boost/pending/queue.hpp>
|
Chris@16
|
23 #include <boost/graph/parallel/properties.hpp>
|
Chris@16
|
24 #include <boost/graph/parallel/container_traits.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 namespace boost {
|
Chris@16
|
27 namespace detail {
|
Chris@16
|
28 /** @brief A unary predicate that decides when to push into a
|
Chris@16
|
29 * breadth-first search queue.
|
Chris@16
|
30 *
|
Chris@16
|
31 * This predicate stores a color map that is used to determine
|
Chris@16
|
32 * when to push. If it is provided with a key for which the color
|
Chris@16
|
33 * is white, it darkens the color to gray and returns true (so
|
Chris@16
|
34 * that the value will be pushed appropriately); if the color is
|
Chris@16
|
35 * not white, it returns false so that the vertex will be
|
Chris@16
|
36 * ignored.
|
Chris@16
|
37 */
|
Chris@16
|
38 template<typename ColorMap>
|
Chris@16
|
39 struct darken_and_push
|
Chris@16
|
40 {
|
Chris@16
|
41 typedef typename property_traits<ColorMap>::key_type argument_type;
|
Chris@16
|
42 typedef bool result_type;
|
Chris@16
|
43
|
Chris@16
|
44 explicit darken_and_push(const ColorMap& color) : color(color) { }
|
Chris@16
|
45
|
Chris@16
|
46 bool operator()(const argument_type& value) const
|
Chris@16
|
47 {
|
Chris@16
|
48 typedef color_traits<typename property_traits<ColorMap>::value_type>
|
Chris@16
|
49 Color;
|
Chris@16
|
50 if (get(color, value) == Color::white()) {
|
Chris@16
|
51 put(color, value, Color::gray());
|
Chris@16
|
52 return true;
|
Chris@16
|
53 } else {
|
Chris@16
|
54 return false;
|
Chris@16
|
55 }
|
Chris@16
|
56 }
|
Chris@16
|
57
|
Chris@16
|
58 ColorMap color;
|
Chris@16
|
59 };
|
Chris@16
|
60
|
Chris@16
|
61 template<typename IndexMap>
|
Chris@16
|
62 struct has_not_been_seen
|
Chris@16
|
63 {
|
Chris@16
|
64 typedef bool result_type;
|
Chris@16
|
65
|
Chris@16
|
66 has_not_been_seen() { }
|
Chris@16
|
67
|
Chris@16
|
68 has_not_been_seen(std::size_t n, IndexMap index_map)
|
Chris@16
|
69 : seen(n), index_map(index_map) {}
|
Chris@16
|
70
|
Chris@16
|
71 template<typename Key>
|
Chris@16
|
72 result_type operator()(Key key)
|
Chris@16
|
73 {
|
Chris@16
|
74 bool result = seen[get(index_map, key)];
|
Chris@16
|
75 seen[get(index_map, key)] = true;
|
Chris@16
|
76 return !result;
|
Chris@16
|
77 }
|
Chris@16
|
78
|
Chris@16
|
79 void swap(has_not_been_seen& other)
|
Chris@16
|
80 {
|
Chris@16
|
81 using std::swap;
|
Chris@16
|
82 swap(seen, other.seen);
|
Chris@16
|
83 swap(index_map, other.index_map);
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 private:
|
Chris@16
|
87 dynamic_bitset<> seen;
|
Chris@16
|
88 IndexMap index_map;
|
Chris@16
|
89 };
|
Chris@16
|
90
|
Chris@16
|
91 template<typename IndexMap>
|
Chris@16
|
92 inline void
|
Chris@16
|
93 swap(has_not_been_seen<IndexMap>& x, has_not_been_seen<IndexMap>& y)
|
Chris@16
|
94 {
|
Chris@16
|
95 x.swap(y);
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 template <class DistributedGraph, class ColorMap, class BFSVisitor,
|
Chris@16
|
99 class BufferRef, class VertexIndexMap>
|
Chris@16
|
100 inline void
|
Chris@16
|
101 parallel_bfs_helper
|
Chris@16
|
102 (DistributedGraph& g,
|
Chris@16
|
103 typename graph_traits<DistributedGraph>::vertex_descriptor s,
|
Chris@16
|
104 ColorMap color,
|
Chris@16
|
105 BFSVisitor vis,
|
Chris@16
|
106 BufferRef Q,
|
Chris@16
|
107 VertexIndexMap)
|
Chris@16
|
108 {
|
Chris@16
|
109 set_property_map_role(vertex_color, color);
|
Chris@16
|
110 color.set_consistency_model(0);
|
Chris@16
|
111 breadth_first_search(g, s, Q.ref, vis, color);
|
Chris@16
|
112 }
|
Chris@16
|
113
|
Chris@16
|
114 template <class DistributedGraph, class ColorMap, class BFSVisitor,
|
Chris@16
|
115 class VertexIndexMap>
|
Chris@16
|
116 void parallel_bfs_helper
|
Chris@16
|
117 (DistributedGraph& g,
|
Chris@16
|
118 typename graph_traits<DistributedGraph>::vertex_descriptor s,
|
Chris@16
|
119 ColorMap color,
|
Chris@16
|
120 BFSVisitor vis,
|
Chris@16
|
121 boost::param_not_found,
|
Chris@16
|
122 VertexIndexMap vertex_index)
|
Chris@16
|
123 {
|
Chris@16
|
124 using boost::graph::parallel::process_group;
|
Chris@16
|
125
|
Chris@16
|
126 typedef graph_traits<DistributedGraph> Traits;
|
Chris@16
|
127 typedef typename Traits::vertex_descriptor Vertex;
|
Chris@16
|
128 typedef typename boost::graph::parallel::process_group_type<DistributedGraph>::type
|
Chris@16
|
129 process_group_type;
|
Chris@16
|
130
|
Chris@16
|
131 set_property_map_role(vertex_color, color);
|
Chris@16
|
132 color.set_consistency_model(0);
|
Chris@16
|
133
|
Chris@16
|
134 // Buffer default
|
Chris@16
|
135 typedef typename property_map<DistributedGraph, vertex_owner_t>
|
Chris@16
|
136 ::const_type vertex_owner_map;
|
Chris@16
|
137 typedef boost::graph::distributed::distributed_queue<
|
Chris@16
|
138 process_group_type, vertex_owner_map, queue<Vertex>,
|
Chris@16
|
139 detail::darken_and_push<ColorMap> > queue_t;
|
Chris@16
|
140 queue_t Q(process_group(g),
|
Chris@16
|
141 get(vertex_owner, g),
|
Chris@16
|
142 detail::darken_and_push<ColorMap>(color));
|
Chris@16
|
143 breadth_first_search(g, s, Q, vis, color);
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 template <class DistributedGraph, class ColorMap, class BFSVisitor,
|
Chris@16
|
147 class P, class T, class R>
|
Chris@16
|
148 void bfs_helper
|
Chris@16
|
149 (DistributedGraph& g,
|
Chris@16
|
150 typename graph_traits<DistributedGraph>::vertex_descriptor s,
|
Chris@16
|
151 ColorMap color,
|
Chris@16
|
152 BFSVisitor vis,
|
Chris@16
|
153 const bgl_named_params<P, T, R>& params,
|
Chris@16
|
154 boost::mpl::true_)
|
Chris@16
|
155 {
|
Chris@16
|
156 parallel_bfs_helper
|
Chris@16
|
157 (g, s, color, vis, get_param(params, buffer_param_t()),
|
Chris@16
|
158 choose_const_pmap(get_param(params, vertex_index), g, vertex_index));
|
Chris@16
|
159 }
|
Chris@16
|
160 }
|
Chris@16
|
161 }
|
Chris@16
|
162
|
Chris@16
|
163 #endif // BOOST_GRAPH_PARALLEL_BFS_HPP
|