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.
 
 
 
 
 
 

212 lignes
6.8 KiB

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