AUTH's THMMY "Parallel and distributed systems" course assignments.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

206 Zeilen
6.6 KiB

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