GCC Code Coverage Report


Directory: ./
File: tasks/chetverikova_e_shell_sort_simple_merge/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 94 97 96.9%
Functions: 8 9 88.9%
Branches: 71 118 60.2%

Line Branch Exec Source
1 #include "chetverikova_e_shell_sort_simple_merge/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <cstddef>
8 #include <utility>
9 #include <vector>
10
11 #include "chetverikova_e_shell_sort_simple_merge/common/include/common.hpp"
12
13 namespace chetverikova_e_shell_sort_simple_merge {
14
15
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 ChetverikovaEShellSortSimpleMergeALL::ChetverikovaEShellSortSimpleMergeALL(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
18 6 int rank = 0;
19
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
20
21
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
22
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 GetInput() = in;
23 } else {
24 GetInput().clear();
25 }
26
27 GetOutput().clear();
28 6 }
29
30 6 bool ChetverikovaEShellSortSimpleMergeALL::ValidationImpl() {
31 6 int rank = 0;
32 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
33
34
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
35 3 return !GetInput().empty();
36 }
37
38 return true;
39 }
40
41 6 bool ChetverikovaEShellSortSimpleMergeALL::PreProcessingImpl() {
42 6 return true;
43 }
44
45
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 void ChetverikovaEShellSortSimpleMergeALL::ShellSort(std::vector<int> &data) {
46
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (data.empty()) {
47 return;
48 }
49
50 size_t n = data.size();
51
52
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 12 times.
26 for (size_t gap = n / 2; gap > 0; gap /= 2) {
53
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 14 times.
40 for (size_t i = gap; i < n; ++i) {
54 26 int temp = data[i];
55 size_t j = i;
56
57
4/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 9 times.
48 while (j >= gap && data[j - gap] > temp) {
58 22 data[j] = data[j - gap];
59 j -= gap;
60 }
61
62 26 data[j] = temp;
63 }
64 }
65 }
66
67 9 std::vector<int> ChetverikovaEShellSortSimpleMergeALL::MergeTwoSortedVectors(const std::vector<int> &a,
68 const std::vector<int> &b) {
69 9 std::vector<int> result(a.size() + b.size());
70
71 9 std::ranges::merge(a, b, result.begin());
72
73 9 return result;
74 }
75
76 void ChetverikovaEShellSortSimpleMergeALL::CalculateCountsAndDisplacements(int global_size, int processes_count,
77 std::vector<int> &counts,
78 std::vector<int> &displacements) {
79 3 const int base = global_size / processes_count;
80 3 const int remainder = global_size % processes_count;
81
82 int offset = 0;
83
84
2/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9 for (int i = 0; i < processes_count; ++i) {
85
2/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 counts[i] = base + (i < remainder ? 1 : 0);
86 6 displacements[i] = offset;
87 6 offset += counts[i];
88 }
89 }
90
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 std::vector<int> ChetverikovaEShellSortSimpleMergeALL::MergeLocalBuffers(std::vector<std::vector<int>> &local_buffers) {
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (local_buffers.empty()) {
93 return {};
94 }
95
96 std::vector<int> result = std::move(local_buffers[0]);
97
98
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 for (size_t i = 1; i < local_buffers.size(); ++i) {
99
1/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 result = MergeTwoSortedVectors(result, local_buffers[i]);
100 }
101
102 return result;
103 }
104
105 6 bool ChetverikovaEShellSortSimpleMergeALL::RunImpl() {
106 6 int rank = 0;
107 6 int size = 0;
108
109 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
110 6 MPI_Comm_size(MPI_COMM_WORLD, &size);
111
112 6 int global_size = 0;
113
114
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
115 3 global_size = static_cast<int>(GetInput().size());
116 }
117
118 6 MPI_Bcast(&global_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
119
120 6 std::vector<int> sendcounts(size);
121
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<int> displs(size);
122
123
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
124 3 CalculateCountsAndDisplacements(global_size, size, sendcounts, displs);
125 }
126
127
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(sendcounts.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
128
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(displs.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
129
130 6 int local_size = 0;
131
132
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &local_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
133
134
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<int> local_data(local_size);
135
136 const int *input_ptr = nullptr;
137
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
138 input_ptr = GetInput().data();
139 }
140
141
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Scatterv(input_ptr, sendcounts.data(), displs.data(), MPI_INT, local_data.data(), local_size, MPI_INT, 0,
142 MPI_COMM_WORLD);
143
144
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 const size_t threads = std::max(1, omp_get_max_threads());
145
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 const size_t parts = std::max<size_t>(1, std::min<size_t>(threads, local_data.size()));
146
147
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<std::vector<int>> buffers(parts);
148
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::vector<size_t> borders(parts + 1, 0);
149
150 6 const size_t block = local_data.size() / parts;
151 6 const size_t rem = local_data.size() % parts;
152
153
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for (size_t i = 0; i < parts; ++i) {
154
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
20 borders[i + 1] = borders[i] + block + (i < rem ? 1 : 0);
155 }
156
157 6 #pragma omp parallel for default(none) shared(local_data, buffers, borders, parts)
158 for (size_t i = 0; i < parts; ++i) {
159 using DiffT = std::vector<int>::difference_type;
160
161 auto begin = local_data.begin() + static_cast<DiffT>(borders[i]);
162 auto end = local_data.begin() + static_cast<DiffT>(borders[i + 1]);
163
164 std::vector<int> temp(begin, end);
165
166 ShellSort(temp);
167 buffers[i] = std::move(temp);
168 }
169
170
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::vector<int> local_sorted = MergeLocalBuffers(buffers);
171
172 6 int local_size_sorted = static_cast<int>(local_sorted.size());
173
174
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<int> recvcounts(size);
175
2/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6 std::vector<int> recvdispls(size);
176
177
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Gather(&local_size_sorted, 1, MPI_INT, recvcounts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
178
179 int total = 0;
180
181
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
182
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (int i = 0; i < size; ++i) {
183 6 recvdispls[i] = total;
184 6 total += recvcounts[i];
185 }
186
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 GetOutput().resize(total);
187 }
188
189
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
9 MPI_Gatherv(local_sorted.data(), local_size_sorted, MPI_INT, (rank == 0 ? GetOutput().data() : nullptr),
190 recvcounts.data(), recvdispls.data(), MPI_INT, 0, MPI_COMM_WORLD);
191
192
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
193
1/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 std::vector<std::vector<int>> chunks(size);
194
195
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (int i = 0; i < size; ++i) {
196 chunks[i] =
197
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
12 std::vector<int>(GetOutput().begin() + recvdispls[i], GetOutput().begin() + recvdispls[i] + recvcounts[i]);
198 }
199
200
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 GetOutput() = MergeLocalBuffers(chunks);
201 3 }
202
203 6 return true;
204 6 }
205
206 6 bool ChetverikovaEShellSortSimpleMergeALL::PostProcessingImpl() {
207 6 int rank = 0;
208
209 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
210
211 6 int output_size = 0;
212
213
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
214 3 output_size = static_cast<int>(GetOutput().size());
215 }
216
217 6 MPI_Bcast(&output_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
218
219
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank != 0) {
220 3 GetOutput().resize(output_size);
221 }
222
223 6 MPI_Bcast(GetOutput().data(), output_size, MPI_INT, 0, MPI_COMM_WORLD);
224
225 6 return true;
226 }
227
228 } // namespace chetverikova_e_shell_sort_simple_merge
229