GCC Code Coverage Report


Directory: ./
File: tasks/tabalaev_a_linear_topology/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 60 78 76.9%
Functions: 7 12 58.3%
Branches: 33 62 53.2%

Line Branch Exec Source
1 #include "tabalaev_a_linear_topology/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <climits>
6 #include <vector>
7
8 #include "tabalaev_a_linear_topology/common/include/common.hpp"
9
10 namespace tabalaev_a_linear_topology {
11
12
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 TabalaevALinearTopologyMPI::TabalaevALinearTopologyMPI(const InType &in) {
13 SetTypeOfTask(GetStaticTypeOfTask());
14 GetInput() = in;
15 GetOutput() = {};
16 6 }
17
18 6 bool TabalaevALinearTopologyMPI::ValidationImpl() {
19 6 int world_rank = 0;
20 6 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
21
22 6 int sender = std::get<0>(GetInput());
23
24 6 int validation = 0;
25
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (world_rank == sender) {
26 3 int world_size = 0;
27 3 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
28
29 3 auto receiver = std::get<1>(GetInput());
30 3 auto data = std::get<2>(GetInput());
31
32
5/10
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
3 if (sender >= 0 && sender < world_size && receiver >= 0 && receiver < world_size && !data.empty()) {
33 3 validation = 1;
34 }
35 }
36
37 6 MPI_Bcast(&validation, 1, MPI_INT, sender, MPI_COMM_WORLD);
38
39 6 return validation != 0;
40 }
41
42 6 bool TabalaevALinearTopologyMPI::PreProcessingImpl() {
43 GetOutput() = {};
44 6 return true;
45 }
46
47 6 bool TabalaevALinearTopologyMPI::RunImpl() {
48 6 int world_size = 1;
49 6 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
50 6 int world_rank = 0;
51 6 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
52
53 6 auto sender = std::get<0>(GetInput());
54 6 auto receiver = std::get<1>(GetInput());
55
56
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (sender == receiver) {
57 2 GetOutput() = std::get<2>(GetInput());
58 2 return true;
59 }
60
61 4 int left = GetLeft(world_rank);
62 4 int right = GetRight(world_rank, world_size);
63 int direction = GetDirection(sender, receiver);
64
65 4 std::vector<int> local_buff;
66
67
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank == sender) {
68
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 ProcessSender(direction, left, right, local_buff);
69
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 } else if (world_rank == receiver) {
70
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 ProcessReceiver(direction, left, right, local_buff);
71 } else if (IsOnPath(world_rank, sender, receiver, direction)) {
72 ProcessIntermediate(direction, left, right, local_buff);
73 }
74
75
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 int data_size = (world_rank == receiver) ? static_cast<int>(local_buff.size()) : 0;
76
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(&data_size, 1, MPI_INT, receiver, MPI_COMM_WORLD);
77
78
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank != receiver) {
79
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 local_buff.resize(data_size);
80 }
81
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(local_buff.data(), data_size, MPI_INT, receiver, MPI_COMM_WORLD);
82
83
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 GetOutput() = local_buff;
84
85 return true;
86 }
87
88 6 bool TabalaevALinearTopologyMPI::PostProcessingImpl() {
89 6 return true;
90 }
91
92 int TabalaevALinearTopologyMPI::GetLeft(int rank) {
93
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 return rank == 0 ? MPI_PROC_NULL : rank - 1;
94 }
95
96 int TabalaevALinearTopologyMPI::GetRight(int rank, int size) {
97
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 return rank == (size - 1) ? MPI_PROC_NULL : rank + 1;
98 }
99
100 int TabalaevALinearTopologyMPI::GetDirection(int sender, int receiver) {
101
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 return sender < receiver ? 1 : -1;
102 }
103
104 bool TabalaevALinearTopologyMPI::IsOnPath(int rank, int sender, int receiver, int direction) {
105 if (direction == 1) {
106 return rank > sender && rank < receiver;
107 }
108 return rank < sender && rank > receiver;
109 }
110
111 2 void TabalaevALinearTopologyMPI::ProcessSender(int direction, int left, int right, std::vector<int> &local_buff) {
112 2 local_buff = std::get<2>(GetInput());
113
114 2 int size = static_cast<int>(local_buff.size());
115
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 int to = (direction == 1 ? right : left);
116
117 2 MPI_Send(&size, 1, MPI_INT, to, 0, MPI_COMM_WORLD);
118 2 MPI_Send(local_buff.data(), size, MPI_INT, to, 1, MPI_COMM_WORLD);
119 2 }
120
121 void TabalaevALinearTopologyMPI::ProcessIntermediate(int direction, int left, int right, std::vector<int> &local_buff) {
122 int from = (direction == 1 ? left : right);
123 int to = (direction == 1 ? right : left);
124
125 int size = 0;
126 MPI_Recv(&size, 1, MPI_INT, from, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
127
128 local_buff.resize(size);
129 MPI_Recv(local_buff.data(), size, MPI_INT, from, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
130
131 MPI_Send(&size, 1, MPI_INT, to, 0, MPI_COMM_WORLD);
132 MPI_Send(local_buff.data(), size, MPI_INT, to, 1, MPI_COMM_WORLD);
133 }
134
135 2 void TabalaevALinearTopologyMPI::ProcessReceiver(int direction, int left, int right, std::vector<int> &local_buff) {
136
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 int from = (direction == 1 ? left : right);
137
138 2 int size = 0;
139 2 MPI_Recv(&size, 1, MPI_INT, from, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
140
141 2 local_buff.resize(size);
142 2 MPI_Recv(local_buff.data(), size, MPI_INT, from, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
143 2 }
144
145 } // namespace tabalaev_a_linear_topology
146