GCC Code Coverage Report


Directory: ./
File: tasks/kutuzov_i_torus_grid/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 86 91 94.5%
Functions: 7 7 100.0%
Branches: 46 86 53.5%

Line Branch Exec Source
1 #include "kutuzov_i_torus_grid/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <string>
7 #include <tuple>
8 #include <vector>
9
10 #include "kutuzov_i_torus_grid/common/include/common.hpp"
11
12 namespace kutuzov_i_torus_grid {
13
14
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 KutuzovIThorusGridMPI::KutuzovIThorusGridMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 GetInput() = in;
17 18 GetOutput() = std::make_tuple(std::vector<int>{}, "");
18 18 }
19
20 18 bool KutuzovIThorusGridMPI::ValidationImpl() {
21 18 int start = std::get<0>(GetInput());
22 18 int end = std::get<1>(GetInput());
23
24
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (start < 0 || end < 0) {
25 return false;
26 }
27
28 18 int process_count = -1;
29 18 MPI_Comm_size(MPI_COMM_WORLD, &process_count);
30
31
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (start > process_count - 1) {
32 return false;
33 }
34
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (end > process_count - 1) {
35 return false;
36 }
37
38 return true;
39 }
40
41 18 bool KutuzovIThorusGridMPI::PreProcessingImpl() {
42 18 return true;
43 }
44
45 18 bool KutuzovIThorusGridMPI::RunImpl() {
46 18 int start = std::get<0>(GetInput());
47 18 int end = std::get<1>(GetInput());
48
49 18 int rank = -1;
50 18 int process_count = -1;
51 18 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
52 18 MPI_Comm_size(MPI_COMM_WORLD, &process_count);
53
54 std::string message;
55 18 int message_size = -1;
56
57
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (rank == start) {
58 message = std::get<2>(GetInput());
59 9 message_size = static_cast<int>(message.size());
60 }
61
62
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
18 if (start == end) {
63
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Bcast(&message_size, 1, MPI_INT, end, MPI_COMM_WORLD);
64
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 message.resize(message_size);
65
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Bcast(message.data(), message_size, MPI_CHAR, end, MPI_COMM_WORLD);
66 10 GetOutput() = std::make_tuple(std::vector<int>{}, message);
67 10 return true;
68 }
69
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (process_count == 1) {
71 GetOutput() = std::make_tuple(std::vector<int>{}, message);
72 return true;
73 }
74
75 8 int columns = -1;
76 8 int rows = -1;
77 8 GenerateTopology(columns, rows, process_count);
78
79 int sender = start;
80 8 int receiver = -1;
81 8 std::vector<int> route;
82 8 int route_size = -1;
83
84 8 int current_x = rank % columns;
85 8 int current_y = rank / columns;
86 8 int end_x = end % columns;
87 8 int end_y = end / columns;
88
89
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 while (sender != end) {
90
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == sender) {
91 4 receiver = GetNextStep(current_x, current_y, end_x, end_y, columns, rows);
92 }
93
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(&receiver, 1, MPI_INT, sender, MPI_COMM_WORLD);
94
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == sender) {
95
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Send(&message_size, 1, MPI_INT, receiver, 0, MPI_COMM_WORLD);
96
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Send(message.data(), message_size, MPI_CHAR, receiver, 1, MPI_COMM_WORLD);
97 route.push_back(rank);
98 4 route_size = static_cast<int>(route.size());
99
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Send(&route_size, 1, MPI_INT, receiver, 2, MPI_COMM_WORLD);
100
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Send(route.data(), route_size, MPI_INT, receiver, 3, MPI_COMM_WORLD);
101
102
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 } else if (rank == receiver) {
103
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Recv(&message_size, 1, MPI_INT, sender, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
104
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 message.resize(message_size);
105
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Recv(message.data(), message_size, MPI_CHAR, sender, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
106
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Recv(&route_size, 1, MPI_INT, sender, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
107
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 route.resize(route_size);
108
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Recv(route.data(), route_size, MPI_INT, sender, 3, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
109 }
110 8 sender = receiver;
111 }
112
113
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == end) {
114 route.push_back(rank);
115 4 route_size = static_cast<int>(route.size());
116 }
117
118
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(&route_size, 1, MPI_INT, end, MPI_COMM_WORLD);
119
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 route.resize(route_size);
120
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(route.data(), route_size, MPI_INT, end, MPI_COMM_WORLD);
121
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(&message_size, 1, MPI_INT, end, MPI_COMM_WORLD);
122
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 message.resize(message_size);
123
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(message.data(), message_size, MPI_CHAR, end, MPI_COMM_WORLD);
124
125
1/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 GetOutput() = std::make_tuple(route, message);
126 return true;
127 }
128
129 18 bool KutuzovIThorusGridMPI::PostProcessingImpl() {
130 18 return true;
131 }
132
133 8 void KutuzovIThorusGridMPI::GenerateTopology(int &columns, int &rows, int process_count) {
134
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (rows = static_cast<int>(std::sqrt(static_cast<double>(process_count))); rows > 0; rows--) {
135
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (process_count % rows == 0) {
136 8 columns = process_count / rows;
137 8 break;
138 }
139 }
140 8 }
141
142 4 int KutuzovIThorusGridMPI::GetNextStep(int current_x, int current_y, int dest_x, int dest_y, int columns, int rows) {
143 4 int up = (((current_y - 1 + rows) % rows) * columns) + current_x;
144 4 int down = (((current_y + 1) % rows) * columns) + current_x;
145 4 int left = (current_y * columns) + ((current_x - 1 + columns) % columns);
146 4 int right = (current_y * columns) + ((current_x + 1) % columns);
147
148 4 int mx = dest_x - current_x;
149 4 int my = dest_y - current_y;
150
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (abs(mx) > columns / 2) {
152 mx = mx > 0 ? mx - columns : mx + columns;
153 }
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (abs(my) > rows / 2) {
155 my = my > 0 ? my - rows : my + rows;
156 }
157
158
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (abs(mx) > abs(my)) {
159
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
6 return mx >= 0 ? right : left;
160 }
161
162 return my >= 0 ? down : up;
163 }
164
165 } // namespace kutuzov_i_torus_grid
166