GCC Code Coverage Report


Directory: ./
File: tasks/vasiliev_m_bubble_sort/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 73 74 98.6%
Functions: 8 9 88.9%
Branches: 68 96 70.8%

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