distributed_page_rank_test.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright 2004 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Douglas Gregor
  6. // Andrew Lumsdaine
  7. #include <boost/graph/use_mpi.hpp>
  8. #include <boost/throw_exception.hpp>
  9. #include <boost/serialization/vector.hpp>
  10. #include <boost/graph/distributed/page_rank.hpp>
  11. #include <boost/test/minimal.hpp>
  12. #include <boost/graph/distributed/adjacency_list.hpp>
  13. #include <boost/graph/distributed/mpi_process_group.hpp>
  14. #include <boost/test/minimal.hpp>
  15. #include <vector>
  16. #include <iostream>
  17. #include <stdlib.h>
  18. #ifdef BOOST_NO_EXCEPTIONS
  19. void
  20. boost::throw_exception(std::exception const& ex)
  21. {
  22. std::cout << ex.what() << std::endl;
  23. abort();
  24. }
  25. #endif
  26. using namespace boost;
  27. using boost::graph::distributed::mpi_process_group;
  28. bool close_to(double x, double y)
  29. {
  30. double diff = x - y;
  31. if (diff < 0) diff = -diff;
  32. double base = (y == 0? x : y);
  33. if (base != 0) return diff / base < 0.01;
  34. else return true;
  35. }
  36. // Make convenient labels for the vertices
  37. enum vertex_id_t { A, B, C, D, N };
  38. void test_distributed_page_rank(int iterations)
  39. {
  40. using namespace boost::graph;
  41. // create a typedef for the Graph type
  42. typedef adjacency_list<vecS,
  43. distributedS<mpi_process_group, vecS>,
  44. bidirectionalS
  45. > Graph;
  46. typedef graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  47. // writing out the edges in the graph
  48. typedef std::pair<int, int> Edge;
  49. Edge edge_array[] =
  50. { Edge(A,B), Edge(A,C), Edge(B,C), Edge(C,A), Edge(D,C) };
  51. const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);
  52. // declare a graph object
  53. Graph g(edge_array, edge_array + num_edges, N);
  54. std::vector<double> ranks(num_vertices(g));
  55. page_rank(g,
  56. make_iterator_property_map(ranks.begin(),
  57. get(boost::vertex_index, g)),
  58. n_iterations(iterations), 0.85, N);
  59. double local_sum = 0.0;
  60. for(unsigned int i = 0; i < num_vertices(g); ++i) {
  61. std::cout << (char)('A' + g.distribution().global(i)) << " = "
  62. << ranks[i] << std::endl;
  63. local_sum += ranks[i];
  64. }
  65. double sum=0.;
  66. boost::mpi::reduce(communicator(g.process_group()),
  67. local_sum, sum, std::plus<double>(), 0);
  68. if (process_id(g.process_group()) == 0) {
  69. std::cout << "Sum = " << sum << "\n\n";
  70. BOOST_CHECK(close_to(sum, 4)); // 1 when alpha=0
  71. }
  72. // double expected_ranks0[N] = {0.400009, 0.199993, 0.399998, 0.0};
  73. double expected_ranks[N] = {1.49011, 0.783296, 1.5766, 0.15};
  74. for (int i = 0; i < N; ++i) {
  75. vertex_descriptor v = vertex(i, g);
  76. if (v != Graph::null_vertex()
  77. && owner(v) == process_id(g.process_group())) {
  78. BOOST_CHECK(close_to(ranks[local(v)], expected_ranks[i]));
  79. }
  80. }
  81. }
  82. int test_main(int argc, char* argv[])
  83. {
  84. mpi::environment env(argc, argv);
  85. int iterations = 50;
  86. if (argc > 1) {
  87. iterations = atoi(argv[1]);
  88. }
  89. test_distributed_page_rank(iterations);
  90. return 0;
  91. }