GCC Code Coverage Report


Directory: ./
File: tasks/iskhakov_d_linear_topology/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 70 78 89.7%
Functions: 8 8 100.0%
Branches: 30 52 57.7%

Line Branch Exec Source
1 #include "iskhakov_d_linear_topology/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <array>
6 #include <utility>
7 #include <vector>
8
9 #include "iskhakov_d_linear_topology/common/include/common.hpp"
10
11 namespace iskhakov_d_linear_topology {
12
13
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 IskhakovDLinearTopologyMPI::IskhakovDLinearTopologyMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 28 GetOutput() = Message{};
17 28 }
18
19 28 bool IskhakovDLinearTopologyMPI::ValidationImpl() {
20 const auto &input = GetInput();
21
22 28 int world_size = 0;
23 28 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
24
25 28 int world_rank = 0;
26 28 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
27
28
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (input.head_process < 0) {
29 return false;
30 }
31
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (input.head_process >= world_size) {
32 return false;
33 }
34
35
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (input.tail_process < 0) {
36 return false;
37 }
38
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (input.tail_process >= world_size) {
39 return false;
40 }
41
42 28 int is_valid_local = 1;
43
44
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (world_rank == input.head_process) {
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (input.data.empty()) {
46 is_valid_local = 0;
47 }
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (input.delivered) {
49 is_valid_local = 0;
50 }
51 }
52
53 28 int is_valid_global = 0;
54 28 MPI_Allreduce(&is_valid_local, &is_valid_global, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
55
56 28 return (is_valid_global == 1);
57 }
58
59 28 bool IskhakovDLinearTopologyMPI::PreProcessingImpl() {
60 28 return true;
61 }
62
63 namespace {
64
65 6 void SendData(int local_data_size, const std::vector<int> &local_data, int next_process) {
66 6 std::array<MPI_Request, 2> requests{};
67 6 MPI_Isend(&local_data_size, 1, MPI_INT, next_process, 0, MPI_COMM_WORLD, requests.data());
68 6 MPI_Isend(local_data.data(), local_data_size, MPI_INT, next_process, 1, MPI_COMM_WORLD, requests.data() + 1);
69 6 MPI_Waitall(2, requests.data(), MPI_STATUSES_IGNORE);
70 6 }
71
72 6 void ReceiveData(int &local_data_size, std::vector<int> &local_data, int previous_process) {
73 6 MPI_Recv(&local_data_size, 1, MPI_INT, previous_process, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
74 6 local_data.resize(local_data_size);
75 6 MPI_Recv(local_data.data(), local_data_size, MPI_INT, previous_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
76 6 }
77
78 16 void HandleSameProcess(int world_rank, int head_process, const Message &input, Message &result) {
79
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (world_rank == head_process) {
80 8 result.SetData(input.data);
81 8 result.delivered = true;
82 } else {
83 8 result.SetData({});
84 8 result.delivered = false;
85 }
86 16 }
87
88 } // namespace
89
90 28 bool IskhakovDLinearTopologyMPI::RunImpl() {
91 28 int world_size = 0;
92 28 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
93
94 28 int world_rank = 0;
95 28 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
96
97 const auto &input = GetInput();
98
99 28 int head_process = input.head_process;
100 28 int tail_process = input.tail_process;
101
102 28 Message result;
103 28 result.head_process = head_process;
104 28 result.tail_process = tail_process;
105
106
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 12 times.
28 if (head_process == tail_process) {
107
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 HandleSameProcess(world_rank, head_process, input, result);
108 GetOutput() = result;
109 return true;
110 }
111
112 int direction = 0;
113
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (head_process < tail_process) {
114 direction = 1;
115 } else {
116 direction = -1;
117 }
118
119 bool participate = false;
120 if (direction > 0) {
121
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 participate = ((world_rank >= head_process) && (world_rank <= tail_process));
122 } else {
123
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 participate = ((world_rank <= head_process) && (world_rank >= tail_process));
124 }
125
126 if (!participate) {
127 result.SetData({});
128 result.delivered = false;
129 GetOutput() = result;
130 return true;
131 }
132
133 12 bool is_head = (world_rank == head_process);
134 bool is_tail = (world_rank == tail_process);
135
136
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 int previous_process = is_head ? MPI_PROC_NULL : world_rank - direction;
137
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 int next_process = is_tail ? MPI_PROC_NULL : world_rank + direction;
138
139 12 std::vector<int> local_data;
140 12 int local_data_size = 0;
141
142
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (is_head) {
143
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 local_data = input.data;
144 6 local_data_size = static_cast<int>(local_data.size());
145
146
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 SendData(local_data_size, local_data, next_process);
147
148 6 result.SetData({});
149 6 result.delivered = false;
150
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 } else if (is_tail) {
151
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 ReceiveData(local_data_size, local_data, previous_process);
152
153 result.SetData(std::move(local_data));
154 6 result.delivered = true;
155 } else {
156 ReceiveData(local_data_size, local_data, previous_process);
157 SendData(local_data_size, local_data, next_process);
158
159 result.SetData({});
160 result.delivered = false;
161 }
162
163 GetOutput() = result;
164 return true;
165 }
166
167 28 bool IskhakovDLinearTopologyMPI::PostProcessingImpl() {
168 28 return true;
169 }
170
171 } // namespace iskhakov_d_linear_topology
172