GCC Code Coverage Report


Directory: ./
File: tasks/vdovin_a_quick_sort_merge/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 93 93 100.0%
Functions: 7 7 100.0%
Branches: 84 118 71.2%

Line Branch Exec Source
1 #include "vdovin_a_quick_sort_merge/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "vdovin_a_quick_sort_merge/common/include/common.hpp"
10
11 namespace vdovin_a_quick_sort_merge {
12
13
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 VdovinAQuickSortMergeMPI::VdovinAQuickSortMergeMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 GetInput() = in;
16 GetOutput() = {};
17 28 }
18
19 28 bool VdovinAQuickSortMergeMPI::ValidationImpl() {
20 28 int rank = 0;
21 28 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
22
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (!GetOutput().empty()) {
23 return false;
24 }
25
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
26
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (GetInput().size() > 1000000) {
27 return false;
28 }
29
2/2
✓ Branch 0 taken 50233 times.
✓ Branch 1 taken 14 times.
50247 for (const auto &val : GetInput()) {
30
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50233 times.
50233 if (val < -1000000 || val > 1000000) {
31 return false;
32 }
33 }
34 }
35 return true;
36 }
37
38 28 bool VdovinAQuickSortMergeMPI::PreProcessingImpl() {
39 28 int rank = 0;
40 28 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
41 28 GetOutput() = GetInput();
42
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (GetOutput().size() != GetInput().size()) {
44 return false;
45 }
46
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
14 if (!GetOutput().empty()) {
47
2/2
✓ Branch 0 taken 50233 times.
✓ Branch 1 taken 13 times.
50246 for (size_t i = 0; i < GetOutput().size(); i++) {
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50233 times.
50233 if (GetOutput()[i] != GetInput()[i]) {
49 return false;
50 }
51 }
52 }
53 }
54 return true;
55 }
56
57 namespace {
58
59 // NOLINTNEXTLINE(misc-no-recursion)
60 44389 void QuickSort(std::vector<int> &arr, int left, int right) {
61
2/2
✓ Branch 0 taken 44389 times.
✓ Branch 1 taken 44364 times.
88753 if (left >= right) {
62 return;
63 }
64 44364 int pivot = arr[(left + right) / 2];
65 int i = left;
66 int j = right;
67
2/2
✓ Branch 0 taken 197695 times.
✓ Branch 1 taken 44364 times.
286423 while (i <= j) {
68
2/2
✓ Branch 0 taken 272642 times.
✓ Branch 1 taken 197695 times.
470337 while (arr[i] < pivot) {
69 272642 i++;
70 }
71
2/2
✓ Branch 0 taken 320488 times.
✓ Branch 1 taken 197695 times.
518183 while (arr[j] > pivot) {
72 320488 j--;
73 }
74
2/2
✓ Branch 0 taken 184064 times.
✓ Branch 1 taken 13631 times.
197695 if (i <= j) {
75 std::swap(arr[i], arr[j]);
76 184064 i++;
77 184064 j--;
78 }
79 }
80 44364 QuickSort(arr, left, j);
81 QuickSort(arr, i, right);
82 }
83
84 13 std::vector<int> Merge(const std::vector<int> &left, const std::vector<int> &right) {
85
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 std::vector<int> result;
86
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 result.reserve(left.size() + right.size());
87 size_t i = 0;
88 size_t j = 0;
89
4/4
✓ Branch 0 taken 50146 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 50141 times.
50154 while (i < left.size() && j < right.size()) {
90
2/2
✓ Branch 0 taken 25047 times.
✓ Branch 1 taken 25094 times.
50141 if (left[i] <= right[j]) {
91 result.push_back(left[i]);
92 25047 i++;
93 } else {
94 result.push_back(right[j]);
95 25094 j++;
96 }
97 }
98
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 13 times.
86 while (i < left.size()) {
99 result.push_back(left[i]);
100 73 i++;
101 }
102
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 13 times.
32 while (j < right.size()) {
103 result.push_back(right[j]);
104 19 j++;
105 }
106 13 return result;
107 }
108
109 } // namespace
110
111 28 bool VdovinAQuickSortMergeMPI::RunImpl() {
112 28 int rank = 0;
113 28 int size = 0;
114 28 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
115 28 MPI_Comm_size(MPI_COMM_WORLD, &size);
116
117
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 26 times.
28 if (GetOutput().empty()) {
118 2 MPI_Barrier(MPI_COMM_WORLD);
119 2 return true;
120 }
121
122 26 int data_size = static_cast<int>(GetOutput().size());
123 26 std::vector<int> sendcounts(size);
124
1/4
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 std::vector<int> displs(size);
125 26 int base_size = data_size / size;
126 26 int remainder = data_size % size;
127
128
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 26 times.
78 for (int i = 0; i < size; i++) {
129
4/4
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 26 times.
90 sendcounts[i] = base_size + (i < remainder ? 1 : 0);
130
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 26 times.
52 displs[i] = (i == 0) ? 0 : displs[i - 1] + sendcounts[i - 1];
131 }
132
133
1/4
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 std::vector<int> local_data(sendcounts[rank]);
134
135
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 if (rank == 0) {
136
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Scatterv(GetOutput().data(), sendcounts.data(), displs.data(), MPI_INT, local_data.data(), sendcounts[rank],
137 MPI_INT, 0, MPI_COMM_WORLD);
138 } else {
139
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Scatterv(nullptr, sendcounts.data(), displs.data(), MPI_INT, local_data.data(), sendcounts[rank], MPI_INT, 0,
140 MPI_COMM_WORLD);
141 }
142
143
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1 times.
26 if (!local_data.empty()) {
144 25 QuickSort(local_data, 0, static_cast<int>(local_data.size()) - 1);
145 }
146
147
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 if (rank == 0) {
148
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 GetOutput() = local_data;
149
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 for (int i = 1; i < size; i++) {
150
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
13 std::vector<int> recv_data(sendcounts[i]);
151
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Recv(recv_data.data(), sendcounts[i], MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
152
3/6
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
26 GetOutput() = Merge(GetOutput(), recv_data);
153 }
154
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 13 times.
26 for (int i = 1; i < size; i++) {
155
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Send(GetOutput().data(), static_cast<int>(GetOutput().size()), MPI_INT, i, 1, MPI_COMM_WORLD);
156 }
157 } else {
158
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Send(local_data.data(), static_cast<int>(local_data.size()), MPI_INT, 0, 0, MPI_COMM_WORLD);
159 13 int recv_size = 0;
160 MPI_Status status;
161
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Probe(0, 1, MPI_COMM_WORLD, &status);
162
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Get_count(&status, MPI_INT, &recv_size);
163
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 GetOutput().resize(recv_size);
164
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 MPI_Recv(GetOutput().data(), recv_size, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
165 }
166
167
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 MPI_Barrier(MPI_COMM_WORLD);
168 return true;
169 }
170
171 28 bool VdovinAQuickSortMergeMPI::PostProcessingImpl() {
172 28 int rank = 0;
173 28 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
174
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 26 times.
28 if (GetOutput().empty()) {
175 2 return GetInput().empty();
176 }
177
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (!std::is_sorted(GetOutput().begin(), GetOutput().end())) {
178 return false;
179 }
180
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (GetOutput().size() != GetInput().size()) {
181 return false;
182 }
183 int sum_input = 0;
184 int sum_output = 0;
185
2/2
✓ Branch 0 taken 100466 times.
✓ Branch 1 taken 26 times.
100492 for (const auto &val : GetInput()) {
186 100466 sum_input += val;
187 }
188
2/2
✓ Branch 0 taken 100466 times.
✓ Branch 1 taken 26 times.
100492 for (const auto &val : GetOutput()) {
189 100466 sum_output += val;
190 }
191 26 return sum_input == sum_output;
192 }
193
194 } // namespace vdovin_a_quick_sort_merge
195