vertex_list_adaptor.hpp 16 KB

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