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.
 
 
 
 
 
 

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