local_subgraph.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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_GRAPH_LOCAL_SUBGRAPH_HPP
  8. #define BOOST_GRAPH_LOCAL_SUBGRAPH_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 <boost/graph/filtered_graph.hpp>
  14. #include <boost/type_traits/is_same.hpp>
  15. #include <boost/type_traits/is_base_and_derived.hpp>
  16. #include <boost/graph/parallel/container_traits.hpp>
  17. namespace boost {
  18. namespace graph { namespace detail {
  19. // Optionally, virtually derive from a base class
  20. template<bool Derive, typename Base> struct derive_from_if;
  21. template<typename Base> struct derive_from_if<true, Base> : virtual Base {};
  22. template<typename Base> struct derive_from_if<false, Base> {};
  23. template<typename NewBase, typename Tag, typename OldBase = NewBase>
  24. struct derive_from_if_tag_is :
  25. derive_from_if<(is_base_and_derived<OldBase, Tag>::value
  26. || is_same<OldBase, Tag>::value),
  27. NewBase>
  28. {
  29. };
  30. } } // end namespace graph::detail
  31. template<typename DistributedGraph>
  32. class is_local_edge
  33. {
  34. public:
  35. typedef bool result_type;
  36. typedef typename graph_traits<DistributedGraph>::edge_descriptor
  37. argument_type;
  38. is_local_edge() : g(0) {}
  39. is_local_edge(DistributedGraph& g) : g(&g), owner(get(vertex_owner, g)) {}
  40. // Since either the source or target vertex must be local, the
  41. // equivalence of their owners indicates a local edge.
  42. result_type operator()(const argument_type& e) const
  43. { return get(owner, source(e, *g)) == get(owner, target(e, *g)); }
  44. private:
  45. DistributedGraph* g;
  46. typename property_map<DistributedGraph, vertex_owner_t>::const_type owner;
  47. };
  48. template<typename DistributedGraph>
  49. class is_local_vertex
  50. {
  51. public:
  52. typedef bool result_type;
  53. typedef typename graph_traits<DistributedGraph>::vertex_descriptor
  54. argument_type;
  55. is_local_vertex() : g(0) {}
  56. is_local_vertex(DistributedGraph& g) : g(&g), owner(get(vertex_owner, g)) { }
  57. // Since either the source or target vertex must be local, the
  58. // equivalence of their owners indicates a local edge.
  59. result_type operator()(const argument_type& v) const
  60. {
  61. return get(owner, v) == process_id(process_group(*g));
  62. }
  63. private:
  64. DistributedGraph* g;
  65. typename property_map<DistributedGraph, vertex_owner_t>::const_type owner;
  66. };
  67. template<typename DistributedGraph>
  68. class local_subgraph
  69. : public filtered_graph<DistributedGraph,
  70. is_local_edge<DistributedGraph>,
  71. is_local_vertex<DistributedGraph> >
  72. {
  73. typedef filtered_graph<DistributedGraph,
  74. is_local_edge<DistributedGraph>,
  75. is_local_vertex<DistributedGraph> >
  76. inherited;
  77. typedef typename graph_traits<DistributedGraph>::traversal_category
  78. inherited_category;
  79. public:
  80. struct traversal_category :
  81. graph::detail::derive_from_if_tag_is<incidence_graph_tag,
  82. inherited_category>,
  83. graph::detail::derive_from_if_tag_is<adjacency_graph_tag,
  84. inherited_category>,
  85. graph::detail::derive_from_if_tag_is<vertex_list_graph_tag,
  86. inherited_category>,
  87. graph::detail::derive_from_if_tag_is<edge_list_graph_tag,
  88. inherited_category>,
  89. graph::detail::derive_from_if_tag_is<vertex_list_graph_tag,
  90. inherited_category,
  91. distributed_vertex_list_graph_tag>,
  92. graph::detail::derive_from_if_tag_is<edge_list_graph_tag,
  93. inherited_category,
  94. distributed_edge_list_graph_tag>
  95. { };
  96. local_subgraph(DistributedGraph& g)
  97. : inherited(g,
  98. is_local_edge<DistributedGraph>(g),
  99. is_local_vertex<DistributedGraph>(g)),
  100. g(g)
  101. {
  102. }
  103. // Distributed Container
  104. typedef typename boost::graph::parallel::process_group_type<DistributedGraph>::type
  105. process_group_type;
  106. process_group_type& process_group()
  107. {
  108. using boost::graph::parallel::process_group;
  109. return process_group(g);
  110. }
  111. const process_group_type& process_group() const
  112. {
  113. using boost::graph::parallel::process_group;
  114. return boost::graph::parallel::process_group(g);
  115. }
  116. DistributedGraph& base() { return g; }
  117. const DistributedGraph& base() const { return g; }
  118. private:
  119. DistributedGraph& g;
  120. };
  121. template<typename DistributedGraph, typename PropertyTag>
  122. class property_map<local_subgraph<DistributedGraph>, PropertyTag>
  123. : public property_map<DistributedGraph, PropertyTag> { };
  124. template<typename DistributedGraph, typename PropertyTag>
  125. class property_map<local_subgraph<const DistributedGraph>, PropertyTag>
  126. {
  127. public:
  128. typedef typename property_map<DistributedGraph, PropertyTag>::const_type
  129. type;
  130. typedef type const_type;
  131. };
  132. template<typename PropertyTag, typename DistributedGraph>
  133. inline typename property_map<local_subgraph<DistributedGraph>, PropertyTag>::type
  134. get(PropertyTag p, local_subgraph<DistributedGraph>& g)
  135. { return get(p, g.base()); }
  136. template<typename PropertyTag, typename DistributedGraph>
  137. inline typename property_map<local_subgraph<DistributedGraph>, PropertyTag>
  138. ::const_type
  139. get(PropertyTag p, const local_subgraph<DistributedGraph>& g)
  140. { return get(p, g.base()); }
  141. template<typename DistributedGraph>
  142. inline local_subgraph<DistributedGraph>
  143. make_local_subgraph(DistributedGraph& g)
  144. { return local_subgraph<DistributedGraph>(g); }
  145. } // end namespace boost
  146. #endif // BOOST_GRAPH_LOCAL_SUBGRAPH_HPP