annotate DEPENDENCIES/generic/include/boost/graph/distributed/adjlist/initialize.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (C) 2007 Douglas Gregor
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 // This file contains code for the distributed adjacency list's
Chris@16 8 // initializations. It should not be included directly by users.
Chris@16 9
Chris@16 10 #ifndef BOOST_GRAPH_DISTRIBUTED_ADJLIST_INITIALIZE_HPP
Chris@16 11 #define BOOST_GRAPH_DISTRIBUTED_ADJLIST_INITIALIZE_HPP
Chris@16 12
Chris@16 13 #ifndef BOOST_GRAPH_USE_MPI
Chris@16 14 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
Chris@16 15 #endif
Chris@16 16
Chris@16 17 namespace boost {
Chris@16 18
Chris@16 19 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
Chris@16 20 template<typename EdgeIterator>
Chris@16 21 void
Chris@16 22 PBGL_DISTRIB_ADJLIST_TYPE::
Chris@16 23 initialize(EdgeIterator first, EdgeIterator last,
Chris@16 24 vertices_size_type, const base_distribution_type& distribution,
Chris@16 25 vecS)
Chris@16 26 {
Chris@16 27 process_id_type id = process_id(process_group_);
Chris@16 28 while (first != last) {
Chris@16 29 if ((process_id_type)distribution(first->first) == id) {
Chris@16 30 vertex_descriptor source(id, distribution.local(first->first));
Chris@16 31 vertex_descriptor target(distribution(first->second),
Chris@16 32 distribution.local(first->second));
Chris@16 33 add_edge(source, target, *this);
Chris@16 34 }
Chris@16 35 ++first;
Chris@16 36 }
Chris@16 37
Chris@16 38 synchronize(process_group_);
Chris@16 39 }
Chris@16 40
Chris@16 41 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
Chris@16 42 template<typename EdgeIterator, typename EdgePropertyIterator>
Chris@16 43 void
Chris@16 44 PBGL_DISTRIB_ADJLIST_TYPE::
Chris@16 45 initialize(EdgeIterator first, EdgeIterator last,
Chris@16 46 EdgePropertyIterator ep_iter,
Chris@16 47 vertices_size_type, const base_distribution_type& distribution,
Chris@16 48 vecS)
Chris@16 49 {
Chris@16 50 process_id_type id = process_id(process_group_);
Chris@16 51 while (first != last) {
Chris@16 52 if (static_cast<process_id_type>(distribution(first->first)) == id) {
Chris@16 53 vertex_descriptor source(id, distribution.local(first->first));
Chris@16 54 vertex_descriptor target(distribution(first->second),
Chris@16 55 distribution.local(first->second));
Chris@16 56 add_edge(source, target, *ep_iter, *this);
Chris@16 57 }
Chris@16 58 ++first;
Chris@16 59 ++ep_iter;
Chris@16 60 }
Chris@16 61
Chris@16 62 synchronize(process_group_);
Chris@16 63 }
Chris@16 64
Chris@16 65 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
Chris@16 66 template<typename EdgeIterator, typename EdgePropertyIterator,
Chris@16 67 typename VertexListS>
Chris@16 68 void
Chris@16 69 PBGL_DISTRIB_ADJLIST_TYPE::
Chris@16 70 initialize(EdgeIterator first, EdgeIterator last,
Chris@16 71 EdgePropertyIterator ep_iter,
Chris@16 72 vertices_size_type n, const base_distribution_type& distribution,
Chris@16 73 VertexListS)
Chris@16 74 {
Chris@16 75 using boost::parallel::inplace_all_to_all;
Chris@16 76
Chris@16 77 typedef vertices_size_type vertex_number_t;
Chris@16 78 typedef typename std::iterator_traits<EdgePropertyIterator>::value_type
Chris@16 79 edge_property_init_t;
Chris@16 80
Chris@16 81 typedef std::pair<vertex_descriptor, vertex_number_t>
Chris@16 82 st_pair;
Chris@16 83 typedef std::pair<st_pair, edge_property_init_t> delayed_edge_t;
Chris@16 84
Chris@16 85 process_group_type pg = process_group();
Chris@16 86 process_id_type id = process_id(pg);
Chris@16 87
Chris@16 88 // Vertex indices
Chris@16 89 std::vector<local_vertex_descriptor> index_to_vertex;
Chris@16 90 index_to_vertex.reserve(num_vertices(*this));
Chris@16 91 BGL_FORALL_VERTICES_T(v, base(), inherited)
Chris@16 92 index_to_vertex.push_back(v);
Chris@16 93
Chris@16 94 // The list of edges we can't add immediately.
Chris@16 95 std::vector<delayed_edge_t> delayed_edges;
Chris@16 96
Chris@16 97 std::vector<std::vector<vertex_number_t> > descriptor_requests;
Chris@16 98 descriptor_requests.resize(num_processes(pg));
Chris@16 99
Chris@16 100 // Add all of the edges we can, up to the point where we run
Chris@16 101 // into a descriptor we don't know.
Chris@16 102 while (first != last) {
Chris@16 103 if (distribution(first->first) == id) {
Chris@16 104 if (distribution(first->second) != id) break;
Chris@16 105 vertex_descriptor source
Chris@16 106 (id, index_to_vertex[distribution.local(first->first)]);
Chris@16 107 vertex_descriptor target
Chris@16 108 (distribution(first->second),
Chris@16 109 index_to_vertex[distribution.local(first->second)]);
Chris@16 110 add_edge(source, target, *ep_iter, *this);
Chris@16 111 }
Chris@16 112 ++first;
Chris@16 113 ++ep_iter;
Chris@16 114 }
Chris@16 115
Chris@16 116 // Queue all of the remaining edges and determine the set of
Chris@16 117 // descriptors we need to know about.
Chris@16 118 while (first != last) {
Chris@16 119 if (distribution(first->first) == id) {
Chris@16 120 vertex_descriptor source
Chris@16 121 (id, index_to_vertex[distribution.local(first->first)]);
Chris@16 122 process_id_type dest = distribution(first->second);
Chris@16 123 if (dest != id) {
Chris@16 124 descriptor_requests[dest]
Chris@16 125 .push_back(distribution.local(first->second));
Chris@16 126 // Compact request list if we need to
Chris@16 127 if (descriptor_requests[dest].size() >
Chris@16 128 distribution.block_size(dest, n)) {
Chris@16 129 std::sort(descriptor_requests[dest].begin(),
Chris@16 130 descriptor_requests[dest].end());
Chris@16 131 descriptor_requests[dest].erase(
Chris@16 132 std::unique(descriptor_requests[dest].begin(),
Chris@16 133 descriptor_requests[dest].end()),
Chris@16 134 descriptor_requests[dest].end());
Chris@16 135 }
Chris@16 136 }
Chris@16 137
Chris@16 138 // Save the edge for later
Chris@16 139 delayed_edges.push_back
Chris@16 140 (delayed_edge_t(st_pair(source, first->second), *ep_iter));
Chris@16 141 }
Chris@16 142 ++first;
Chris@16 143 ++ep_iter;
Chris@16 144 }
Chris@16 145
Chris@16 146 // Compact descriptor requests
Chris@16 147 for (process_id_type dest = 0; dest < num_processes(pg); ++dest) {
Chris@16 148 std::sort(descriptor_requests[dest].begin(),
Chris@16 149 descriptor_requests[dest].end());
Chris@16 150 descriptor_requests[dest].erase(
Chris@16 151 std::unique(descriptor_requests[dest].begin(),
Chris@16 152 descriptor_requests[dest].end()),
Chris@16 153 descriptor_requests[dest].end());
Chris@16 154 }
Chris@16 155
Chris@16 156 // Send out all of the descriptor requests
Chris@16 157 std::vector<std::vector<vertex_number_t> > in_descriptor_requests;
Chris@16 158 in_descriptor_requests.resize(num_processes(pg));
Chris@16 159 inplace_all_to_all(pg, descriptor_requests, in_descriptor_requests);
Chris@16 160
Chris@16 161 // Reply to all of the descriptor requests
Chris@16 162 std::vector<std::vector<local_vertex_descriptor> >
Chris@16 163 descriptor_responses;
Chris@16 164 descriptor_responses.resize(num_processes(pg));
Chris@16 165 for (process_id_type dest = 0; dest < num_processes(pg); ++dest) {
Chris@16 166 for (std::size_t i = 0; i < in_descriptor_requests[dest].size(); ++i) {
Chris@16 167 local_vertex_descriptor v =
Chris@16 168 index_to_vertex[in_descriptor_requests[dest][i]];
Chris@16 169 descriptor_responses[dest].push_back(v);
Chris@16 170 }
Chris@16 171 in_descriptor_requests[dest].clear();
Chris@16 172 }
Chris@16 173 in_descriptor_requests.clear();
Chris@16 174 inplace_all_to_all(pg, descriptor_responses);
Chris@16 175
Chris@16 176 // Add the queued edges
Chris@16 177 for(typename std::vector<delayed_edge_t>::iterator i
Chris@16 178 = delayed_edges.begin(); i != delayed_edges.end(); ++i) {
Chris@16 179 process_id_type dest = distribution(i->first.second);
Chris@16 180 local_vertex_descriptor tgt_local;
Chris@16 181 if (dest == id) {
Chris@16 182 tgt_local = index_to_vertex[distribution.local(i->first.second)];
Chris@16 183 } else {
Chris@16 184 std::vector<vertex_number_t>& requests = descriptor_requests[dest];
Chris@16 185 typename std::vector<vertex_number_t>::iterator pos =
Chris@16 186 std::lower_bound(requests.begin(), requests.end(),
Chris@16 187 distribution.local(i->first.second));
Chris@16 188 tgt_local = descriptor_responses[dest][pos - requests.begin()];
Chris@16 189 }
Chris@16 190 add_edge(i->first.first, vertex_descriptor(dest, tgt_local),
Chris@16 191 i->second, *this);
Chris@16 192 }
Chris@16 193 synchronize(process_group_);
Chris@16 194 }
Chris@16 195
Chris@16 196 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
Chris@16 197 template<typename EdgeIterator, typename VertexListS>
Chris@16 198 void
Chris@16 199 PBGL_DISTRIB_ADJLIST_TYPE::
Chris@16 200 initialize(EdgeIterator first, EdgeIterator last,
Chris@16 201 vertices_size_type n, const base_distribution_type& distribution,
Chris@16 202 VertexListS)
Chris@16 203 {
Chris@16 204 using boost::parallel::inplace_all_to_all;
Chris@16 205
Chris@16 206 typedef vertices_size_type vertex_number_t;
Chris@16 207
Chris@16 208 typedef std::pair<vertex_descriptor, vertex_number_t> delayed_edge_t;
Chris@16 209
Chris@16 210 process_group_type pg = process_group();
Chris@16 211 process_id_type id = process_id(pg);
Chris@16 212
Chris@16 213 // Vertex indices
Chris@16 214 std::vector<local_vertex_descriptor> index_to_vertex;
Chris@16 215 index_to_vertex.reserve(num_vertices(*this));
Chris@16 216 BGL_FORALL_VERTICES_T(v, base(), inherited)
Chris@16 217 index_to_vertex.push_back(v);
Chris@16 218
Chris@16 219 // The list of edges we can't add immediately.
Chris@16 220 std::vector<delayed_edge_t> delayed_edges;
Chris@16 221
Chris@16 222 std::vector<std::vector<vertex_number_t> > descriptor_requests;
Chris@16 223 descriptor_requests.resize(num_processes(pg));
Chris@16 224
Chris@16 225 // Add all of the edges we can, up to the point where we run
Chris@16 226 // into a descriptor we don't know.
Chris@16 227 while (first != last) {
Chris@16 228 if (distribution(first->first) == id) {
Chris@16 229 if (distribution(first->second) != id) break;
Chris@16 230 vertex_descriptor source
Chris@16 231 (id, index_to_vertex[distribution.local(first->first)]);
Chris@16 232 vertex_descriptor target
Chris@16 233 (distribution(first->second),
Chris@16 234 index_to_vertex[distribution.local(first->second)]);
Chris@16 235 add_edge(source, target, *this);
Chris@16 236 }
Chris@16 237 ++first;
Chris@16 238 }
Chris@16 239
Chris@16 240 // Queue all of the remaining edges and determine the set of
Chris@16 241 // descriptors we need to know about.
Chris@16 242 while (first != last) {
Chris@16 243 if (distribution(first->first) == id) {
Chris@16 244 vertex_descriptor source
Chris@16 245 (id, index_to_vertex[distribution.local(first->first)]);
Chris@16 246 process_id_type dest = distribution(first->second);
Chris@16 247 if (dest != id) {
Chris@16 248 descriptor_requests[dest]
Chris@16 249 .push_back(distribution.local(first->second));
Chris@16 250 // Compact request list if we need to
Chris@16 251 if (descriptor_requests[dest].size() >
Chris@16 252 distribution.block_size(dest, n)) {
Chris@16 253 std::sort(descriptor_requests[dest].begin(),
Chris@16 254 descriptor_requests[dest].end());
Chris@16 255 descriptor_requests[dest].erase(
Chris@16 256 std::unique(descriptor_requests[dest].begin(),
Chris@16 257 descriptor_requests[dest].end()),
Chris@16 258 descriptor_requests[dest].end());
Chris@16 259 }
Chris@16 260 }
Chris@16 261
Chris@16 262 // Save the edge for later
Chris@16 263 delayed_edges.push_back(delayed_edge_t(source, first->second));
Chris@16 264 }
Chris@16 265 ++first;
Chris@16 266 }
Chris@16 267
Chris@16 268 // Compact descriptor requests
Chris@16 269 for (process_id_type dest = 0; dest < num_processes(pg); ++dest) {
Chris@16 270 std::sort(descriptor_requests[dest].begin(),
Chris@16 271 descriptor_requests[dest].end());
Chris@16 272 descriptor_requests[dest].erase(
Chris@16 273 std::unique(descriptor_requests[dest].begin(),
Chris@16 274 descriptor_requests[dest].end()),
Chris@16 275 descriptor_requests[dest].end());
Chris@16 276 }
Chris@16 277
Chris@16 278 // Send out all of the descriptor requests
Chris@16 279 std::vector<std::vector<vertex_number_t> > in_descriptor_requests;
Chris@16 280 in_descriptor_requests.resize(num_processes(pg));
Chris@16 281 inplace_all_to_all(pg, descriptor_requests, in_descriptor_requests);
Chris@16 282
Chris@16 283 // Reply to all of the descriptor requests
Chris@16 284 std::vector<std::vector<local_vertex_descriptor> >
Chris@16 285 descriptor_responses;
Chris@16 286 descriptor_responses.resize(num_processes(pg));
Chris@16 287 for (process_id_type dest = 0; dest < num_processes(pg); ++dest) {
Chris@16 288 for (std::size_t i = 0; i < in_descriptor_requests[dest].size(); ++i) {
Chris@16 289 local_vertex_descriptor v =
Chris@16 290 index_to_vertex[in_descriptor_requests[dest][i]];
Chris@16 291 descriptor_responses[dest].push_back(v);
Chris@16 292 }
Chris@16 293 in_descriptor_requests[dest].clear();
Chris@16 294 }
Chris@16 295 in_descriptor_requests.clear();
Chris@16 296 inplace_all_to_all(pg, descriptor_responses);
Chris@16 297
Chris@16 298 // Add the queued edges
Chris@16 299 for(typename std::vector<delayed_edge_t>::iterator i
Chris@16 300 = delayed_edges.begin(); i != delayed_edges.end(); ++i) {
Chris@16 301 process_id_type dest = distribution(i->second);
Chris@16 302 local_vertex_descriptor tgt_local;
Chris@16 303 if (dest == id) {
Chris@16 304 tgt_local = index_to_vertex[distribution.local(i->second)];
Chris@16 305 } else {
Chris@16 306 std::vector<vertex_number_t>& requests = descriptor_requests[dest];
Chris@16 307 typename std::vector<vertex_number_t>::iterator pos =
Chris@16 308 std::lower_bound(requests.begin(), requests.end(),
Chris@16 309 distribution.local(i->second));
Chris@16 310 tgt_local = descriptor_responses[dest][pos - requests.begin()];
Chris@16 311 }
Chris@16 312 add_edge(i->first, vertex_descriptor(dest, tgt_local), *this);
Chris@16 313 }
Chris@16 314 synchronize(process_group_);
Chris@16 315 }
Chris@16 316
Chris@16 317 } // end namespace boost
Chris@16 318
Chris@16 319 #endif // BOOST_GRAPH_DISTRIBUTED_ADJLIST_INITIALIZE_HPP