| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "rozenberg_a_bubble_odd_even_sort/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cstddef> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "rozenberg_a_bubble_odd_even_sort/common/include/common.hpp" | ||
| 10 | |||
| 11 | namespace rozenberg_a_bubble_odd_even_sort { | ||
| 12 | |||
| 13 | 16 | void RozenbergABubbleOddEvenSortMPI::LocalBubbleSort(InType &local_buf) { | |
| 14 | 16 | int chunk = static_cast<int>(local_buf.size()); | |
| 15 |
2/2✓ Branch 0 taken 161 times.
✓ Branch 1 taken 16 times.
|
177 | for (int i = 0; i < chunk; i++) { |
| 16 |
2/2✓ Branch 0 taken 5216 times.
✓ Branch 1 taken 161 times.
|
5377 | for (int j = 0; j < chunk - 1; j++) { |
| 17 |
2/2✓ Branch 0 taken 1266 times.
✓ Branch 1 taken 3950 times.
|
5216 | if (local_buf[j] > local_buf[j + 1]) { |
| 18 | std::swap(local_buf[j], local_buf[j + 1]); | ||
| 19 | } | ||
| 20 | } | ||
| 21 | } | ||
| 22 | 16 | } | |
| 23 | |||
| 24 | 16 | void RozenbergABubbleOddEvenSortMPI::ExchangeAndMerge(InType &local_buf, int neighbor, int chunk, int neighbor_n, | |
| 25 | int rank) { | ||
| 26 | 16 | std::vector<int> neighbor_data(static_cast<size_t>(neighbor_n)); | |
| 27 |
2/6✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
16 | std::vector<int> merged(static_cast<size_t>(chunk + neighbor_n)); |
| 28 | |||
| 29 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Sendrecv(local_buf.data(), chunk, MPI_INT, neighbor, 0, neighbor_data.data(), neighbor_n, MPI_INT, neighbor, 0, |
| 30 | MPI_COMM_WORLD, MPI_STATUS_IGNORE); | ||
| 31 | |||
| 32 | 16 | std::ranges::merge(local_buf, neighbor_data, merged.begin()); | |
| 33 | |||
| 34 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank < neighbor) { |
| 35 | 8 | std::copy(merged.begin(), merged.begin() + chunk, local_buf.begin()); | |
| 36 | } else { | ||
| 37 | 8 | std::copy(merged.end() - chunk, merged.end(), local_buf.begin()); | |
| 38 | } | ||
| 39 | 16 | } | |
| 40 | |||
| 41 | 16 | RozenbergABubbleOddEvenSortMPI::RozenbergABubbleOddEvenSortMPI(const InType &in) { | |
| 42 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 43 | |||
| 44 | InType empty; | ||
| 45 | GetInput().swap(empty); | ||
| 46 | |||
| 47 |
2/2✓ Branch 0 taken 161 times.
✓ Branch 1 taken 16 times.
|
177 | for (const auto &elem : in) { |
| 48 | GetInput().push_back(elem); | ||
| 49 | } | ||
| 50 | |||
| 51 | GetOutput().clear(); | ||
| 52 | 16 | } | |
| 53 | |||
| 54 | 16 | bool RozenbergABubbleOddEvenSortMPI::ValidationImpl() { | |
| 55 | 16 | int rank = 0; | |
| 56 | 16 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 57 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 58 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | return (!(GetInput().empty())) && (GetOutput().empty()); |
| 59 | } | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | 16 | bool RozenbergABubbleOddEvenSortMPI::PreProcessingImpl() { | |
| 64 | 16 | int rank = 0; | |
| 65 | 16 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 66 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 67 | 8 | GetOutput().resize(GetInput().size()); | |
| 68 | } | ||
| 69 | 16 | return true; | |
| 70 | } | ||
| 71 | |||
| 72 | 16 | bool RozenbergABubbleOddEvenSortMPI::RunImpl() { | |
| 73 | 16 | int rank = 0; | |
| 74 | 16 | int size = 0; | |
| 75 | 16 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 76 | 16 | MPI_Comm_size(MPI_COMM_WORLD, &size); | |
| 77 | |||
| 78 | 16 | int n = 0; | |
| 79 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 80 | 8 | n = static_cast<int>(GetInput().size()); | |
| 81 | } | ||
| 82 | 16 | MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 83 | |||
| 84 | 16 | std::vector<int> sendcounts(size); | |
| 85 |
1/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
16 | std::vector<int> displs(size); |
| 86 | |||
| 87 | int sum = 0; | ||
| 88 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
|
48 | for (int i = 0; i < size; i++) { |
| 89 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 6 times.
|
58 | sendcounts[i] = (n / size) + (i < (n % size) ? 1 : 0); |
| 90 | 32 | displs[i] = sum; | |
| 91 | 32 | sum += sendcounts[i]; | |
| 92 | } | ||
| 93 | |||
| 94 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | int chunk = sendcounts[rank]; |
| 95 |
2/6✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
16 | InType local_buf(static_cast<size_t>(chunk)); |
| 96 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Scatterv(GetInput().data(), sendcounts.data(), displs.data(), MPI_INT, local_buf.data(), chunk, MPI_INT, 0, |
| 97 | MPI_COMM_WORLD); | ||
| 98 | |||
| 99 | 16 | LocalBubbleSort(local_buf); | |
| 100 | |||
| 101 | 16 | int iterations = size + n; | |
| 102 |
1/2✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
|
26 | for (int i = 0; i < iterations; i++) { |
| 103 | 26 | bool local_changed = false; | |
| 104 | 26 | bool is_even_step = (i % 2 == 0); | |
| 105 | 26 | bool is_even_rank = (rank % 2 == 0); | |
| 106 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
|
26 | int neighbor = (is_even_step == is_even_rank) ? rank + 1 : rank - 1; |
| 107 | |||
| 108 |
4/4✓ Branch 0 taken 21 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 5 times.
|
26 | if (neighbor >= 0 && neighbor < size) { |
| 109 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | InType init_data = local_buf; |
| 110 | |||
| 111 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | int neighbor_n = sendcounts[neighbor]; |
| 112 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | ExchangeAndMerge(local_buf, neighbor, chunk, neighbor_n, rank); |
| 113 | |||
| 114 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6 times.
|
16 | if (init_data != local_buf) { |
| 115 | 10 | local_changed = true; | |
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | 26 | bool any_changed = false; | |
| 120 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | MPI_Allreduce(&local_changed, &any_changed, 1, MPI_C_BOOL, MPI_LOR, MPI_COMM_WORLD); |
| 121 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16 times.
|
26 | if (!any_changed) { |
| 122 | break; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Gatherv(local_buf.data(), chunk, MPI_INT, GetOutput().data(), sendcounts.data(), displs.data(), MPI_INT, 0, |
| 127 | MPI_COMM_WORLD); | ||
| 128 | |||
| 129 | 16 | return true; | |
| 130 | } | ||
| 131 | |||
| 132 | 16 | bool RozenbergABubbleOddEvenSortMPI::PostProcessingImpl() { | |
| 133 | 16 | return true; | |
| 134 | } | ||
| 135 | |||
| 136 | } // namespace rozenberg_a_bubble_odd_even_sort | ||
| 137 |