AUTH's THMMY "Parallel and distributed systems" course assignments.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

211 lignes
6.7 KiB

  1. /**
  2. * \file
  3. * \brief PDS HW2 tests
  4. *
  5. * To run these test execute:
  6. * make tests
  7. * mpirun -np <N> ./out/tests
  8. *
  9. * Note:
  10. * Yes each process runs the entire test suite!!
  11. *
  12. * \author
  13. * Christos Choutouridis AEM:8997
  14. * <cchoutou@ece.auth.gr>
  15. */
  16. #include <gtest/gtest.h>
  17. #include <mpi.h>
  18. #include <random>
  19. #include "distsort.hpp"
  20. /*
  21. * Global fixtures
  22. */
  23. // MPI handler for the test session
  24. MPI_t<> ts_mpi;
  25. // Mersenne seeded from hw if possible. range: [type_min, type_max]
  26. std::random_device rd;
  27. std::mt19937 gen(rd());
  28. class TMPIdistSort : public ::testing::Test {
  29. protected:
  30. static void SetUpTestSuite() {
  31. int argc = 0;
  32. char** argv = nullptr;
  33. ts_mpi.init(&argc, &argv);
  34. }
  35. static void TearDownTestSuite() {
  36. ts_mpi.finalize();
  37. }
  38. };
  39. /*
  40. * MPI: SysTest (acceptance)
  41. * Each process executes distBubbletonic for uin8_t [16]
  42. */
  43. TEST_F(TMPIdistSort, distBubbletonic_test1) {
  44. // Create and fill vector
  45. using tsValue_t = uint8_t; // Test parameters
  46. size_t ts_buffer_size = 16;
  47. ShadowedVec_t<tsValue_t> ts_Data;
  48. std::uniform_int_distribution<tsValue_t > dis(
  49. std::numeric_limits<tsValue_t>::min(),
  50. std::numeric_limits<tsValue_t>::max()
  51. );
  52. ts_Data.resize(ts_buffer_size);
  53. std::generate(ts_Data.begin(), ts_Data.end(), [&]() { return dis(gen); });
  54. // Execute function under test in all processes
  55. distBubbletonic(ts_Data, ts_mpi.size(), ts_mpi.rank());
  56. // Local min and max
  57. auto local_min = *std::min_element(ts_Data.begin(), ts_Data.end());
  58. auto local_max = *std::max_element(ts_Data.begin(), ts_Data.end());
  59. // Gather min/max to rank 0
  60. std::vector<tsValue_t> global_mins(ts_mpi.size());
  61. std::vector<tsValue_t> global_maxes(ts_mpi.size());
  62. MPI_Datatype datatype = MPI_TypeMapper<tsValue_t>::getType();
  63. MPI_Gather(&local_min, 1, datatype, global_mins.data(), 1, datatype, 0, MPI_COMM_WORLD);
  64. MPI_Gather(&local_max, 1, datatype, global_maxes.data(), 1, datatype, 0, MPI_COMM_WORLD);
  65. // Check results
  66. EXPECT_EQ(std::is_sorted(ts_Data.begin(), ts_Data.end()), true);
  67. if (ts_mpi.rank() == 0) {
  68. for (size_t i = 1; i < global_mins.size(); ++i) {
  69. EXPECT_LE(global_maxes[i - 1], global_mins[i]);
  70. }
  71. }
  72. }
  73. /*
  74. * MPI: SysTest (acceptance)
  75. * Each process executes distBubbletonic for uin32_t [1 << 16]
  76. */
  77. TEST_F(TMPIdistSort, distBubbletonic_test2) {
  78. // Create and fill vector
  79. using tsValue_t = uint32_t; // Test parameters
  80. size_t ts_buffer_size = 1 << 16;
  81. ShadowedVec_t<tsValue_t> ts_Data;
  82. std::uniform_int_distribution<tsValue_t > dis(
  83. std::numeric_limits<tsValue_t>::min(),
  84. std::numeric_limits<tsValue_t>::max()
  85. );
  86. ts_Data.resize(ts_buffer_size);
  87. std::generate(ts_Data.begin(), ts_Data.end(), [&]() { return dis(gen); });
  88. // Execute function under test in all processes
  89. distBubbletonic(ts_Data, ts_mpi.size(), ts_mpi.rank());
  90. // Local min and max
  91. auto local_min = *std::min_element(ts_Data.begin(), ts_Data.end());
  92. auto local_max = *std::max_element(ts_Data.begin(), ts_Data.end());
  93. // Gather min/max to rank 0
  94. std::vector<tsValue_t> global_mins(ts_mpi.size());
  95. std::vector<tsValue_t> global_maxes(ts_mpi.size());
  96. MPI_Datatype datatype = MPI_TypeMapper<tsValue_t>::getType();
  97. MPI_Gather(&local_min, 1, datatype, global_mins.data(), 1, datatype, 0, MPI_COMM_WORLD);
  98. MPI_Gather(&local_max, 1, datatype, global_maxes.data(), 1, datatype, 0, MPI_COMM_WORLD);
  99. // Check results
  100. EXPECT_EQ(std::is_sorted(ts_Data.begin(), ts_Data.end()), true);
  101. if (ts_mpi.rank() == 0) {
  102. for (size_t i = 1; i < global_mins.size(); ++i) {
  103. EXPECT_LE(global_maxes[i - 1], global_mins[i]);
  104. }
  105. }
  106. }
  107. /*
  108. * MPI: SysTest (acceptance)
  109. * Each process executes distBitonic for uin8_t [16]
  110. */
  111. TEST_F(TMPIdistSort, distBitonic_test1) {
  112. // Create and fill vector
  113. using tsValue_t = uint8_t; // Test parameters
  114. size_t ts_buffer_size = 16;
  115. ShadowedVec_t<tsValue_t> ts_Data;
  116. std::uniform_int_distribution<tsValue_t > dis(
  117. std::numeric_limits<tsValue_t>::min(),
  118. std::numeric_limits<tsValue_t>::max()
  119. );
  120. ts_Data.resize(ts_buffer_size);
  121. std::generate(ts_Data.begin(), ts_Data.end(), [&]() { return dis(gen); });
  122. // Execute function under test in all processes
  123. distBitonic(ts_Data, ts_mpi.size(), ts_mpi.rank());
  124. // Local min and max
  125. auto local_min = *std::min_element(ts_Data.begin(), ts_Data.end());
  126. auto local_max = *std::max_element(ts_Data.begin(), ts_Data.end());
  127. // Gather min/max to rank 0
  128. std::vector<tsValue_t> global_mins(ts_mpi.size());
  129. std::vector<tsValue_t> global_maxes(ts_mpi.size());
  130. MPI_Datatype datatype = MPI_TypeMapper<tsValue_t>::getType();
  131. MPI_Gather(&local_min, 1, datatype, global_mins.data(), 1, datatype, 0, MPI_COMM_WORLD);
  132. MPI_Gather(&local_max, 1, datatype, global_maxes.data(), 1, datatype, 0, MPI_COMM_WORLD);
  133. // Check results
  134. EXPECT_EQ(std::is_sorted(ts_Data.begin(), ts_Data.end()), true);
  135. if (ts_mpi.rank() == 0) {
  136. for (size_t i = 1; i < global_mins.size(); ++i) {
  137. EXPECT_LE(global_maxes[i - 1], global_mins[i]);
  138. }
  139. }
  140. }
  141. /*
  142. * MPI: SysTest (acceptance)
  143. * Each process executes distBitonic for uin32_t [1 << 16]
  144. */
  145. TEST_F(TMPIdistSort, distBitonic_test2) {
  146. // Create and fill vector
  147. using tsValue_t = uint32_t; // Test parameters
  148. size_t ts_buffer_size = 1 << 16;
  149. ShadowedVec_t<tsValue_t> ts_Data;
  150. std::uniform_int_distribution<tsValue_t > dis(
  151. std::numeric_limits<tsValue_t>::min(),
  152. std::numeric_limits<tsValue_t>::max()
  153. );
  154. ts_Data.resize(ts_buffer_size);
  155. std::generate(ts_Data.begin(), ts_Data.end(), [&]() { return dis(gen); });
  156. // Execute function under test in all processes
  157. distBitonic(ts_Data, ts_mpi.size(), ts_mpi.rank());
  158. // Local min and max
  159. auto local_min = *std::min_element(ts_Data.begin(), ts_Data.end());
  160. auto local_max = *std::max_element(ts_Data.begin(), ts_Data.end());
  161. // Gather min/max to rank 0
  162. std::vector<tsValue_t> global_mins(ts_mpi.size());
  163. std::vector<tsValue_t> global_maxes(ts_mpi.size());
  164. MPI_Datatype datatype = MPI_TypeMapper<tsValue_t>::getType();
  165. MPI_Gather(&local_min, 1, datatype, global_mins.data(), 1, datatype, 0, MPI_COMM_WORLD);
  166. MPI_Gather(&local_max, 1, datatype, global_maxes.data(), 1, datatype, 0, MPI_COMM_WORLD);
  167. // Check results
  168. EXPECT_EQ(std::is_sorted(ts_Data.begin(), ts_Data.end()), true);
  169. if (ts_mpi.rank() == 0) {
  170. for (size_t i = 1; i < global_mins.size(); ++i) {
  171. EXPECT_LE(global_maxes[i - 1], global_mins[i]);
  172. }
  173. }
  174. }