gather_test.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (C) 2005, 2006 Douglas Gregor.
  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. // A test of the gather() and gatherv() collectives.
  6. #include <boost/mpi/collectives/gather.hpp>
  7. #include <boost/mpi/collectives/gatherv.hpp>
  8. #include <boost/mpi/communicator.hpp>
  9. #include <boost/mpi/environment.hpp>
  10. #include "gps_position.hpp"
  11. #include <boost/serialization/string.hpp>
  12. #include <boost/serialization/list.hpp>
  13. #include <boost/iterator/counting_iterator.hpp>
  14. #include <boost/lexical_cast.hpp>
  15. #define BOOST_TEST_MODULE mpi_gather
  16. #include <boost/test/included/unit_test.hpp>
  17. using boost::mpi::communicator;
  18. template<typename Generator>
  19. void
  20. gather_test(const communicator& comm, Generator generator,
  21. const char* kind, int root = -1)
  22. {
  23. typedef typename Generator::result_type value_type;
  24. value_type value = generator(comm.rank());
  25. if (root == -1) {
  26. for (root = 0; root < comm.size(); ++root)
  27. gather_test(comm, generator, kind, root);
  28. } else {
  29. using boost::mpi::gather;
  30. std::vector<value_type> values;
  31. if (comm.rank() == root) {
  32. std::cout << "Gathering " << kind << " from root "
  33. << root << "..." << std::endl;
  34. }
  35. gather(comm, value, values, root);
  36. if (comm.rank() == root) {
  37. std::vector<value_type> expected_values;
  38. for (int p = 0; p < comm.size(); ++p)
  39. expected_values.push_back(generator(p));
  40. BOOST_CHECK(values == expected_values);
  41. } else {
  42. BOOST_CHECK(values.empty());
  43. }
  44. }
  45. (comm.barrier)();
  46. }
  47. template<typename Generator>
  48. void
  49. gatherv_test(const communicator& comm, Generator generator,
  50. const char* kind, int root = -1)
  51. {
  52. typedef typename Generator::result_type value_type;
  53. if (root == -1) {
  54. for (root = 0; root < comm.size(); ++root)
  55. gatherv_test(comm, generator, kind, root);
  56. } else {
  57. using boost::mpi::gatherv;
  58. int mysize = comm.rank() + 1;
  59. int nprocs = comm.size();
  60. // process p will send p+1 identical generator(p) elements
  61. std::vector<value_type> myvalues(mysize, generator(comm.rank()));
  62. if (comm.rank() == root) {
  63. std::vector<value_type> values((nprocs*(nprocs+1))/2);
  64. std::vector<int> sizes(comm.size());
  65. for (int p = 0; p < comm.size(); ++p)
  66. sizes[p] = p + 1;
  67. std::cout << "Gatheringv " << kind << " from root "
  68. << root << "..." << std::endl;
  69. gatherv(comm, myvalues, &values[0], sizes, root);
  70. std::vector<value_type> expected_values;
  71. for (int p = 0; p < comm.size(); ++p)
  72. for (int i = 0; i < p+1; ++i)
  73. expected_values.push_back(generator(p));
  74. BOOST_CHECK(values == expected_values);
  75. } else {
  76. gatherv(comm, myvalues, root);
  77. }
  78. }
  79. (comm.barrier)();
  80. }
  81. //
  82. // Generators to test with gather/gatherv
  83. //
  84. struct int_generator
  85. {
  86. typedef int result_type;
  87. int operator()(int p) const { return 17 + p; }
  88. };
  89. struct gps_generator
  90. {
  91. typedef gps_position result_type;
  92. gps_position operator()(int p) const
  93. {
  94. return gps_position(39 + p, 16, 20.2799);
  95. }
  96. };
  97. struct string_generator
  98. {
  99. typedef std::string result_type;
  100. std::string operator()(int p) const
  101. {
  102. std::string result = boost::lexical_cast<std::string>(p);
  103. result += " rosebud";
  104. if (p != 1) result += 's';
  105. return result;
  106. }
  107. };
  108. struct string_list_generator
  109. {
  110. typedef std::list<std::string> result_type;
  111. std::list<std::string> operator()(int p) const
  112. {
  113. std::list<std::string> result;
  114. for (int i = 0; i <= p; ++i) {
  115. std::string value = boost::lexical_cast<std::string>(i);
  116. result.push_back(value);
  117. }
  118. return result;
  119. }
  120. };
  121. BOOST_AUTO_TEST_CASE(gather_check)
  122. {
  123. boost::mpi::environment env;
  124. communicator comm;
  125. gather_test(comm, int_generator(), "integers");
  126. gather_test(comm, gps_generator(), "GPS positions");
  127. gather_test(comm, string_generator(), "string");
  128. gather_test(comm, string_list_generator(), "list of strings");
  129. gatherv_test(comm, int_generator(), "integers");
  130. gatherv_test(comm, gps_generator(), "GPS positions");
  131. gatherv_test(comm, string_generator(), "string");
  132. gatherv_test(comm, string_list_generator(), "list of strings");
  133. }