From 1082c372b5260eaa97004aca5d84f704a3ad5f0a Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 5 Jun 2007 00:54:56 +0000 Subject: [PATCH] Create a separate graph_communicator type to handle graph topologies [SVN r37898] --- build/Jamfile.v2 | 2 +- doc/Jamfile.v2 | 2 +- doc/mpi.qbk | 9 +- include/boost/mpi.hpp | 2 +- include/boost/mpi/communicator.hpp | 105 +++----- ...ph_topology.hpp => graph_communicator.hpp} | 239 +++++++++++++++--- src/communicator.cpp | 19 +- ...ph_topology.cpp => graph_communicator.cpp} | 14 +- test/graph_topology_test.cpp | 20 +- 9 files changed, 271 insertions(+), 141 deletions(-) rename include/boost/mpi/{graph_topology.hpp => graph_communicator.hpp} (54%) rename src/{graph_topology.cpp => graph_communicator.cpp} (87%) diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 407c02a..7c2fde1 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -26,7 +26,7 @@ lib boost_mpi content_oarchive.cpp environment.cpp exception.cpp - graph_topology.cpp + graph_communicator.cpp group.cpp intercommunicator.cpp mpi_datatype_cache.cpp diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 3efd6c1..499c3d7 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -19,7 +19,7 @@ doxygen mpi_autodoc ../../../boost/mpi/datatype_fwd.hpp ../../../boost/mpi/environment.hpp ../../../boost/mpi/exception.hpp - ../../../boost/mpi/graph_topology.hpp + ../../../boost/mpi/graph_communicator.hpp ../../../boost/mpi/group.hpp ../../../boost/mpi/intercommunicator.hpp ../../../boost/mpi/nonblocking.hpp diff --git a/doc/mpi.qbk b/doc/mpi.qbk index 11f712f..6d9237f 100644 --- a/doc/mpi.qbk +++ b/doc/mpi.qbk @@ -1229,7 +1229,7 @@ operations are called internally by Boost.MPI. `MPI_Type_contiguous`]] [arrays]] [[[@http://www.mpi-forum.org/docs/mpi-11-html/node56.html#Node56 -`MPI_Type_extent`]] [unsupported]] +`MPI_Type_extent`]] [used automatically in Boost.MPI]] [[[@http://www.mpi-forum.org/docs/mpi-11-html/node58.html#Node58 `MPI_Type_free`]] [used automatically in Boost.MPI]] @@ -1238,8 +1238,7 @@ operations are called internally by Boost.MPI. `MPI_Type_hindexed`]] [any type used as a subobject]] [[[@http://www.mpi-forum.org/docs/mpi-11-html/node55.html#Node55 -`MPI_Type_hvector`]] [unsupported unless equivalent to -`MPI_Type_contiguous`]] +`MPI_Type_hvector`]] [unused]] [[[@http://www.mpi-forum.org/docs/mpi-11-html/node55.html#Node55 `MPI_Type_indexed`]] [any type used as a subobject]] @@ -1248,7 +1247,7 @@ operations are called internally by Boost.MPI. `MPI_Type_lb`]] [unsupported]] [[[@http://www.mpi-forum.org/docs/mpi-11-html/node56.html#Node56 -`MPI_Type_size`]] [unsupported]] +`MPI_Type_size`]] [used automatically in Boost.MPI]] [[[@http://www.mpi-forum.org/docs/mpi-11-html/node55.html#Node55 `MPI_Type_struct`]] [user-defined classes and structs]] @@ -1257,7 +1256,7 @@ operations are called internally by Boost.MPI. `MPI_Type_ub`]] [unsupported]] [[[@http://www.mpi-forum.org/docs/mpi-11-html/node55.html#Node55 -`MPI_Type_vector`]] [unsupported unless equivalent to `MPI_Type_contiguous`]] +`MPI_Type_vector`]] [used automatically in Boost.MPI]] ] MPI's packing facilities store values into a contiguous buffer, which diff --git a/include/boost/mpi.hpp b/include/boost/mpi.hpp index 3237239..835d73c 100644 --- a/include/boost/mpi.hpp +++ b/include/boost/mpi.hpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/mpi/communicator.hpp b/include/boost/mpi/communicator.hpp index 17a12d4..14d751c 100644 --- a/include/boost/mpi/communicator.hpp +++ b/include/boost/mpi/communicator.hpp @@ -102,6 +102,14 @@ class group; */ class intercommunicator; +/** + * INTERNAL ONLY + * + * Forward declaration of @c graph_communicator needed for the "cast" + * from a communicator to a graph communicator. + */ +class graph_communicator; + /** * @brief A communicator that permits communication and * synchronization among a set of processes. @@ -795,80 +803,43 @@ class communicator */ optional as_intercommunicator() const; + /** + * Determine if the communicator has a graph topology and, if so, + * return that @c graph_communicator. Even though the communicators + * have different types, they refer to the same underlying + * communication space and can be used interchangeably for + * communication. + * + * @returns an @c optional containing the graph communicator, if this + * communicator does in fact have a graph topology. Otherwise, returns + * an empty @c optional. + */ + optional as_graph_communicator() const; + /** * Determines whether this communicator has a Cartesian topology. */ bool has_cartesian_topology() const; - /** - * Determines whether this communicator has a graph topology. If - * the communicator does have a graph topology, the communicator - * itself can be viewed as a graph by the algorithms in the Boost - * Graph Library. The communicator then meets the requirements of - * the @c Graph, @c Incidence Graph, @c Adjacency Graph, @c Vertex - * List Graph, and @c Edge List Graph concepts. - */ - bool has_graph_topology() const; - - /** - * Create a new communicator whose topology is described by the - * given graph. The vertex index map (@p index) gives the mapping - * from vertices in the graph to ranks within the - * communicator. There may be fewer vertices in the graph than - * there are processes in the communicator; in this case, this - * routine will return a NULL communicator. - * - * To use this function, you will need to have included either all - * of the Boost.MPI library (@c boost/mpi.hpp) or the - * graph topology header (@c boost/mpi/graph_topology.hpp). - * - * @param graph Any type that meets the requirements of the - * IncidenceGraph and VertexListGraph concepts from the Boost Graph - * Library. This structure of this graph will become the topology - * of the communicator that is returned. - * - * @param reorder Whether MPI is permitted to re-order the process - * ranks within the returned communicator, to better optimize - * communication. If false, the ranks of each process in the - * returned process will match precisely the rank of that process - * within the original communicator. - * - * @param rank This map translates vertices in the @c graph into - * ranks within the current communicator. It must be a Readable - * Property Map (see the Boost Property Map library) whose key type - * is the vertex type of the @p graph and whose value type is @c - * int. - */ - template +#if 0 + template communicator - with_graph_topology(const Graph& graph, bool reorder, VertexIndexMap rank); + with_cartesian_topology(const Extents& extents, + bool periodic = false, + bool reorder = false) const; - /** - * Create a new communicator whose topology is described by the - * given graph. The mapping from vertices in the graph to ranks - * within the communicator is provided by the internal @c - * vertex_index property of the graph. There may be fewer vertices - * in the graph than there are processes in the communicator; in - * this case, this routine will return a NULL communicator. - * - * To use this function, you will need to have included either all - * of the Boost.MPI library (@c boost/mpi.hpp) or the - * graph topology header (@c boost/mpi/graph_topology.hpp). - * - * @param graph Any type that meets the requirements of the - * IncidenceGraph and VertexListGraph concepts from the Boost Graph - * Library. This structure of this graph will become the topology - * of the communicator that is returned. - * - * @param reorder Whether MPI is permitted to re-order the process - * ranks within the returned communicator, to better optimize - * communication. If false, the ranks of each process in the - * returned process will match precisely the rank of that process - * within the original communicator. - */ - template - communicator - with_graph_topology(const Graph& graph, bool reorder = true); + template + communicator + with_cartesian_topology(DimInputIterator first_dim, + DimInputIterator last_dim, + PeriodicInputIterator first_periodic, + bool reorder = false); + + template + communicator + with_cartesian_topology(const multi_array& periods, + bool reorder = false); +#endif /** Abort all tasks in the group of this communicator. * diff --git a/include/boost/mpi/graph_topology.hpp b/include/boost/mpi/graph_communicator.hpp similarity index 54% rename from include/boost/mpi/graph_topology.hpp rename to include/boost/mpi/graph_communicator.hpp index 2d1021b..1b42be8 100644 --- a/include/boost/mpi/graph_topology.hpp +++ b/include/boost/mpi/graph_communicator.hpp @@ -7,18 +7,19 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -/** @file graph_topology.hpp +/** @file graph_communicator.hpp * - * This header defines facilities to support graph topologies, using - * the graph interface defined by the Boost Graph Library. One can - * construct a communicator whose topology is described by any graph - * meeting the requirements of the Boost Graph Library's graph - * concepts. Likewise, any communicator that has a graph topology can - * be viewed as a graph by the Boost Graph Library, permitting one to - * use the BGL's graph algorithms on the process topology. + * This header defines facilities to support MPI communicators with + * graph topologies, using the graph interface defined by the Boost + * Graph Library. One can construct a communicator whose topology is + * described by any graph meeting the requirements of the Boost Graph + * Library's graph concepts. Likewise, any communicator that has a + * graph topology can be viewed as a graph by the Boost Graph + * Library, permitting one to use the BGL's graph algorithms on the + * process topology. */ -#ifndef BOOST_MPI_TOPOLOGIES_HPP -#define BOOST_MPI_TOPOLOGIES_HPP +#ifndef BOOST_MPI_GRAPH_COMMUNICATOR_HPP +#define BOOST_MPI_GRAPH_COMMUNICATOR_HPP #include #include @@ -31,35 +32,191 @@ #include #include #include +#include namespace boost { namespace mpi { -/**************************************************************************** - * Graph -> Communicator with Graph Topology * - ****************************************************************************/ -template -inline communicator -communicator::with_graph_topology(const Graph& graph, bool reorder) +/** + * @brief An MPI communicator with a graph topology. + * + * A @c graph_communicator is a communicator whose topology is + * expressed as a graph. Graph communicators have the same + * functionality as (intra)communicators, but also allow one to query + * the relationships among processes. Those relationships are + * expressed via a graph, using the interface defined by the Boost + * Graph Library. The @c graph_communicator class meets the + * requirements of the BGL Graph, Incidence Graph, Adjacency Graph, + * Vertex List Graph, and Edge List Graph concepts. + */ +class graph_communicator : public communicator { - return with_graph_topology(graph, reorder, get(vertex_index, graph)); + friend class communicator; + + /** + * INTERNAL ONLY + * + * Construct a graph communicator given a shared pointer to the + * underlying MPI_Comm. This operation is used for "casting" from a + * communicator to a graph communicator. + */ + explicit graph_communicator(const shared_ptr& comm_ptr) + { +#ifndef BOOST_DISABLE_ASSERTS + int status; + BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status)); + BOOST_ASSERT(status == MPI_GRAPH); +#endif + this->comm_ptr = comm_ptr; + } + +public: + /** + * Build a new Boost.MPI graph communicator based on the MPI + * communicator @p comm with graph topology. + * + * @p comm may be any valid MPI communicator. If @p comm is + * MPI_COMM_NULL, an empty communicator (that cannot be used for + * communication) is created and the @p kind parameter is + * ignored. Otherwise, the @p kind parameter determines how the + * Boost.MPI communicator will be related to @p comm: + * + * - If @p kind is @c comm_duplicate, duplicate @c comm to create + * a new communicator. This new communicator will be freed when + * the Boost.MPI communicator (and all copies of it) is + * destroyed. This option is only permitted if the underlying MPI + * implementation supports MPI 2.0; duplication of + * intercommunicators is not available in MPI 1.x. + * + * - If @p kind is @c comm_take_ownership, take ownership of @c + * comm. It will be freed automatically when all of the Boost.MPI + * communicators go out of scope. + * + * - If @p kind is @c comm_attach, this Boost.MPI communicator + * will reference the existing MPI communicator @p comm but will + * not free @p comm when the Boost.MPI communicator goes out of + * scope. This option should only be used when the communicator is + * managed by the user. + */ + graph_communicator(const MPI_Comm& comm, comm_create_kind kind) + : communicator(comm, kind) + { +#ifndef BOOST_DISABLE_ASSERTS + int status; + BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status)); + BOOST_ASSERT(status == MPI_GRAPH); +#endif + } + + /** + * Create a new communicator whose topology is described by the + * given graph. The indices of the vertices in the graph will be + * assumed to be the ranks of the processes within the + * communicator. There may be fewer vertices in the graph than + * there are processes in the communicator; in this case, the + * resulting communicator will be a NULL communicator. + * + * @param comm The communicator that the new, graph communicator + * will be based on. + * + * @param graph Any type that meets the requirements of the + * Incidence Graph and Vertex List Graph concepts from the Boost Graph + * Library. This structure of this graph will become the topology + * of the communicator that is returned. + * + * @param reorder Whether MPI is permitted to re-order the process + * ranks within the returned communicator, to better optimize + * communication. If false, the ranks of each process in the + * returned process will match precisely the rank of that process + * within the original communicator. + */ + template + explicit + graph_communicator(const communicator& comm, const Graph& graph, + bool reorder = false); + + /** + * Create a new communicator whose topology is described by the + * given graph. The rank map (@p rank) gives the mapping from + * vertices in the graph to ranks within the communicator. There + * may be fewer vertices in the graph than there are processes in + * the communicator; in this case, the resulting communicator will + * be a NULL communicator. + * + * @param comm The communicator that the new, graph communicator + * will be based on. The ranks in @c rank refer to the processes in + * this communicator. + * + * @param graph Any type that meets the requirements of the + * Incidence Graph and Vertex List Graph concepts from the Boost Graph + * Library. This structure of this graph will become the topology + * of the communicator that is returned. + * + * @param rank This map translates vertices in the @c graph into + * ranks within the current communicator. It must be a Readable + * Property Map (see the Boost Property Map library) whose key type + * is the vertex type of the @p graph and whose value type is @c + * int. + * + * @param reorder Whether MPI is permitted to re-order the process + * ranks within the returned communicator, to better optimize + * communication. If false, the ranks of each process in the + * returned process will match precisely the rank of that process + * within the original communicator. + */ + template + explicit + graph_communicator(const communicator& comm, const Graph& graph, + RankMap rank, bool reorder = false); + +protected: + /** + * INTERNAL ONLY + * + * Used by the constructors to create the new communicator with a + * graph topology. + */ + template + void + setup_graph(const communicator& comm, const Graph& graph, RankMap rank, + bool reorder); +}; + +/**************************************************************************** + * Implementation Details * + ****************************************************************************/ + +template +graph_communicator::graph_communicator(const communicator& comm, + const Graph& graph, + bool reorder) +{ + this->setup_graph(comm, graph, get(vertex_index, graph), reorder); } -template -communicator -communicator::with_graph_topology(const Graph& graph, - bool reorder, - VertexIndexMap rank) +template +graph_communicator::graph_communicator(const communicator& comm, + const Graph& graph, + RankMap rank, bool reorder) +{ + this->setup_graph(comm, graph, rank, reorder); +} + + +template +void +graph_communicator::setup_graph(const communicator& comm, const Graph& graph, + RankMap rank, bool reorder) { typedef typename graph_traits::vertex_descriptor vertex_descriptor; // Build a mapping from ranks to vertices std::vector vertex_with_rank(num_vertices(graph)); + if (vertex_with_rank.empty()) + return; + BGL_FORALL_VERTICES_T(v, graph, Graph) vertex_with_rank[get(rank, v)] = v; - if (vertex_with_rank.empty()) - return communicator(MPI_COMM_NULL, comm_take_ownership); - // Build the representation of the graph required by // MPI_Graph_create. std::vector indices(num_vertices(graph)); @@ -77,13 +234,13 @@ communicator::with_graph_topology(const Graph& graph, // Create the new communicator MPI_Comm newcomm; BOOST_MPI_CHECK_RESULT(MPI_Graph_create, - ((MPI_Comm)*this, + ((MPI_Comm)comm, nvertices, &indices[0], edges.empty()? (int*)0 : &edges[0], reorder, &newcomm)); - return communicator(newcomm, comm_take_ownership); + this->comm_ptr.reset(new MPI_Comm(newcomm), comm_free()); } /**************************************************************************** @@ -243,7 +400,7 @@ namespace detail { * @brief Returns the source vertex from an edge in the graph topology * of a communicator. */ -inline int source(const std::pair& edge, const communicator&) +inline int source(const std::pair& edge, const graph_communicator&) { return edge.first; } @@ -252,7 +409,7 @@ inline int source(const std::pair& edge, const communicator&) * @brief Returns the target vertex from an edge in the graph topology * of a communicator. */ -inline int target(const std::pair& edge, const communicator&) +inline int target(const std::pair& edge, const graph_communicator&) { return edge.second; } @@ -263,14 +420,14 @@ inline int target(const std::pair& edge, const communicator&) * communicator. */ std::pair -out_edges(int vertex, const communicator& comm); +out_edges(int vertex, const graph_communicator& comm); /** * @brief Returns the out-degree of a vertex in the graph topology of * a communicator. */ -int out_degree(int vertex, const communicator& comm); +int out_degree(int vertex, const graph_communicator& comm); // Adjacency Graph requirements @@ -279,7 +436,7 @@ int out_degree(int vertex, const communicator& comm); * the given vertex in the communicator's graph topology. */ std::pair -adjacent_vertices(int vertex, const communicator& comm); +adjacent_vertices(int vertex, const graph_communicator& comm); // Vertex List Graph requirements @@ -289,7 +446,7 @@ adjacent_vertices(int vertex, const communicator& comm); * ranks in the communicator. */ inline std::pair, counting_iterator > -vertices(const communicator& comm) +vertices(const graph_communicator& comm) { return std::make_pair(counting_iterator(0), counting_iterator(comm.size())); @@ -300,7 +457,7 @@ vertices(const communicator& comm) * the communicator, i.e., the number of processes in the * communicator. */ -inline int num_vertices(const communicator& comm) { return comm.size(); } +inline int num_vertices(const graph_communicator& comm) { return comm.size(); } // Edge List Graph requirements @@ -309,13 +466,13 @@ inline int num_vertices(const communicator& comm) { return comm.size(); } * with the communicator's graph topology. */ std::pair -edges(const communicator& comm); +edges(const graph_communicator& comm); /** * @brief Returns the number of edges in the communicator's graph * topology. */ -int num_edges(const communicator& comm); +int num_edges(const graph_communicator& comm); // Property Graph requirements @@ -326,7 +483,7 @@ int num_edges(const communicator& comm); * Since the vertices are ranks in the communicator, the returned * property map is the identity property map. */ -inline identity_property_map get(vertex_index_t, const communicator&) +inline identity_property_map get(vertex_index_t, const graph_communicator&) { return identity_property_map(); } @@ -338,7 +495,7 @@ inline identity_property_map get(vertex_index_t, const communicator&) * Since the vertices are ranks in the communicator, this is the * identity function. */ -inline int get(vertex_index_t, const communicator&, int vertex) +inline int get(vertex_index_t, const graph_communicator&, int vertex) { return vertex; } @@ -359,7 +516,7 @@ namespace boost { * Library. */ template<> -struct graph_traits { +struct graph_traits { // Graph concept requirements typedef int vertex_descriptor; typedef std::pair edge_descriptor; @@ -405,7 +562,7 @@ struct graph_traits { * INTERNAL ONLY */ template<> -struct property_map +struct property_map { typedef identity_property_map type; typedef identity_property_map const_type; @@ -415,4 +572,4 @@ struct property_map -#endif // BOOST_MPI_TOPOLOGIES_HPP +#endif // BOOST_MPI_GRAPH_COMMUNICATOR_HPP diff --git a/src/communicator.cpp b/src/communicator.cpp index 0ab5844..a93b856 100644 --- a/src/communicator.cpp +++ b/src/communicator.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -160,6 +161,16 @@ optional communicator::as_intercommunicator() const return optional(); } +optional communicator::as_graph_communicator() const +{ + int status; + BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status)); + if (status == MPI_GRAPH) + return graph_communicator(comm_ptr); + else + return optional(); +} + bool communicator::has_cartesian_topology() const { int status; @@ -168,14 +179,6 @@ bool communicator::has_cartesian_topology() const return status == MPI_CART; } -bool communicator::has_graph_topology() const -{ - int status; - BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status)); - - return status == MPI_GRAPH; -} - void communicator::abort(int errcode) const { BOOST_MPI_CHECK_RESULT(MPI_Abort, (MPI_Comm(*this), errcode)); diff --git a/src/graph_topology.cpp b/src/graph_communicator.cpp similarity index 87% rename from src/graph_topology.cpp rename to src/graph_communicator.cpp index 4c66321..586b57b 100644 --- a/src/graph_topology.cpp +++ b/src/graph_communicator.cpp @@ -6,13 +6,13 @@ // 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) -#include +#include namespace boost { namespace mpi { // Incidence Graph requirements std::pair -out_edges(int vertex, const communicator& comm) +out_edges(int vertex, const graph_communicator& comm) { int nneighbors = out_degree(vertex, comm); shared_array neighbors(new int[nneighbors]); @@ -23,7 +23,7 @@ out_edges(int vertex, const communicator& comm) nneighbors)); } -int out_degree(int vertex, const communicator& comm) +int out_degree(int vertex, const graph_communicator& comm) { int nneighbors; BOOST_MPI_CHECK_RESULT(MPI_Graph_neighbors_count, @@ -33,7 +33,7 @@ int out_degree(int vertex, const communicator& comm) // Adjacency Graph requirements std::pair -adjacent_vertices(int vertex, const communicator& comm) +adjacent_vertices(int vertex, const graph_communicator& comm) { int nneighbors = out_degree(vertex, comm); shared_array neighbors(new int[nneighbors]); @@ -45,10 +45,10 @@ adjacent_vertices(int vertex, const communicator& comm) // Edge List Graph requirements std::pair -edges(const communicator& comm); +edges(const graph_communicator& comm); std::pair -edges(const communicator& comm) +edges(const graph_communicator& comm) { int nnodes, nedges; BOOST_MPI_CHECK_RESULT(MPI_Graphdims_get, ((MPI_Comm)comm, &nnodes, &nedges)); @@ -63,7 +63,7 @@ edges(const communicator& comm) } -int num_edges(const communicator& comm) +int num_edges(const graph_communicator& comm) { int nnodes, nedges; BOOST_MPI_CHECK_RESULT(MPI_Graphdims_get, ((MPI_Comm)comm, &nnodes, &nedges)); diff --git a/test/graph_topology_test.cpp b/test/graph_topology_test.cpp index bdd9213..d573f20 100644 --- a/test/graph_topology_test.cpp +++ b/test/graph_topology_test.cpp @@ -11,7 +11,7 @@ // verifies that the same data makes it all the way. Should test all // of the various kinds of data that can be sent (primitive types, POD // types, serializable objects, etc.) -#include +#include #include #include #include @@ -26,14 +26,15 @@ #include using boost::mpi::communicator; +using boost::mpi::graph_communicator; using namespace boost; int test_main(int argc, char* argv[]) { - boost::function_requires< IncidenceGraphConcept >(); - boost::function_requires< AdjacencyGraphConcept >(); - boost::function_requires< VertexListGraphConcept >(); - boost::function_requires< EdgeListGraphConcept >(); + boost::function_requires< IncidenceGraphConcept >(); + boost::function_requires< AdjacencyGraphConcept >(); + boost::function_requires< VertexListGraphConcept >(); + boost::function_requires< EdgeListGraphConcept >(); double prob = 0.1; @@ -89,8 +90,7 @@ int test_main(int argc, char* argv[]) } // Create a communicator with a topology equivalent to the graph - communicator graph_comm = world.with_graph_topology(graph, false, - graph_alt_index); + graph_communicator graph_comm(world, graph, graph_alt_index, false); // The communicator's topology should have the same number of // vertices and edges and the original graph @@ -100,15 +100,15 @@ int test_main(int argc, char* argv[]) // Display the communicator graph if (graph_comm.rank() == 0) { std::cout << "Communicator graph:\n"; - BGL_FORALL_VERTICES(v, graph_comm, communicator) { - BGL_FORALL_OUTEDGES(v, e, graph_comm, communicator) { + BGL_FORALL_VERTICES(v, graph_comm, graph_communicator) { + BGL_FORALL_OUTEDGES(v, e, graph_comm, graph_communicator) { std::cout << source(e, graph_comm) << " -> " << target(e, graph_comm) << std::endl; } } std::cout << "Communicator graph via edges():\n"; - BGL_FORALL_EDGES(e, graph_comm, communicator) + BGL_FORALL_EDGES(e, graph_comm, graph_communicator) std::cout << source(e, graph_comm) << " -> " << target(e, graph_comm) << std::endl; }