GCC Code Coverage Report


Directory: ./
File: tasks/dergynov_s_hypercube/mpi/src/ops_mpi.cpp
Date: 2026-02-23 23:20:07
Exec Total Coverage
Lines: 91 97 93.8%
Functions: 9 11 81.8%
Branches: 51 88 58.0%

Line Branch Exec Source
1 #include "dergynov_s_hypercube/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <numeric>
7 #include <vector>
8
9 #include "dergynov_s_hypercube/common/include/common.hpp"
10
11 namespace dergynov_s_hypercube {
12
13
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 DergynovSHypercubeMPI::DergynovSHypercubeMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GetInput() = in;
16 12 GetOutput() = 0;
17 12 }
18
19 int DergynovSHypercubeMPI::CalcDim(int size) {
20 int dim = 0;
21 int cap = 1;
22
2/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 while (cap < size) {
23 8 cap <<= 1;
24 8 dim++;
25 }
26 return dim;
27 }
28
29 8 std::vector<int> DergynovSHypercubeMPI::BuildPath(int src, int dst, int dim) {
30 8 std::vector<int> path;
31 8 int cur = src;
32
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 int diff = src ^ dst;
33 path.push_back(cur);
34
35
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (int dim_idx = 0; dim_idx < dim; ++dim_idx) {
36
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if ((diff & (1 << dim_idx)) != 0) {
37
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 cur ^= (1 << dim_idx);
38 path.push_back(cur);
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (cur == dst) {
40 break;
41 }
42 }
43 }
44 8 return path;
45 }
46
47 8 void DergynovSHypercubeMPI::FindPos(int rank, const std::vector<int> &path, int &pos, int &next, int &prev) {
48 8 pos = -1;
49 8 next = -1;
50 8 prev = -1;
51
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 for (std::size_t idx = 0; idx < path.size(); ++idx) {
52
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 if (path[idx] == rank) {
53 8 pos = static_cast<int>(idx);
54
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (idx > 0) {
55 4 prev = path[idx - 1];
56 }
57
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (idx + 1 < path.size()) {
58 4 next = path[idx + 1];
59 }
60 break;
61 }
62 }
63 8 }
64
65 4 void DergynovSHypercubeMPI::SendVec(const std::vector<int> &data, int to) {
66 4 int sz = static_cast<int>(data.size());
67 4 MPI_Send(&sz, 1, MPI_INT, to, 0, MPI_COMM_WORLD);
68
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (sz > 0) {
69 3 MPI_Send(data.data(), sz, MPI_INT, to, 1, MPI_COMM_WORLD);
70 }
71 4 }
72
73 4 void DergynovSHypercubeMPI::RecvVec(std::vector<int> &data, int from) {
74 4 int sz = 0;
75 4 MPI_Recv(&sz, 1, MPI_INT, from, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
76 4 data.resize(sz);
77
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (sz > 0) {
78 3 MPI_Recv(data.data(), sz, MPI_INT, from, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
79 }
80 4 }
81
82 void DergynovSHypercubeMPI::BusyWork(int iters) {
83 8 volatile int x = 0;
84
4/8
✓ Branch 0 taken 480000 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 480000 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
960008 for (int i = 0; i < iters; ++i) {
85 960000 x = (x * 31 + i) % 1000003;
86 }
87 8 (void)x;
88 4 }
89
90 12 bool DergynovSHypercubeMPI::ValidationImpl() {
91 12 int size = 0;
92 12 MPI_Comm_size(MPI_COMM_WORLD, &size);
93 auto &in = GetInput();
94
3/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 8 times.
12 if (in[0] < 0 || in[0] >= size) {
95 4 in[0] = 0;
96 }
97
3/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
12 if (in[1] < 0 || in[1] >= size) {
98 6 in[1] = size - 1;
99 }
100 12 return true;
101 }
102
103 12 bool DergynovSHypercubeMPI::PreProcessingImpl() {
104 12 GetOutput() = 0;
105 12 return true;
106 }
107
108 12 bool DergynovSHypercubeMPI::RunImpl() {
109 12 int rank = 0;
110 12 int size = 0;
111 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
112 12 MPI_Comm_size(MPI_COMM_WORLD, &size);
113
114 const auto &in = GetInput();
115 12 int src = in[0];
116 12 int dst = in[1];
117 12 int data_size = in[2];
118
119 12 std::vector<int> data;
120
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == src) {
121
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 data.resize(data_size, 1);
122 }
123
124
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (src == dst) {
125
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(&data_size, 1, MPI_INT, dst, MPI_COMM_WORLD);
126
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank != dst) {
127
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 data.resize(data_size);
128 }
129
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(data.data(), data_size, MPI_INT, dst, MPI_COMM_WORLD);
130 4 GetOutput() = std::accumulate(data.begin(), data.end(), 0);
131 4 return true;
132 }
133
134 8 int dim = CalcDim(size);
135
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 auto path = BuildPath(src, dst, dim);
136
137 int pos = -1;
138 int next = -1;
139 int prev = -1;
140 8 FindPos(rank, path, pos, next, prev);
141
142
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (pos != -1) {
143
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == src) {
144 BusyWork(120000);
145
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 SendVec(data, next);
146
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 } else if (rank == dst) {
147
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 RecvVec(data, prev);
148 BusyWork(120000);
149 } else {
150 RecvVec(data, prev);
151 BusyWork(120000);
152 SendVec(data, next);
153 }
154 }
155
156 8 int final_size = static_cast<int>(data.size());
157
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(&final_size, 1, MPI_INT, dst, MPI_COMM_WORLD);
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (pos == -1) {
159 data.resize(final_size);
160 }
161
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(data.data(), final_size, MPI_INT, dst, MPI_COMM_WORLD);
162
163 8 GetOutput() = std::accumulate(data.begin(), data.end(), 0);
164
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Barrier(MPI_COMM_WORLD);
165 return true;
166 }
167
168 12 bool DergynovSHypercubeMPI::PostProcessingImpl() {
169 12 return true;
170 }
171
172 } // namespace dergynov_s_hypercube
173