Chris@16
|
1 // Copyright (C) 2004-2006 The Trustees of Indiana University.
|
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 // Authors: Douglas Gregor
|
Chris@16
|
8 // Andrew Lumsdaine
|
Chris@16
|
9 #ifndef BOOST_GRAPH_LOCAL_SUBGRAPH_HPP
|
Chris@16
|
10 #define BOOST_GRAPH_LOCAL_SUBGRAPH_HPP
|
Chris@16
|
11
|
Chris@16
|
12 #ifndef BOOST_GRAPH_USE_MPI
|
Chris@16
|
13 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/graph/graph_traits.hpp>
|
Chris@16
|
17 #include <boost/graph/filtered_graph.hpp>
|
Chris@16
|
18 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
19 #include <boost/type_traits/is_base_and_derived.hpp>
|
Chris@16
|
20 #include <boost/graph/parallel/container_traits.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost {
|
Chris@16
|
23
|
Chris@16
|
24 namespace graph { namespace detail {
|
Chris@16
|
25 // Optionally, virtually derive from a base class
|
Chris@16
|
26 template<bool Derive, typename Base> struct derive_from_if;
|
Chris@16
|
27 template<typename Base> struct derive_from_if<true, Base> : virtual Base {};
|
Chris@16
|
28 template<typename Base> struct derive_from_if<false, Base> {};
|
Chris@16
|
29
|
Chris@16
|
30 template<typename NewBase, typename Tag, typename OldBase = NewBase>
|
Chris@16
|
31 struct derive_from_if_tag_is :
|
Chris@16
|
32 derive_from_if<(is_base_and_derived<OldBase, Tag>::value
|
Chris@16
|
33 || is_same<OldBase, Tag>::value),
|
Chris@16
|
34 NewBase>
|
Chris@16
|
35 {
|
Chris@16
|
36 };
|
Chris@16
|
37 } } // end namespace graph::detail
|
Chris@16
|
38
|
Chris@16
|
39 template<typename DistributedGraph>
|
Chris@16
|
40 class is_local_edge
|
Chris@16
|
41 {
|
Chris@16
|
42 public:
|
Chris@16
|
43 typedef bool result_type;
|
Chris@16
|
44 typedef typename graph_traits<DistributedGraph>::edge_descriptor
|
Chris@16
|
45 argument_type;
|
Chris@16
|
46
|
Chris@16
|
47 is_local_edge() : g(0) {}
|
Chris@16
|
48 is_local_edge(DistributedGraph& g) : g(&g), owner(get(vertex_owner, g)) {}
|
Chris@16
|
49
|
Chris@16
|
50 // Since either the source or target vertex must be local, the
|
Chris@16
|
51 // equivalence of their owners indicates a local edge.
|
Chris@16
|
52 result_type operator()(const argument_type& e) const
|
Chris@16
|
53 { return get(owner, source(e, *g)) == get(owner, target(e, *g)); }
|
Chris@16
|
54
|
Chris@16
|
55 private:
|
Chris@16
|
56 DistributedGraph* g;
|
Chris@16
|
57 typename property_map<DistributedGraph, vertex_owner_t>::const_type owner;
|
Chris@16
|
58 };
|
Chris@16
|
59
|
Chris@16
|
60 template<typename DistributedGraph>
|
Chris@16
|
61 class is_local_vertex
|
Chris@16
|
62 {
|
Chris@16
|
63 public:
|
Chris@16
|
64 typedef bool result_type;
|
Chris@16
|
65 typedef typename graph_traits<DistributedGraph>::vertex_descriptor
|
Chris@16
|
66 argument_type;
|
Chris@16
|
67
|
Chris@16
|
68 is_local_vertex() : g(0) {}
|
Chris@16
|
69 is_local_vertex(DistributedGraph& g) : g(&g), owner(get(vertex_owner, g)) { }
|
Chris@16
|
70
|
Chris@16
|
71 // Since either the source or target vertex must be local, the
|
Chris@16
|
72 // equivalence of their owners indicates a local edge.
|
Chris@16
|
73 result_type operator()(const argument_type& v) const
|
Chris@16
|
74 {
|
Chris@16
|
75 return get(owner, v) == process_id(process_group(*g));
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 private:
|
Chris@16
|
79 DistributedGraph* g;
|
Chris@16
|
80 typename property_map<DistributedGraph, vertex_owner_t>::const_type owner;
|
Chris@16
|
81 };
|
Chris@16
|
82
|
Chris@16
|
83 template<typename DistributedGraph>
|
Chris@16
|
84 class local_subgraph
|
Chris@16
|
85 : public filtered_graph<DistributedGraph,
|
Chris@16
|
86 is_local_edge<DistributedGraph>,
|
Chris@16
|
87 is_local_vertex<DistributedGraph> >
|
Chris@16
|
88 {
|
Chris@16
|
89 typedef filtered_graph<DistributedGraph,
|
Chris@16
|
90 is_local_edge<DistributedGraph>,
|
Chris@16
|
91 is_local_vertex<DistributedGraph> >
|
Chris@16
|
92 inherited;
|
Chris@16
|
93 typedef typename graph_traits<DistributedGraph>::traversal_category
|
Chris@16
|
94 inherited_category;
|
Chris@16
|
95
|
Chris@16
|
96 public:
|
Chris@16
|
97 struct traversal_category :
|
Chris@16
|
98 graph::detail::derive_from_if_tag_is<incidence_graph_tag,
|
Chris@16
|
99 inherited_category>,
|
Chris@16
|
100 graph::detail::derive_from_if_tag_is<adjacency_graph_tag,
|
Chris@16
|
101 inherited_category>,
|
Chris@16
|
102 graph::detail::derive_from_if_tag_is<vertex_list_graph_tag,
|
Chris@16
|
103 inherited_category>,
|
Chris@16
|
104 graph::detail::derive_from_if_tag_is<edge_list_graph_tag,
|
Chris@16
|
105 inherited_category>,
|
Chris@16
|
106 graph::detail::derive_from_if_tag_is<vertex_list_graph_tag,
|
Chris@16
|
107 inherited_category,
|
Chris@16
|
108 distributed_vertex_list_graph_tag>,
|
Chris@16
|
109 graph::detail::derive_from_if_tag_is<edge_list_graph_tag,
|
Chris@16
|
110 inherited_category,
|
Chris@16
|
111 distributed_edge_list_graph_tag>
|
Chris@16
|
112 { };
|
Chris@16
|
113
|
Chris@16
|
114 local_subgraph(DistributedGraph& g)
|
Chris@16
|
115 : inherited(g,
|
Chris@16
|
116 is_local_edge<DistributedGraph>(g),
|
Chris@16
|
117 is_local_vertex<DistributedGraph>(g)),
|
Chris@16
|
118 g(g)
|
Chris@16
|
119 {
|
Chris@16
|
120 }
|
Chris@16
|
121
|
Chris@16
|
122 // Distributed Container
|
Chris@16
|
123 typedef typename boost::graph::parallel::process_group_type<DistributedGraph>::type
|
Chris@16
|
124 process_group_type;
|
Chris@16
|
125
|
Chris@16
|
126 process_group_type& process_group()
|
Chris@16
|
127 {
|
Chris@16
|
128 using boost::graph::parallel::process_group;
|
Chris@16
|
129 return process_group(g);
|
Chris@16
|
130 }
|
Chris@16
|
131 const process_group_type& process_group() const
|
Chris@16
|
132 {
|
Chris@16
|
133 using boost::graph::parallel::process_group;
|
Chris@16
|
134 return boost::graph::parallel::process_group(g);
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 DistributedGraph& base() { return g; }
|
Chris@16
|
138 const DistributedGraph& base() const { return g; }
|
Chris@16
|
139
|
Chris@16
|
140 private:
|
Chris@16
|
141 DistributedGraph& g;
|
Chris@16
|
142 };
|
Chris@16
|
143
|
Chris@16
|
144 template<typename DistributedGraph, typename PropertyTag>
|
Chris@16
|
145 class property_map<local_subgraph<DistributedGraph>, PropertyTag>
|
Chris@16
|
146 : public property_map<DistributedGraph, PropertyTag> { };
|
Chris@16
|
147
|
Chris@16
|
148 template<typename DistributedGraph, typename PropertyTag>
|
Chris@16
|
149 class property_map<local_subgraph<const DistributedGraph>, PropertyTag>
|
Chris@16
|
150 {
|
Chris@16
|
151 public:
|
Chris@16
|
152 typedef typename property_map<DistributedGraph, PropertyTag>::const_type
|
Chris@16
|
153 type;
|
Chris@16
|
154 typedef type const_type;
|
Chris@16
|
155 };
|
Chris@16
|
156
|
Chris@16
|
157 template<typename PropertyTag, typename DistributedGraph>
|
Chris@16
|
158 inline typename property_map<local_subgraph<DistributedGraph>, PropertyTag>::type
|
Chris@16
|
159 get(PropertyTag p, local_subgraph<DistributedGraph>& g)
|
Chris@16
|
160 { return get(p, g.base()); }
|
Chris@16
|
161
|
Chris@16
|
162 template<typename PropertyTag, typename DistributedGraph>
|
Chris@16
|
163 inline typename property_map<local_subgraph<DistributedGraph>, PropertyTag>
|
Chris@16
|
164 ::const_type
|
Chris@16
|
165 get(PropertyTag p, const local_subgraph<DistributedGraph>& g)
|
Chris@16
|
166 { return get(p, g.base()); }
|
Chris@16
|
167
|
Chris@16
|
168 template<typename DistributedGraph>
|
Chris@16
|
169 inline local_subgraph<DistributedGraph>
|
Chris@16
|
170 make_local_subgraph(DistributedGraph& g)
|
Chris@16
|
171 { return local_subgraph<DistributedGraph>(g); }
|
Chris@16
|
172
|
Chris@16
|
173 } // end namespace boost
|
Chris@16
|
174
|
Chris@16
|
175 #endif // BOOST_GRAPH_LOCAL_SUBGRAPH_HPP
|