GCC Code Coverage Report


Directory: ./
File: tasks/chernov_t_max_matrix_columns/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 98 100 98.0%
Functions: 9 9 100.0%
Branches: 52 80 65.0%

Line Branch Exec Source
1 #include "chernov_t_max_matrix_columns/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <array>
7 #include <cstddef>
8 #include <vector>
9
10 #include "chernov_t_max_matrix_columns/common/include/common.hpp"
11
12 namespace chernov_t_max_matrix_columns {
13
14
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 ChernovTMaxMatrixColumnsMPI::ChernovTMaxMatrixColumnsMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 GetInput() = in;
17 4 GetOutput() = std::vector<int>();
18 4 }
19
20 4 bool ChernovTMaxMatrixColumnsMPI::ValidationImpl() {
21 auto &input = GetInput();
22 4 std::size_t m = std::get<0>(input);
23 4 std::size_t n = std::get<1>(input);
24 std::vector<int> &matrix = std::get<2>(input);
25
26
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 valid_ = (m > 0) && (n > 0) && (matrix.size() == m * n);
27 4 return valid_;
28 }
29
30 4 bool ChernovTMaxMatrixColumnsMPI::PreProcessingImpl() {
31 4 int rank = 0;
32 4 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
33
34
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!valid_) {
35 return false;
36 }
37
38
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank == 0) {
39 auto &input = GetInput();
40 2 rows_ = std::get<0>(input);
41 2 cols_ = std::get<1>(input);
42 2 input_matrix_ = std::get<2>(input);
43 }
44
45 return true;
46 }
47
48 4 bool ChernovTMaxMatrixColumnsMPI::RunImpl() {
49 4 int rank = 0;
50 4 int size = 0;
51 4 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
52 4 MPI_Comm_size(MPI_COMM_WORLD, &size);
53
54
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!valid_) {
55 GetOutput() = std::vector<int>();
56 return false;
57 }
58
59 4 BroadcastDimensions(rank);
60 4 std::vector<int> local_data = ScatterMatrixData(rank, size);
61
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 std::vector<int> local_maxima = ComputeLocalMaxima(rank, size, local_data);
62
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 ComputeAndBroadcastResult(local_maxima);
63
64 return true;
65 }
66
67 4 void ChernovTMaxMatrixColumnsMPI::BroadcastDimensions(int rank) {
68 4 std::array<int, 2> dimensions{};
69
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank == 0) {
70 2 dimensions[0] = static_cast<int>(rows_);
71 2 dimensions[1] = static_cast<int>(cols_);
72 }
73 4 MPI_Bcast(dimensions.data(), 2, MPI_INT, 0, MPI_COMM_WORLD);
74 4 total_rows_ = dimensions[0];
75 4 total_cols_ = dimensions[1];
76 4 }
77
78 4 std::vector<int> ChernovTMaxMatrixColumnsMPI::ScatterMatrixData(int rank, int size) {
79 4 int base_cols = total_cols_ / size;
80 4 int remainder = total_cols_ % size;
81
82 int my_cols = base_cols;
83
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (rank < remainder) {
84 1 my_cols++;
85 }
86
87 4 int my_elements = my_cols * total_rows_;
88 4 std::vector<int> local_data(my_elements);
89
90
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<int> send_counts(size, 0);
91
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<int> displacements(size, 0);
92 4 std::vector<int> reordered_data;
93
94
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank == 0) {
95
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 reordered_data.resize(static_cast<std::size_t>(total_rows_) * static_cast<std::size_t>(total_cols_));
96
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 for (int col = 0; col < total_cols_; ++col) {
97
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 for (int row = 0; row < total_rows_; ++row) {
98 13 reordered_data[(static_cast<std::size_t>(col) * static_cast<std::size_t>(total_rows_)) +
99 13 static_cast<std::size_t>(row)] =
100 13 input_matrix_[(static_cast<std::size_t>(row) * static_cast<std::size_t>(total_cols_)) +
101 13 static_cast<std::size_t>(col)];
102 }
103 }
104
105 int current_displacement = 0;
106
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < size; ++i) {
107 int cols_for_i = base_cols;
108
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (i < remainder) {
109 1 cols_for_i++;
110 }
111 4 send_counts[i] = cols_for_i * total_rows_;
112 4 displacements[i] = current_displacement;
113 4 current_displacement += send_counts[i];
114 }
115 }
116
117
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(send_counts.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
118
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(displacements.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
119
120
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank == 0) {
121
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 MPI_Scatterv(reordered_data.data(), send_counts.data(), displacements.data(), MPI_INT, local_data.data(),
122 my_elements, MPI_INT, 0, MPI_COMM_WORLD);
123 } else {
124 std::vector<int> dummy_sendbuf;
125
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 MPI_Scatterv(dummy_sendbuf.data(), send_counts.data(), displacements.data(), MPI_INT, local_data.data(),
126 my_elements, MPI_INT, 0, MPI_COMM_WORLD);
127 }
128
129 4 return local_data;
130 }
131
132 4 std::vector<int> ChernovTMaxMatrixColumnsMPI::ComputeLocalMaxima(int rank, int size,
133 const std::vector<int> &local_data) const {
134 4 int base_cols = total_cols_ / size;
135 4 int remainder = total_cols_ % size;
136
137 int my_cols = base_cols;
138
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (rank < remainder) {
139 1 my_cols++;
140 }
141
142 4 std::vector<int> local_maxima(my_cols);
143
144
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 for (int local_col = 0; local_col < my_cols; ++local_col) {
145 5 int max_val = local_data[(static_cast<std::size_t>(local_col) * static_cast<std::size_t>(total_rows_))];
146
147
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 for (int row = 1; row < total_rows_; ++row) {
148 int element = local_data[(static_cast<std::size_t>(local_col) * static_cast<std::size_t>(total_rows_)) +
149 8 static_cast<std::size_t>(row)];
150 8 max_val = std::max(element, max_val);
151 }
152 5 local_maxima[local_col] = max_val;
153 }
154
155 4 return local_maxima;
156 }
157
158 4 void ChernovTMaxMatrixColumnsMPI::ComputeAndBroadcastResult(const std::vector<int> &local_maxima) {
159 4 int size = 0;
160 4 MPI_Comm_size(MPI_COMM_WORLD, &size);
161
162 4 int base_cols = total_cols_ / size;
163 4 int remainder = total_cols_ % size;
164
165 4 std::vector<int> recv_counts(size);
166
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<int> displacements(size);
167
168 int current_displacement = 0;
169
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (int i = 0; i < size; ++i) {
170
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 recv_counts[i] = base_cols;
171
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (i < remainder) {
172 2 recv_counts[i]++;
173 }
174 8 displacements[i] = current_displacement;
175 8 current_displacement += recv_counts[i];
176 }
177
178
2/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4 std::vector<int> result(total_cols_);
179
180
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Gatherv(local_maxima.data(), static_cast<int>(local_maxima.size()), MPI_INT, result.data(), recv_counts.data(),
181 displacements.data(), MPI_INT, 0, MPI_COMM_WORLD);
182
183
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(result.data(), total_cols_, MPI_INT, 0, MPI_COMM_WORLD);
184
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 GetOutput() = result;
185 4 }
186
187
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 bool ChernovTMaxMatrixColumnsMPI::PostProcessingImpl() {
188 input_matrix_.clear();
189 4 return true;
190 }
191
192 } // namespace chernov_t_max_matrix_columns
193