1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
// Copyright (C) 2007 Trustees of Indiana University
// Authors: Douglas Gregor
// Andrew Lumsdaine
// 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)
// A test of the communicator that passes data around a ring and
// 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 <boost/mpi/graph_communicator.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/mpi/environment.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/graph/erdos_renyi_generator.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/graph/isomorphism.hpp>
#include <algorithm> // for shuffle
#include <boost/serialization/vector.hpp>
#include <boost/mpi/collectives/broadcast.hpp>
#include <boost/config.hpp>
#include "mpi_test_utils.hpp"
#include <random>
using boost::mpi::communicator;
using boost::mpi::graph_communicator;
using namespace boost;
int main()
{
boost::function_requires< IncidenceGraphConcept<graph_communicator> >();
boost::function_requires< AdjacencyGraphConcept<graph_communicator> >();
boost::function_requires< VertexListGraphConcept<graph_communicator> >();
boost::function_requires< EdgeListGraphConcept<graph_communicator> >();
int failed = 0;
double prob = 0.1;
boost::mpi::environment env;
communicator world;
// Random number generator
minstd_rand gen;
// Build a random graph with as many vertices as there are processes
typedef adjacency_list<listS, vecS, bidirectionalS> Graph;
sorted_erdos_renyi_iterator<minstd_rand, Graph>
first(gen, world.size(), prob), last;
Graph graph(first, last, world.size());
// Display the original graph
if (world.rank() == 0) {
std::cout << "Original, random graph:\n";
BGL_FORALL_VERTICES(v, graph, Graph) {
BGL_FORALL_OUTEDGES(v, e, graph, Graph) {
std::cout << source(e, graph) << " -> " << target(e, graph)
<< std::endl;
}
}
}
// Create an arbitrary mapping from vertices to integers
typedef property_map<Graph, vertex_index_t>::type GraphVertexIndexMap;
std::vector<int> graph_alt_index_vec(num_vertices(graph));
iterator_property_map<int*, GraphVertexIndexMap>
graph_alt_index(&graph_alt_index_vec[0], get(vertex_index, graph));
// Rank 0 will populate the alternative index vector
if (world.rank() == 0) {
int index = 0;
BGL_FORALL_VERTICES(v, graph, Graph)
put(graph_alt_index, v, index++);
{
std::random_device rd;
std::mt19937 gen(rd());
std::shuffle(graph_alt_index_vec.begin(), graph_alt_index_vec.end(), gen);
}
}
broadcast(world, graph_alt_index_vec, 0);
// Display the original graph with the remapping
if (world.rank() == 0) {
std::cout << "Original, random graph with remapped vertex numbers:\n";
BGL_FORALL_VERTICES(v, graph, Graph) {
BGL_FORALL_OUTEDGES(v, e, graph, Graph) {
std::cout << get(graph_alt_index, source(e, graph)) << " -> "
<< get(graph_alt_index, target(e, graph)) << std::endl;
}
}
}
// Create a communicator with a topology equivalent to the graph
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
BOOST_MPI_CHECK((int)num_vertices(graph) == num_vertices(graph_comm), failed);
BOOST_MPI_CHECK((int)num_edges(graph) == num_edges(graph_comm), failed);
// Display the communicator graph
if (graph_comm.rank() == 0) {
std::cout << "Communicator graph:\n";
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, graph_communicator)
std::cout << source(e, graph_comm) << " -> " << target(e, graph_comm)
<< std::endl;
}
(graph_comm.barrier)();
// Verify the isomorphism
if (graph_comm.rank() == 0)
std::cout << "Verifying isomorphism..." << std::endl;
BOOST_MPI_CHECK(verify_isomorphism(graph, graph_comm, graph_alt_index), failed);
return failed;
}
|