distributed_queue_test.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright (C) 2004-2006 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/config.hpp>
  9. #include <boost/throw_exception.hpp>
  10. #include <boost/serialization/vector.hpp>
  11. #include <boost/graph/distributed/queue.hpp>
  12. #include <boost/test/minimal.hpp>
  13. #include <boost/graph/distributed/mpi_process_group.hpp>
  14. #include <boost/pending/queue.hpp>
  15. #include <boost/property_map/property_map.hpp>
  16. #include <utility>
  17. #include <iostream>
  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 boost::graph::distributed::mpi_process_group;
  27. struct global_value
  28. {
  29. global_value(int p = -1, std::size_t l = 0) : processor(p), value(l) {}
  30. int processor;
  31. std::size_t value;
  32. template<typename Archiver>
  33. void serialize(Archiver& ar, const unsigned int /*version*/)
  34. {
  35. ar & processor & value;
  36. }
  37. };
  38. namespace boost { namespace mpi {
  39. template<> struct is_mpi_datatype<global_value> : mpl::true_ { };
  40. } } // end namespace boost::mpi
  41. BOOST_IS_BITWISE_SERIALIZABLE(global_value)
  42. BOOST_CLASS_IMPLEMENTATION(global_value,object_serializable)
  43. BOOST_CLASS_TRACKING(global_value,track_never)
  44. inline bool operator==(const global_value& x, const global_value& y)
  45. { return x.processor == y.processor && x.value == y.value; }
  46. struct global_value_owner_map
  47. {
  48. typedef int value_type;
  49. typedef value_type reference;
  50. typedef global_value key_type;
  51. typedef boost::readable_property_map_tag category;
  52. };
  53. int get(global_value_owner_map, global_value k)
  54. {
  55. return k.processor;
  56. }
  57. void test_distributed_queue()
  58. {
  59. mpi_process_group process_group;
  60. typedef boost::queue<global_value> local_queue_type;
  61. typedef boost::graph::distributed::distributed_queue<mpi_process_group,
  62. global_value_owner_map,
  63. local_queue_type> dist_queue_type;
  64. dist_queue_type Q(process_group, global_value_owner_map());
  65. mpi_process_group::process_id_type id = process_id(process_group),
  66. n = num_processes(process_group);
  67. global_value v(0, 0);
  68. if (id == 0) {
  69. std::cerr << "Should print level of each processor in a binary tree:\n";
  70. }
  71. synchronize(process_group);
  72. if (id == n-1) Q.push(v);
  73. while (!Q.empty()) {
  74. v = Q.top(); Q.pop();
  75. std::cerr << "#" << id << ": level = " << v.value << std::endl;
  76. int level_begin = 1;
  77. for (std::size_t i = 0; i < v.value; ++i) level_begin *= 2;
  78. int level_end = level_begin * 2;
  79. BOOST_CHECK(level_begin <= (id + 1));
  80. BOOST_CHECK((id + 1) <= level_end);
  81. ++v.value;
  82. v.processor = v.processor * 2 + 1;
  83. if (v.processor < n) Q.push(v);
  84. ++v.processor;
  85. if (v.processor < n) Q.push(v);
  86. }
  87. }
  88. int test_main(int argc, char** argv)
  89. {
  90. boost::mpi::environment env(argc, argv);
  91. test_distributed_queue();
  92. return 0;
  93. }