GCC Code Coverage Report


Directory: ./
File: tasks/boltenkov_s_broadcast/mpi/src/ops_mpi.cpp
Date: 2026-01-09 01:27:18
Exec Total Coverage
Lines: 79 82 96.3%
Functions: 8 10 80.0%
Branches: 55 88 62.5%

Line Branch Exec Source
1 #include "boltenkov_s_broadcast/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <cstddef>
7 #include <tuple>
8 #include <utility>
9 #include <vector>
10
11 #include "boltenkov_s_broadcast/common/include/common.hpp"
12
13 namespace boltenkov_s_broadcast {
14
15
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 BoltenkovSBroadcastkMPI::BoltenkovSBroadcastkMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 6 int rank = 0;
18
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
19
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == std::get<0>(in)) {
20 GetInput() = in;
21 } else {
22 int cnt_byte = 0;
23
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (std::get<1>(in) == static_cast<size_t>(0)) {
24 1 cnt_byte = std::get<2>(in) * static_cast<int>(sizeof(int));
25
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 } else if (std::get<1>(in) == static_cast<size_t>(1)) {
26 1 cnt_byte = std::get<2>(in) * static_cast<int>(sizeof(float));
27
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } else if (std::get<1>(in) == static_cast<size_t>(2)) {
28 1 cnt_byte = std::get<2>(in) * static_cast<int>(sizeof(double));
29 }
30
31 3 std::vector<char> vec;
32
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (cnt_byte > 0) {
33
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 vec.resize(cnt_byte);
34 }
35
36 3 GetInput() = std::make_tuple(std::get<0>(in), std::get<1>(in), std::get<2>(in), std::move(vec));
37 }
38 6 GetOutput() = std::make_tuple(-1, -1, std::vector<char>());
39 6 mpi_type_ = MPI_DOUBLE;
40 6 }
41
42 MPI_Datatype BoltenkovSBroadcastkMPI::GetTypeData(const int &ind_data_type) {
43
2/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (ind_data_type == 0) {
44 return MPI_INT;
45 }
46
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if (ind_data_type == 1) {
47 3 return MPI_FLOAT;
48 }
49 return MPI_DOUBLE;
50 }
51
52 6 bool BoltenkovSBroadcastkMPI::ValidationImpl() {
53 6 int rank = 0;
54 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
55
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == std::get<0>(GetInput())) {
56 3 int size = 0;
57 3 MPI_Comm_size(MPI_COMM_WORLD, &size);
58
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 return std::get<0>(GetInput()) >= 0 && std::get<0>(GetInput()) < size && std::get<2>(GetInput()) >= 0 &&
59
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
6 !std::get<3>(GetInput()).empty() && std::get<1>(GetInput()) >= 0 && std::get<1>(GetInput()) < 3;
60 }
61 return true;
62 }
63
64 6 bool BoltenkovSBroadcastkMPI::PreProcessingImpl() {
65 6 int rank = 0;
66 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
67
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == std::get<0>(GetInput())) {
68
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 int ind_data_type = std::get<1>(GetInput());
69 3 mpi_type_ = GetTypeData(ind_data_type);
70 }
71 12 int type_int = GetIndTypeData(mpi_type_);
72 6 MPI_Bcast(&type_int, 1, MPI_INT, std::get<0>(GetInput()), MPI_COMM_WORLD);
73 6 mpi_type_ = GetTypeData(type_int);
74 6 return true;
75 }
76
77 int BoltenkovSBroadcastkMPI::GetIndTypeData(MPI_Datatype datatype) {
78
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
6 if (datatype == MPI_INT) {
79 return 0;
80 }
81
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 1 times.
9 if (datatype == MPI_FLOAT) {
82 return 1;
83 }
84
2/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
6 if (datatype == MPI_DOUBLE) {
85 6 return 2;
86 }
87 return -1;
88 }
89
90 6 bool BoltenkovSBroadcastkMPI::CheckLeftChild(int left_child, int shift_left_child, MPI_Comm comm) {
91 6 int rank = 0;
92 6 int size = 0;
93 6 MPI_Comm_rank(comm, &rank);
94 6 MPI_Comm_size(comm, &size);
95
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 return shift_left_child < size && left_child != rank;
96 }
97
98 6 bool BoltenkovSBroadcastkMPI::CheckRightChild(int right_child, int shift_right_child, MPI_Comm comm) {
99 6 int rank = 0;
100 6 int size = 0;
101 6 MPI_Comm_rank(comm, &rank);
102 6 MPI_Comm_size(comm, &size);
103
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 return shift_right_child < size && right_child != rank;
104 }
105
106 6 int BoltenkovSBroadcastkMPI::MyBcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm) {
107 6 int rank = 0;
108 6 int size = 0;
109 6 MPI_Comm_rank(comm, &rank);
110 6 MPI_Comm_size(comm, &size);
111
112
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (size == 1) {
113 return MPI_SUCCESS;
114 }
115
116 // for root = 0
117 6 int shift_rank = (rank - root + size) % size;
118
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 int shift_parent = (shift_rank == 0) ? -1 : (shift_rank - 1) / 2;
119 6 int shift_left_child = (2 * shift_rank) + 1;
120 6 int shift_right_child = (2 * shift_rank) + 2;
121
122 // for cur root
123 6 int parent = (shift_parent + root) % size;
124 6 int left_child = (shift_left_child + root) % size;
125 6 int right_child = (shift_right_child + root) % size;
126
127
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank != root) {
128 3 MPI_Recv(buffer, count, datatype, parent, 0, comm, MPI_STATUS_IGNORE);
129 }
130
131
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 if (CheckLeftChild(left_child, shift_left_child, comm)) {
132 3 MPI_Send(buffer, count, datatype, left_child, 0, comm);
133 }
134
135
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (CheckRightChild(right_child, shift_right_child, comm)) {
136 MPI_Send(buffer, count, datatype, right_child, 0, comm);
137 }
138
139 return MPI_SUCCESS;
140 }
141
142 6 bool BoltenkovSBroadcastkMPI::RunImpl() {
143 6 int res_mpi = MyBcast(static_cast<void *>(std::get<3>(GetInput()).data()), std::get<2>(GetInput()), mpi_type_,
144 std::get<0>(GetInput()), MPI_COMM_WORLD);
145
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 GetOutput() = std::make_tuple(GetIndTypeData(mpi_type_), std::get<2>(GetInput()), std::get<3>(GetInput()));
146 6 return res_mpi == MPI_SUCCESS;
147 }
148
149 6 bool BoltenkovSBroadcastkMPI::PostProcessingImpl() {
150
4/8
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
6 return std::get<1>(GetOutput()) >= 0 && !std::get<2>(GetOutput()).empty() && std::get<0>(GetOutput()) >= 0 &&
151 6 std::get<0>(GetOutput()) <= 2;
152 }
153
154 } // namespace boltenkov_s_broadcast
155