GCC Code Coverage Report


Directory: ./
File: tasks/buzuluksky_d_bubble_sort/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 61 61 100.0%
Functions: 7 7 100.0%
Branches: 58 82 70.7%

Line Branch Exec Source
1 #include "buzuluksky_d_bubble_sort/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm> // std::ranges::merge, std::swap, std::copy_n
6 #include <cstddef> // std::size_t, std::ptrdiff_t
7 #include <vector>
8
9 #include "buzuluksky_d_bubble_sort/common/include/common.hpp"
10
11 namespace buzuluksky_d_bubble_sort {
12
13 namespace {
14
15 18 void LocalOddEvenSort(std::vector<int> &data) {
16 bool sorted = false;
17 const std::size_t n = data.size();
18
19
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 18 times.
51 while (!sorted) {
20 sorted = true;
21
22
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 33 times.
82 for (std::size_t i = 0; i + 1 < n; i += 2) {
23
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 28 times.
49 if (data[i] > data[i + 1]) {
24 std::swap(data[i], data[i + 1]);
25 sorted = false;
26 }
27 }
28
29
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 33 times.
71 for (std::size_t i = 1; i + 1 < n; i += 2) {
30
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 23 times.
38 if (data[i] > data[i + 1]) {
31 std::swap(data[i], data[i + 1]);
32 sorted = false;
33 }
34 }
35 }
36 18 }
37
38 int PartnerRank(int rank, int phase) {
39 const bool even_phase = (phase % 2) == 0;
40 const bool even_rank = (rank % 2) == 0;
41
42 54 if (even_phase) {
43
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
36 return even_rank ? rank + 1 : rank - 1;
44 }
45
46
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 return even_rank ? rank - 1 : rank + 1;
47 }
48
49
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 18 times.
54 void ExchangeWithNeighbor(std::vector<int> &local, int rank, int partner, const std::vector<int> &counts) {
50 54 const int proc_count = static_cast<int>(counts.size());
51
6/6
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 28 times.
54 if (partner < 0 || partner >= proc_count || counts[rank] == 0 || counts[partner] == 0) {
52 26 return;
53 }
54
55
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 std::vector<int> remote(static_cast<std::size_t>(counts[partner]));
56
57
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Sendrecv(local.data(), static_cast<int>(local.size()), MPI_INT, partner, 0, remote.data(),
58 static_cast<int>(remote.size()), MPI_INT, partner, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
59
60
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
28 std::vector<int> merged(local.size() + remote.size());
61 28 std::ranges::merge(local, remote, merged.begin());
62
63 const std::size_t local_size = local.size();
64
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank < partner) {
65 14 std::copy_n(merged.begin(), local_size, local.begin());
66 } else {
67 14 std::copy_n(merged.end() - static_cast<std::ptrdiff_t>(local_size), local_size, local.begin());
68 }
69 }
70
71 } // namespace
72
73
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 BuzulukskyDBubbleSortMPI::BuzulukskyDBubbleSortMPI(const InType &input) {
74 SetTypeOfTask(GetStaticTypeOfTask());
75
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 GetInput() = input;
76 static_cast<void>(GetOutput());
77 18 }
78
79 18 bool BuzulukskyDBubbleSortMPI::ValidationImpl() {
80 18 return true;
81 }
82
83 18 bool BuzulukskyDBubbleSortMPI::PreProcessingImpl() {
84 18 return true;
85 }
86
87 18 bool BuzulukskyDBubbleSortMPI::RunImpl() {
88 18 int rank = 0;
89 18 int proc_count = 1;
90
91 18 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
92 18 MPI_Comm_size(MPI_COMM_WORLD, &proc_count);
93
94 const auto &input = GetInput();
95 18 const int n = static_cast<int>(input.size());
96
97 18 std::vector<int> counts(proc_count, 0);
98
1/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 std::vector<int> displs(proc_count, 0);
99
100
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (rank == 0) {
101 int offset = 0;
102 9 const int base = n / proc_count;
103 9 const int remainder = n % proc_count;
104
105
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9 times.
27 for (int i = 0; i < proc_count; ++i) {
106
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
32 counts[i] = base + (i < remainder ? 1 : 0);
107 18 displs[i] = offset;
108 18 offset += counts[i];
109 }
110 }
111
112
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 MPI_Bcast(counts.data(), proc_count, MPI_INT, 0, MPI_COMM_WORLD);
113
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 MPI_Bcast(displs.data(), proc_count, MPI_INT, 0, MPI_COMM_WORLD);
114
115
1/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 std::vector<int> local(static_cast<std::size_t>(counts[rank]));
116
117
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
27 MPI_Scatterv(rank == 0 ? input.data() : nullptr, counts.data(), displs.data(), MPI_INT, local.data(), counts[rank],
118 MPI_INT, 0, MPI_COMM_WORLD);
119
120 18 LocalOddEvenSort(local);
121
122
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 18 times.
72 for (int phase = 0; phase < proc_count + 1; ++phase) {
123
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 18 times.
54 const int partner = PartnerRank(rank, phase);
124
1/2
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
54 ExchangeWithNeighbor(local, rank, partner, counts);
125 }
126
127
1/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 std::vector<int> result(static_cast<std::size_t>(n));
128
129
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
27 MPI_Gatherv(local.data(), counts[rank], MPI_INT, rank == 0 ? result.data() : nullptr, counts.data(), displs.data(),
130 MPI_INT, 0, MPI_COMM_WORLD);
131
132
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 GetOutput().resize(n);
133
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (rank == 0) {
134
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 GetOutput() = result;
135 }
136
137
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
18 if (n > 0) {
138
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Bcast(GetOutput().data(), n, MPI_INT, 0, MPI_COMM_WORLD);
139 }
140
141 18 return true;
142 }
143
144 18 bool BuzulukskyDBubbleSortMPI::PostProcessingImpl() {
145 18 return true;
146 }
147
148 } // namespace buzuluksky_d_bubble_sort
149