123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- // Copyright (C) 2004-2006 The Trustees of Indiana University.
- // Use, modification and distribution is subject to the Boost Software
- // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- // Authors: Douglas Gregor
- // Andrew Lumsdaine
- #ifndef BOOST_GRAPH_LOCAL_SUBGRAPH_HPP
- #define BOOST_GRAPH_LOCAL_SUBGRAPH_HPP
- #ifndef BOOST_GRAPH_USE_MPI
- #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
- #endif
- #include <boost/graph/graph_traits.hpp>
- #include <boost/graph/filtered_graph.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/type_traits/is_base_and_derived.hpp>
- #include <boost/graph/parallel/container_traits.hpp>
- namespace boost {
- namespace graph { namespace detail {
- // Optionally, virtually derive from a base class
- template<bool Derive, typename Base> struct derive_from_if;
- template<typename Base> struct derive_from_if<true, Base> : virtual Base {};
- template<typename Base> struct derive_from_if<false, Base> {};
- template<typename NewBase, typename Tag, typename OldBase = NewBase>
- struct derive_from_if_tag_is :
- derive_from_if<(is_base_and_derived<OldBase, Tag>::value
- || is_same<OldBase, Tag>::value),
- NewBase>
- {
- };
- } } // end namespace graph::detail
- template<typename DistributedGraph>
- class is_local_edge
- {
- public:
- typedef bool result_type;
- typedef typename graph_traits<DistributedGraph>::edge_descriptor
- argument_type;
- is_local_edge() : g(0) {}
- is_local_edge(DistributedGraph& g) : g(&g), owner(get(vertex_owner, g)) {}
- // Since either the source or target vertex must be local, the
- // equivalence of their owners indicates a local edge.
- result_type operator()(const argument_type& e) const
- { return get(owner, source(e, *g)) == get(owner, target(e, *g)); }
- private:
- DistributedGraph* g;
- typename property_map<DistributedGraph, vertex_owner_t>::const_type owner;
- };
- template<typename DistributedGraph>
- class is_local_vertex
- {
- public:
- typedef bool result_type;
- typedef typename graph_traits<DistributedGraph>::vertex_descriptor
- argument_type;
- is_local_vertex() : g(0) {}
- is_local_vertex(DistributedGraph& g) : g(&g), owner(get(vertex_owner, g)) { }
- // Since either the source or target vertex must be local, the
- // equivalence of their owners indicates a local edge.
- result_type operator()(const argument_type& v) const
- {
- return get(owner, v) == process_id(process_group(*g));
- }
- private:
- DistributedGraph* g;
- typename property_map<DistributedGraph, vertex_owner_t>::const_type owner;
- };
- template<typename DistributedGraph>
- class local_subgraph
- : public filtered_graph<DistributedGraph,
- is_local_edge<DistributedGraph>,
- is_local_vertex<DistributedGraph> >
- {
- typedef filtered_graph<DistributedGraph,
- is_local_edge<DistributedGraph>,
- is_local_vertex<DistributedGraph> >
- inherited;
- typedef typename graph_traits<DistributedGraph>::traversal_category
- inherited_category;
-
- public:
- struct traversal_category :
- graph::detail::derive_from_if_tag_is<incidence_graph_tag,
- inherited_category>,
- graph::detail::derive_from_if_tag_is<adjacency_graph_tag,
- inherited_category>,
- graph::detail::derive_from_if_tag_is<vertex_list_graph_tag,
- inherited_category>,
- graph::detail::derive_from_if_tag_is<edge_list_graph_tag,
- inherited_category>,
- graph::detail::derive_from_if_tag_is<vertex_list_graph_tag,
- inherited_category,
- distributed_vertex_list_graph_tag>,
- graph::detail::derive_from_if_tag_is<edge_list_graph_tag,
- inherited_category,
- distributed_edge_list_graph_tag>
- { };
- local_subgraph(DistributedGraph& g)
- : inherited(g,
- is_local_edge<DistributedGraph>(g),
- is_local_vertex<DistributedGraph>(g)),
- g(g)
- {
- }
- // Distributed Container
- typedef typename boost::graph::parallel::process_group_type<DistributedGraph>::type
- process_group_type;
- process_group_type& process_group()
- {
- using boost::graph::parallel::process_group;
- return process_group(g);
- }
- const process_group_type& process_group() const
- {
- using boost::graph::parallel::process_group;
- return boost::graph::parallel::process_group(g);
- }
-
- DistributedGraph& base() { return g; }
- const DistributedGraph& base() const { return g; }
- private:
- DistributedGraph& g;
- };
- template<typename DistributedGraph, typename PropertyTag>
- class property_map<local_subgraph<DistributedGraph>, PropertyTag>
- : public property_map<DistributedGraph, PropertyTag> { };
- template<typename DistributedGraph, typename PropertyTag>
- class property_map<local_subgraph<const DistributedGraph>, PropertyTag>
- {
- public:
- typedef typename property_map<DistributedGraph, PropertyTag>::const_type
- type;
- typedef type const_type;
- };
- template<typename PropertyTag, typename DistributedGraph>
- inline typename property_map<local_subgraph<DistributedGraph>, PropertyTag>::type
- get(PropertyTag p, local_subgraph<DistributedGraph>& g)
- { return get(p, g.base()); }
- template<typename PropertyTag, typename DistributedGraph>
- inline typename property_map<local_subgraph<DistributedGraph>, PropertyTag>
- ::const_type
- get(PropertyTag p, const local_subgraph<DistributedGraph>& g)
- { return get(p, g.base()); }
- template<typename DistributedGraph>
- inline local_subgraph<DistributedGraph>
- make_local_subgraph(DistributedGraph& g)
- { return local_subgraph<DistributedGraph>(g); }
- } // end namespace boost
- #endif // BOOST_GRAPH_LOCAL_SUBGRAPH_HPP
|