initialize.hpp 11 KB

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