File: graph_topology_test.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (128 lines) | stat: -rw-r--r-- 4,600 bytes parent folder | download | duplicates (5)
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
// 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>
#include <random>
#include <boost/serialization/vector.hpp>
#include <boost/mpi/collectives/broadcast.hpp>
#include <boost/config.hpp>

#define BOOST_TEST_MODULE mpi_graph_topology
#include <boost/test/included/unit_test.hpp>

using boost::mpi::communicator;
using boost::mpi::graph_communicator;
using namespace boost;

BOOST_AUTO_TEST_CASE(graph_topology)
{
  boost::function_requires< IncidenceGraphConcept<graph_communicator> >();
  boost::function_requires< AdjacencyGraphConcept<graph_communicator> >();
  boost::function_requires< VertexListGraphConcept<graph_communicator> >();
  boost::function_requires< EdgeListGraphConcept<graph_communicator> >();

  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_CHECK((int)num_vertices(graph) == num_vertices(graph_comm));
  BOOST_CHECK((int)num_edges(graph) == num_edges(graph_comm));

  // 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_CHECK(verify_isomorphism(graph, graph_comm, graph_alt_index));
}