vertex_list_adaptor.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. // Copyright (C) 2004-2006 The Trustees of Indiana University.
  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. // Authors: Douglas Gregor
  6. // Andrew Lumsdaine
  7. #ifndef BOOST_VERTEX_LIST_ADAPTOR_HPP
  8. #define BOOST_VERTEX_LIST_ADAPTOR_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. #include <boost/graph/graph_traits.hpp>
  13. #include <vector>
  14. #include <boost/shared_ptr.hpp>
  15. #include <boost/property_map/property_map.hpp>
  16. #include <boost/property_map/parallel/parallel_property_maps.hpp>
  17. #include <boost/graph/parallel/algorithm.hpp>
  18. #include <boost/graph/parallel/container_traits.hpp>
  19. #include <boost/property_map/vector_property_map.hpp>
  20. namespace boost { namespace graph {
  21. // --------------------------------------------------------------------------
  22. // Global index map built from a distribution
  23. // --------------------------------------------------------------------------
  24. template<typename Distribution, typename OwnerPropertyMap,
  25. typename LocalPropertyMap>
  26. class distribution_global_index_map
  27. {
  28. public:
  29. typedef std::size_t value_type;
  30. typedef value_type reference;
  31. typedef typename property_traits<OwnerPropertyMap>::key_type key_type;
  32. typedef readable_property_map_tag category;
  33. distribution_global_index_map(const Distribution& distribution,
  34. const OwnerPropertyMap& owner,
  35. const LocalPropertyMap& local)
  36. : distribution_(distribution), owner(owner), local(local) { }
  37. Distribution distribution_;
  38. OwnerPropertyMap owner;
  39. LocalPropertyMap local;
  40. };
  41. template<typename Distribution, typename OwnerPropertyMap,
  42. typename LocalPropertyMap>
  43. inline
  44. typename distribution_global_index_map<Distribution, OwnerPropertyMap,
  45. LocalPropertyMap>::value_type
  46. get(const distribution_global_index_map<Distribution, OwnerPropertyMap,
  47. LocalPropertyMap>& p,
  48. typename distribution_global_index_map<Distribution, OwnerPropertyMap,
  49. LocalPropertyMap>::key_type x)
  50. {
  51. using boost::get;
  52. return p.distribution_.global(get(p.owner, x), get(p.local, x));
  53. }
  54. template<typename Graph, typename Distribution>
  55. inline
  56. distribution_global_index_map<
  57. Distribution,
  58. typename property_map<Graph, vertex_owner_t>::const_type,
  59. typename property_map<Graph, vertex_local_t>::const_type>
  60. make_distribution_global_index_map(const Graph& g, const Distribution& d)
  61. {
  62. typedef distribution_global_index_map<
  63. Distribution,
  64. typename property_map<Graph, vertex_owner_t>::const_type,
  65. typename property_map<Graph, vertex_local_t>::const_type>
  66. result_type;
  67. return result_type(d, get(vertex_owner, g), get(vertex_local, g));
  68. }
  69. // --------------------------------------------------------------------------
  70. // Global index map built from a distributed index map and list of vertices
  71. // --------------------------------------------------------------------------
  72. template<typename IndexMap>
  73. class stored_global_index_map : public IndexMap
  74. {
  75. public:
  76. typedef readable_property_map_tag category;
  77. stored_global_index_map(const IndexMap& index_map) : IndexMap(index_map) {
  78. // When we have a global index, we need to always have the indices
  79. // of every key we've seen
  80. this->set_max_ghost_cells(0);
  81. }
  82. };
  83. // --------------------------------------------------------------------------
  84. // Global index map support code
  85. // --------------------------------------------------------------------------
  86. namespace detail {
  87. template<typename PropertyMap, typename ForwardIterator>
  88. inline void
  89. initialize_global_index_map(const PropertyMap&,
  90. ForwardIterator, ForwardIterator)
  91. { }
  92. template<typename IndexMap, typename ForwardIterator>
  93. void
  94. initialize_global_index_map(stored_global_index_map<IndexMap>& p,
  95. ForwardIterator first, ForwardIterator last)
  96. {
  97. using std::distance;
  98. typedef typename property_traits<IndexMap>::value_type size_t;
  99. size_t n = distance(first, last);
  100. for (size_t i = 0; i < n; ++i, ++first) local_put(p, *first, i);
  101. }
  102. }
  103. // --------------------------------------------------------------------------
  104. // Adapts a Distributed Vertex List Graph to a Vertex List Graph
  105. // --------------------------------------------------------------------------
  106. template<typename Graph, typename GlobalIndexMap>
  107. class vertex_list_adaptor : public graph_traits<Graph>
  108. {
  109. typedef graph_traits<Graph> inherited;
  110. typedef typename inherited::traversal_category base_traversal_category;
  111. public:
  112. typedef typename inherited::vertex_descriptor vertex_descriptor;
  113. typedef typename std::vector<vertex_descriptor>::iterator vertex_iterator;
  114. typedef typename std::vector<vertex_descriptor>::size_type
  115. vertices_size_type;
  116. struct traversal_category
  117. : public virtual base_traversal_category,
  118. public virtual vertex_list_graph_tag {};
  119. vertex_list_adaptor(const Graph& g,
  120. const GlobalIndexMap& index_map = GlobalIndexMap())
  121. : g(&g), index_map(index_map)
  122. {
  123. using boost::vertices;
  124. all_vertices_.reset(new std::vector<vertex_descriptor>());
  125. all_gather(process_group(), vertices(g).first, vertices(g).second,
  126. *all_vertices_);
  127. detail::initialize_global_index_map(this->index_map,
  128. all_vertices_->begin(),
  129. all_vertices_->end());
  130. }
  131. const Graph& base() const { return *g; }
  132. // --------------------------------------------------------------------------
  133. // Distributed Container
  134. // --------------------------------------------------------------------------
  135. typedef typename boost::graph::parallel::process_group_type<Graph>::type
  136. process_group_type;
  137. process_group_type process_group() const
  138. {
  139. using boost::graph::parallel::process_group;
  140. return process_group(*g);
  141. }
  142. std::pair<vertex_iterator, vertex_iterator> vertices() const
  143. { return std::make_pair(all_vertices_->begin(), all_vertices_->end()); }
  144. vertices_size_type num_vertices() const { return all_vertices_->size(); }
  145. GlobalIndexMap get_index_map() const { return index_map; }
  146. private:
  147. const Graph* g;
  148. GlobalIndexMap index_map;
  149. shared_ptr<std::vector<vertex_descriptor> > all_vertices_;
  150. };
  151. template<typename Graph, typename GlobalIndexMap>
  152. inline vertex_list_adaptor<Graph, GlobalIndexMap>
  153. make_vertex_list_adaptor(const Graph& g, const GlobalIndexMap& index_map)
  154. { return vertex_list_adaptor<Graph, GlobalIndexMap>(g, index_map); }
  155. namespace detail {
  156. template<typename Graph>
  157. class default_global_index_map
  158. {
  159. typedef typename graph_traits<Graph>::vertices_size_type value_type;
  160. typedef typename property_map<Graph, vertex_index_t>::const_type local_map;
  161. public:
  162. typedef vector_property_map<value_type, local_map> distributed_map;
  163. typedef stored_global_index_map<distributed_map> type;
  164. };
  165. }
  166. template<typename Graph>
  167. inline
  168. vertex_list_adaptor<Graph,
  169. typename detail::default_global_index_map<Graph>::type>
  170. make_vertex_list_adaptor(const Graph& g)
  171. {
  172. typedef typename detail::default_global_index_map<Graph>::type
  173. GlobalIndexMap;
  174. typedef typename detail::default_global_index_map<Graph>::distributed_map
  175. DistributedMap;
  176. typedef vertex_list_adaptor<Graph, GlobalIndexMap> result_type;
  177. return result_type(g,
  178. GlobalIndexMap(DistributedMap(num_vertices(g),
  179. get(vertex_index, g))));
  180. }
  181. // --------------------------------------------------------------------------
  182. // Incidence Graph
  183. // --------------------------------------------------------------------------
  184. template<typename Graph, typename GlobalIndexMap>
  185. inline typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor
  186. source(typename vertex_list_adaptor<Graph, GlobalIndexMap>::edge_descriptor e,
  187. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  188. { return source(e, g.base()); }
  189. template<typename Graph, typename GlobalIndexMap>
  190. inline typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor
  191. target(typename vertex_list_adaptor<Graph, GlobalIndexMap>::edge_descriptor e,
  192. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  193. { return target(e, g.base()); }
  194. template<typename Graph, typename GlobalIndexMap>
  195. inline
  196. std::pair<typename vertex_list_adaptor<Graph, GlobalIndexMap>::out_edge_iterator,
  197. typename vertex_list_adaptor<Graph, GlobalIndexMap>::out_edge_iterator>
  198. out_edges(typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor v,
  199. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  200. { return out_edges(v, g.base()); }
  201. template<typename Graph, typename GlobalIndexMap>
  202. inline typename vertex_list_adaptor<Graph, GlobalIndexMap>::degree_size_type
  203. out_degree(typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor v,
  204. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  205. { return out_degree(v, g.base()); }
  206. // --------------------------------------------------------------------------
  207. // Bidirectional Graph
  208. // --------------------------------------------------------------------------
  209. template<typename Graph, typename GlobalIndexMap>
  210. inline
  211. std::pair<typename vertex_list_adaptor<Graph, GlobalIndexMap>::in_edge_iterator,
  212. typename vertex_list_adaptor<Graph, GlobalIndexMap>::in_edge_iterator>
  213. in_edges(typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor v,
  214. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  215. { return in_edges(v, g.base()); }
  216. template<typename Graph, typename GlobalIndexMap>
  217. inline typename vertex_list_adaptor<Graph, GlobalIndexMap>::degree_size_type
  218. in_degree(typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor v,
  219. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  220. { return in_degree(v, g.base()); }
  221. template<typename Graph, typename GlobalIndexMap>
  222. inline typename vertex_list_adaptor<Graph, GlobalIndexMap>::degree_size_type
  223. degree(typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor v,
  224. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  225. { return degree(v, g.base()); }
  226. // --------------------------------------------------------------------------
  227. // Adjacency Graph
  228. // --------------------------------------------------------------------------
  229. template<typename Graph, typename GlobalIndexMap>
  230. inline
  231. std::pair<typename vertex_list_adaptor<Graph, GlobalIndexMap>::adjacency_iterator,
  232. typename vertex_list_adaptor<Graph, GlobalIndexMap>::adjacency_iterator>
  233. adjacent_vertices(typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor v,
  234. const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  235. { return adjacent_vertices(v, g.base()); }
  236. // --------------------------------------------------------------------------
  237. // Vertex List Graph
  238. // --------------------------------------------------------------------------
  239. template<typename Graph, typename GlobalIndexMap>
  240. inline
  241. std::pair<typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_iterator,
  242. typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_iterator>
  243. vertices(const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  244. { return g.vertices(); }
  245. template<typename Graph, typename GlobalIndexMap>
  246. inline
  247. typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertices_size_type
  248. num_vertices(const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  249. { return g.num_vertices(); }
  250. // --------------------------------------------------------------------------
  251. // Edge List Graph
  252. // --------------------------------------------------------------------------
  253. template<typename Graph, typename GlobalIndexMap>
  254. inline
  255. std::pair<typename vertex_list_adaptor<Graph, GlobalIndexMap>::edge_iterator,
  256. typename vertex_list_adaptor<Graph, GlobalIndexMap>::edge_iterator>
  257. edges(const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  258. { return edges(g.base()); }
  259. template<typename Graph, typename GlobalIndexMap>
  260. inline
  261. typename vertex_list_adaptor<Graph, GlobalIndexMap>::edges_size_type
  262. num_edges(const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  263. { return num_edges(g.base()); }
  264. // --------------------------------------------------------------------------
  265. // Property Graph
  266. // --------------------------------------------------------------------------
  267. template<typename PropertyTag, typename Graph, typename GlobalIndexMap>
  268. inline typename property_map<Graph, PropertyTag>::type
  269. get(PropertyTag p, vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  270. { return get(p, g.base()); }
  271. template<typename PropertyTag, typename Graph, typename GlobalIndexMap>
  272. inline typename property_map<Graph, PropertyTag>::const_type
  273. get(PropertyTag p, const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  274. { return get(p, g.base()); }
  275. template<typename PropertyTag, typename Graph, typename GlobalIndexMap>
  276. inline typename property_traits<
  277. typename property_map<Graph, PropertyTag>::type
  278. >::value_type
  279. get(PropertyTag p, const vertex_list_adaptor<Graph, GlobalIndexMap>& g,
  280. typename property_traits<
  281. typename property_map<Graph, PropertyTag>::type
  282. >::key_type const& x)
  283. { return get(p, g.base(), x); }
  284. template<typename PropertyTag, typename Graph, typename GlobalIndexMap>
  285. inline void
  286. put(PropertyTag p, vertex_list_adaptor<Graph, GlobalIndexMap>& g,
  287. typename property_traits<
  288. typename property_map<Graph, PropertyTag>::type
  289. >::key_type const& x,
  290. typename property_traits<
  291. typename property_map<Graph, PropertyTag>::type
  292. >::value_type const& v)
  293. { return put(p, g.base(), x, v); }
  294. // --------------------------------------------------------------------------
  295. // Property Graph: vertex_index property
  296. // --------------------------------------------------------------------------
  297. template<typename Graph, typename GlobalIndexMap>
  298. inline GlobalIndexMap
  299. get(vertex_index_t, const vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  300. { return g.get_index_map(); }
  301. template<typename Graph, typename GlobalIndexMap>
  302. inline typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertices_size_type
  303. get(vertex_index_t, const vertex_list_adaptor<Graph, GlobalIndexMap>& g,
  304. typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor x)
  305. { return get(g.get_index_map(), x); }
  306. // --------------------------------------------------------------------------
  307. // Adjacency Matrix Graph
  308. // --------------------------------------------------------------------------
  309. template<typename Graph, typename GlobalIndexMap>
  310. std::pair<typename vertex_list_adaptor<Graph, GlobalIndexMap>::edge_descriptor,
  311. bool>
  312. edge(typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor u,
  313. typename vertex_list_adaptor<Graph, GlobalIndexMap>::vertex_descriptor v,
  314. vertex_list_adaptor<Graph, GlobalIndexMap>& g)
  315. { return edge(u, v, g.base()); }
  316. } } // end namespace boost::graph
  317. namespace boost {
  318. // --------------------------------------------------------------------------
  319. // Property Graph: vertex_index property
  320. // --------------------------------------------------------------------------
  321. template<typename Graph, typename GlobalIndexMap>
  322. class property_map<vertex_index_t,
  323. graph::vertex_list_adaptor<Graph, GlobalIndexMap> >
  324. {
  325. public:
  326. typedef GlobalIndexMap type;
  327. typedef type const_type;
  328. };
  329. template<typename Graph, typename GlobalIndexMap>
  330. class property_map<vertex_index_t,
  331. const graph::vertex_list_adaptor<Graph, GlobalIndexMap> >
  332. {
  333. public:
  334. typedef GlobalIndexMap type;
  335. typedef type const_type;
  336. };
  337. using graph::distribution_global_index_map;
  338. using graph::make_distribution_global_index_map;
  339. using graph::stored_global_index_map;
  340. using graph::make_vertex_list_adaptor;
  341. using graph::vertex_list_adaptor;
  342. } // end namespace boost
  343. #endif // BOOST_VERTEX_LIST_ADAPTOR_HPP