graph_topology_test.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright (C) 2007 Trustees of Indiana University
  2. // Authors: Douglas Gregor
  3. // Andrew Lumsdaine
  4. // Use, modification and distribution is subject to the Boost Software
  5. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // A test of the communicator that passes data around a ring and
  8. // verifies that the same data makes it all the way. Should test all
  9. // of the various kinds of data that can be sent (primitive types, POD
  10. // types, serializable objects, etc.)
  11. #include <boost/mpi/graph_communicator.hpp>
  12. #include <boost/mpi/communicator.hpp>
  13. #include <boost/mpi/environment.hpp>
  14. #include <boost/graph/adjacency_list.hpp>
  15. #include <boost/lexical_cast.hpp>
  16. #include <boost/graph/erdos_renyi_generator.hpp>
  17. #include <boost/random/linear_congruential.hpp>
  18. #include <boost/graph/iteration_macros.hpp>
  19. #include <boost/graph/isomorphism.hpp>
  20. #include <algorithm> // for random_shuffle
  21. #include <boost/serialization/vector.hpp>
  22. #include <boost/mpi/collectives/broadcast.hpp>
  23. #include <boost/config.hpp>
  24. #define BOOST_TEST_MODULE mpi_graph_topology
  25. #include <boost/test/included/unit_test.hpp>
  26. #if defined(BOOST_NO_CXX98_RANDOM_SHUFFLE)
  27. #include <random>
  28. std::default_random_engine gen;
  29. template<typename RandomIt> void random_shuffle( RandomIt first, RandomIt last )
  30. {
  31. std::shuffle( first, last, gen );
  32. }
  33. #else
  34. using std::random_shuffle;
  35. #endif // #if defined(BOOST_NO_CXX98_RANDOM_SHUFFLE)
  36. using boost::mpi::communicator;
  37. using boost::mpi::graph_communicator;
  38. using namespace boost;
  39. BOOST_AUTO_TEST_CASE(graph_topology)
  40. {
  41. boost::function_requires< IncidenceGraphConcept<graph_communicator> >();
  42. boost::function_requires< AdjacencyGraphConcept<graph_communicator> >();
  43. boost::function_requires< VertexListGraphConcept<graph_communicator> >();
  44. boost::function_requires< EdgeListGraphConcept<graph_communicator> >();
  45. double prob = 0.1;
  46. boost::mpi::environment env;
  47. communicator world;
  48. // Random number generator
  49. minstd_rand gen;
  50. // Build a random graph with as many vertices as there are processes
  51. typedef adjacency_list<listS, vecS, bidirectionalS> Graph;
  52. sorted_erdos_renyi_iterator<minstd_rand, Graph>
  53. first(gen, world.size(), prob), last;
  54. Graph graph(first, last, world.size());
  55. // Display the original graph
  56. if (world.rank() == 0) {
  57. std::cout << "Original, random graph:\n";
  58. BGL_FORALL_VERTICES(v, graph, Graph) {
  59. BGL_FORALL_OUTEDGES(v, e, graph, Graph) {
  60. std::cout << source(e, graph) << " -> " << target(e, graph)
  61. << std::endl;
  62. }
  63. }
  64. }
  65. // Create an arbitrary mapping from vertices to integers
  66. typedef property_map<Graph, vertex_index_t>::type GraphVertexIndexMap;
  67. std::vector<int> graph_alt_index_vec(num_vertices(graph));
  68. iterator_property_map<int*, GraphVertexIndexMap>
  69. graph_alt_index(&graph_alt_index_vec[0], get(vertex_index, graph));
  70. // Rank 0 will populate the alternative index vector
  71. if (world.rank() == 0) {
  72. int index = 0;
  73. BGL_FORALL_VERTICES(v, graph, Graph)
  74. put(graph_alt_index, v, index++);
  75. ::random_shuffle(graph_alt_index_vec.begin(), graph_alt_index_vec.end());
  76. }
  77. broadcast(world, graph_alt_index_vec, 0);
  78. // Display the original graph with the remapping
  79. if (world.rank() == 0) {
  80. std::cout << "Original, random graph with remapped vertex numbers:\n";
  81. BGL_FORALL_VERTICES(v, graph, Graph) {
  82. BGL_FORALL_OUTEDGES(v, e, graph, Graph) {
  83. std::cout << get(graph_alt_index, source(e, graph)) << " -> "
  84. << get(graph_alt_index, target(e, graph)) << std::endl;
  85. }
  86. }
  87. }
  88. // Create a communicator with a topology equivalent to the graph
  89. graph_communicator graph_comm(world, graph, graph_alt_index, false);
  90. // The communicator's topology should have the same number of
  91. // vertices and edges and the original graph
  92. BOOST_CHECK((int)num_vertices(graph) == num_vertices(graph_comm));
  93. BOOST_CHECK((int)num_edges(graph) == num_edges(graph_comm));
  94. // Display the communicator graph
  95. if (graph_comm.rank() == 0) {
  96. std::cout << "Communicator graph:\n";
  97. BGL_FORALL_VERTICES(v, graph_comm, graph_communicator) {
  98. BGL_FORALL_OUTEDGES(v, e, graph_comm, graph_communicator) {
  99. std::cout << source(e, graph_comm) << " -> " << target(e, graph_comm)
  100. << std::endl;
  101. }
  102. }
  103. std::cout << "Communicator graph via edges():\n";
  104. BGL_FORALL_EDGES(e, graph_comm, graph_communicator)
  105. std::cout << source(e, graph_comm) << " -> " << target(e, graph_comm)
  106. << std::endl;
  107. }
  108. (graph_comm.barrier)();
  109. // Verify the isomorphism
  110. if (graph_comm.rank() == 0)
  111. std::cout << "Verifying isomorphism..." << std::endl;
  112. BOOST_CHECK(verify_isomorphism(graph, graph_comm, graph_alt_index));
  113. }