GCC Code Coverage Report


Directory: ./
File: tasks/zagryadskov_m_max_by_column/mpi/src/max_by_column.cpp
Date: 2026-02-02 01:14:38
Exec Total Coverage
Lines: 79 89 88.8%
Functions: 6 6 100.0%
Branches: 54 106 50.9%

Line Branch Exec Source
1 #include "zagryadskov_m_max_by_column/mpi/include/max_by_column.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <limits>
7 #include <stdexcept>
8 #include <utility>
9 #include <vector>
10
11 #include "zagryadskov_m_max_by_column/common/include/common.hpp"
12
13 namespace zagryadskov_m_max_by_column {
14
15
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 ZagryadskovMMaxByColumnMPI::ZagryadskovMMaxByColumnMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 4 int world_rank = 0;
18 int err_code = 0;
19
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 err_code = MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
20
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
21 throw std::runtime_error("MPI_Comm_rank failed");
22 }
23
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank == 0) {
24 GetInput() = in;
25 }
26 4 }
27
28 4 bool ZagryadskovMMaxByColumnMPI::ValidationImpl() {
29 bool res = false;
30 4 int world_rank = 0;
31 int err_code = 0;
32 4 err_code = MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
33
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
34 throw std::runtime_error("MPI_Comm_rank failed");
35 }
36
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank == 0) {
37 size_t mat_size = std::get<1>(GetInput()).size();
38 2 size_t n = std::get<0>(GetInput());
39 2 bool if_dividable = mat_size % n == 0;
40 2 bool if_suits_int = mat_size <= static_cast<size_t>(std::numeric_limits<int>::max());
41
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 res = (n > 0) && (mat_size > 0) && (GetOutput().empty()) && if_dividable && if_suits_int;
42 } else {
43 res = true;
44 }
45 4 return res;
46 }
47
48 4 bool ZagryadskovMMaxByColumnMPI::PreProcessingImpl() {
49 4 return true;
50 }
51
52 4 bool ZagryadskovMMaxByColumnMPI::SecondPhase(int m, int n, int world_size, int world_rank, std::vector<int> &sendcounts,
53 std::vector<int> &displs, OutType &res, OutType &local_res,
54 MPI_Datatype datatype) {
55 int r = 0;
56 int err_code = 0;
57
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (r = 0; r < world_size; ++r) {
58
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 sendcounts[r] /= m;
59
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (r > 0) {
60 4 displs[r] = displs[r - 1] + sendcounts[r - 1];
61 }
62 }
63
64 4 err_code = MPI_Gatherv(local_res.data(), static_cast<int>(local_res.size()), datatype, res.data(), sendcounts.data(),
65 displs.data(), datatype, 0, MPI_COMM_WORLD);
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
67 throw std::runtime_error("MPI_Gatherv failed");
68 }
69
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank != 0) {
70 2 res.resize(n);
71 }
72 // sequential version requires not to call MPI funcs
73 4 err_code = MPI_Bcast(res.data(), static_cast<int>(res.size()), datatype, 0, MPI_COMM_WORLD);
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
75 throw std::runtime_error("MPI_Bcast failed");
76 }
77
78 bool result = false;
79
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank == 0) {
80 2 result = !res.empty();
81 } else {
82 result = true;
83 }
84 4 err_code = MPI_Barrier(MPI_COMM_WORLD);
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
86 throw std::runtime_error("MPI_Barrier failed");
87 }
88 4 return result;
89 }
90
91 4 bool ZagryadskovMMaxByColumnMPI::RunImpl() {
92 4 int world_size = 0;
93 4 int world_rank = 0;
94 int err_code = 0;
95 4 err_code = MPI_Comm_size(MPI_COMM_WORLD, &world_size);
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
97 throw std::runtime_error("MPI_Comm_size failed");
98 }
99 4 err_code = MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
101 throw std::runtime_error("MPI_Comm_rank failed");
102 }
103 4 int n = 0;
104 const void *mat_data = nullptr;
105
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 int m = 0;
106 OutType &res = GetOutput();
107 4 OutType local_res;
108 4 OutType columns;
109
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<int> sendcounts(world_size);
110
2/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 std::vector<int> displs(world_size);
111
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!displs.empty()) {
112 4 displs[0] = 0;
113 }
114
115
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank == 0) {
116 2 n = static_cast<int>(std::get<0>(GetInput()));
117 const auto &mat = std::get<1>(GetInput());
118 2 m = static_cast<int>(mat.size()) / n;
119 mat_data = reinterpret_cast<const void *>(mat.data());
120 }
121
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 err_code = MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
123 throw std::runtime_error("MPI_Bcast failed");
124 }
125
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 err_code = MPI_Bcast(&m, 1, MPI_INT, 0, MPI_COMM_WORLD);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err_code != MPI_SUCCESS) {
127 throw std::runtime_error("MPI_Bcast failed");
128 }
129
130 4 int columns_count = n / world_size;
131 using T = double; // datatype cannot be sent to other processes
132 MPI_Datatype datatype = MPI_DOUBLE;
133
134 int i = 0;
135 int j = 0;
136 int r = 0;
137 T tmp = std::numeric_limits<T>::lowest();
138 bool tmp_flag = false;
139
140
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank == 0) {
141
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 res.assign(n, std::numeric_limits<T>::lowest());
142 }
143
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (r = 0; r < world_size; ++r) {
144
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 sendcounts[r] = (columns_count + static_cast<int>(r < (n % world_size))) * m;
145
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (r > 0) {
146 4 displs[r] = displs[r - 1] + sendcounts[r - 1];
147 }
148 }
149
150
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 local_res.assign(static_cast<size_t>(sendcounts[world_rank] / m), std::numeric_limits<T>::lowest());
151
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 columns.resize(sendcounts[world_rank]);
152
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 err_code = MPI_Scatterv(mat_data, sendcounts.data(), displs.data(), datatype, columns.data(), sendcounts[world_rank],
153 datatype, 0, MPI_COMM_WORLD);
154
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (err_code != MPI_SUCCESS) {
155 throw std::runtime_error("MPI_Scatterv failed");
156 }
157 4101 for (j = 0; std::cmp_less(j, local_res.size()); ++j) {
158
2/2
✓ Branch 0 taken 8388658 times.
✓ Branch 1 taken 4101 times.
8392759 for (i = 0; i < m; ++i) {
159 8388658 tmp = columns[(j * m) + i];
160 8388658 tmp_flag = tmp > local_res[j];
161 8388658 local_res[j] = (static_cast<T>(tmp_flag) * tmp) + (static_cast<T>(!tmp_flag) * local_res[j]);
162 }
163 }
164
165
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 return SecondPhase(m, n, world_size, world_rank, sendcounts, displs, res, local_res, datatype);
166 }
167
168 4 bool ZagryadskovMMaxByColumnMPI::PostProcessingImpl() {
169 bool result = false;
170 4 int world_rank = 0;
171 4 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
172
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (world_rank == 0) {
173 2 result = !GetOutput().empty();
174 } else {
175 result = true;
176 }
177 4 return result;
178 }
179
180 } // namespace zagryadskov_m_max_by_column
181