GCC Code Coverage Report


Directory: ./
File: tasks/kopilov_d_shell_merge/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 64 64 100.0%
Functions: 8 8 100.0%
Branches: 35 42 83.3%

Line Branch Exec Source
1 #include "kopilov_d_shell_merge/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <iterator>
8 #include <utility>
9 #include <vector>
10
11 namespace kopilov_d_shell_merge {
12
13 namespace {
14
15
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 void ShellSort(std::vector<int> &vec) {
16 const std::size_t n = vec.size();
17
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 if (n < 2) {
18 return;
19 }
20
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8 times.
21 for (std::size_t gap = n / 2; gap > 0; gap /= 2) {
21
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 13 times.
46 for (std::size_t i = gap; i < n; ++i) {
22 33 const int tmp = vec[i];
23 std::size_t j = i;
24
4/4
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 21 times.
52 while (j >= gap && vec[j - gap] > tmp) {
25 19 vec[j] = vec[j - gap];
26 j -= gap;
27 }
28 33 vec[j] = tmp;
29 }
30 }
31 }
32
33 7 std::vector<int> SimpleMerge(const std::vector<int> &a, const std::vector<int> &b) {
34
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 std::vector<int> result;
35
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 result.reserve(a.size() + b.size());
36
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 std::ranges::merge(a, b, std::back_inserter(result));
37 7 return result;
38 }
39
40 7 void SendVector(int dest, int tag, const std::vector<int> &vec, MPI_Comm comm) {
41 7 auto size = static_cast<int>(vec.size());
42 7 MPI_Send(&size, 1, MPI_INT, dest, tag, comm);
43 7 MPI_Send(vec.data(), size, MPI_INT, dest, tag, comm);
44 7 }
45
46 7 std::vector<int> RecvVector(int source, int tag, MPI_Comm comm) {
47 7 int size = 0;
48 MPI_Status status;
49 7 MPI_Recv(&size, 1, MPI_INT, source, tag, comm, &status);
50 7 std::vector<int> vec(size);
51
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 MPI_Recv(vec.data(), size, MPI_INT, source, tag, comm, &status);
52 7 return vec;
53 }
54
55 } // namespace
56
57 14 bool KopilovDShellMergeMPI::ValidationImpl() {
58 14 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank_);
59 14 MPI_Comm_size(MPI_COMM_WORLD, &world_size_);
60 14 return true;
61 }
62
63 14 bool KopilovDShellMergeMPI::PreProcessingImpl() {
64 14 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank_);
65 14 MPI_Comm_size(MPI_COMM_WORLD, &world_size_);
66
67 14 int global_size = 0;
68
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (world_rank_ == 0) {
69 7 global_size = static_cast<int>(GetInput().size());
70 }
71 14 MPI_Bcast(&global_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
72
73 14 counts_.assign(world_size_, 0);
74 14 displs_.assign(world_size_, 0);
75
76
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 const int base = (global_size > 0) ? (global_size / world_size_) : 0;
77
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 const int rem = (global_size > 0) ? (global_size % world_size_) : 0;
78
79
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
42 for (int i = 0; i < world_size_; ++i) {
80
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 6 times.
50 counts_[i] = base + (i < rem ? 1 : 0);
81 }
82
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 for (int i = 1; i < world_size_; ++i) {
83 14 displs_[i] = displs_[i - 1] + counts_[i - 1];
84 }
85
86 14 local_.resize(counts_[world_rank_]);
87
88 14 MPI_Scatterv(GetInput().data(), counts_.data(), displs_.data(), MPI_INT, local_.data(),
89 static_cast<int>(local_.size()), MPI_INT, 0, MPI_COMM_WORLD);
90
91 GetOutput().clear();
92 14 return true;
93 }
94
95 14 bool KopilovDShellMergeMPI::RunImpl() {
96 14 ShellSort(local_);
97 14 return true;
98 }
99
100 14 bool KopilovDShellMergeMPI::PostProcessingImpl() {
101
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (world_rank_ == 0) {
102
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for (int i = 1; i < world_size_; ++i) {
103 7 std::vector<int> other = RecvVector(i, 0, MPI_COMM_WORLD);
104
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
14 local_ = SimpleMerge(local_, other);
105 }
106 7 GetOutput() = std::move(local_);
107 7 auto size = static_cast<int>(GetOutput().size());
108 7 MPI_Bcast(&size, 1, MPI_INT, 0, MPI_COMM_WORLD);
109 7 MPI_Bcast(GetOutput().data(), size, MPI_INT, 0, MPI_COMM_WORLD);
110 } else {
111 7 SendVector(0, 0, local_, MPI_COMM_WORLD);
112 7 int size = 0;
113 7 MPI_Bcast(&size, 1, MPI_INT, 0, MPI_COMM_WORLD);
114 7 GetOutput().resize(size);
115 7 MPI_Bcast(GetOutput().data(), size, MPI_INT, 0, MPI_COMM_WORLD);
116 }
117 14 return true;
118 }
119
120 } // namespace kopilov_d_shell_merge
121