GCC Code Coverage Report


Directory: ./
File: tasks/urin_o_max_val_in_col_of_mat/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 83 90 92.2%
Functions: 9 10 90.0%
Branches: 51 86 59.3%

Line Branch Exec Source
1 #include "urin_o_max_val_in_col_of_mat/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <utility>
8 #include <vector>
9
10 // #include "urin_o_max_val_in_col_of_mat/common/include/common.hpp"
11 /*#include "util/include/util.hpp"*/
12
13 namespace urin_o_max_val_in_col_of_mat {
14
15
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 UrinOMaxValInColOfMatMPI::UrinOMaxValInColOfMatMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 // GetInput() = in;
18
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (!in.empty()) {
19
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 GetInput() = in;
20 } else {
21 GetInput() = InType(); // Explicit empty vector
22 }
23 28 GetOutput() = std::vector<int>();
24 28 }
25
26 28 bool UrinOMaxValInColOfMatMPI::ValidationImpl() {
27 28 int rank = 0;
28 28 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
29
30 28 bool is_valid = false;
31 28 int rows = 0;
32 28 int cols = 0;
33
34
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
35 const auto &matrix = this->GetInput();
36
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 is_valid = !matrix.empty() && !matrix[0].empty();
37
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (is_valid) {
38 14 rows = static_cast<int>(matrix.size());
39 14 cols = static_cast<int>(matrix[0].size());
40 // Проверяем что матрица прямоугольная
41
2/2
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 14 times.
672 for (const auto &row : matrix) {
42 // if (row.size() != static_cast<size_t>(cols)) {
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 658 times.
658 if (row.size() != static_cast<size_t>(cols)) {
44 is_valid = false;
45 break;
46 }
47 }
48 }
49 /*if (!is_valid) {
50 rows = 0;
51 cols = 0;
52 }*/
53 }
54
55 // Рассылаем результат валидации и размеры матрицы
56 28 MPI_Bcast(&is_valid, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD);
57 28 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
58 28 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
59
60 28 return is_valid;
61 }
62
63 28 bool UrinOMaxValInColOfMatMPI::PreProcessingImpl() {
64 28 return true;
65 }
66
67 28 bool UrinOMaxValInColOfMatMPI::RunImpl() {
68 28 int rank = 0;
69 28 int size = 0;
70 28 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
71 28 MPI_Comm_size(MPI_COMM_WORLD, &size);
72
73 28 auto [rows, cols] = GetMatrixDimensions(rank);
74
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
28 if (rows == 0 || cols == 0) {
75 GetOutput() = OutType();
76 return true;
77 }
78
79
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 std::vector<std::vector<int>> local_matrix(rows, std::vector<int>(cols));
80
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 DistributeMatrixData(rank, rows, cols, local_matrix);
81 28 auto column_dist = CalculateColumnDistribution(rank, size, cols);
82 int start_col = column_dist.first;
83 int local_cols_count = column_dist.second;
84
85 // Compute local maxima
86 28 auto local_maxima = ComputeLocalMaxima(local_matrix, rows, start_col, local_cols_count);
87
88 /*auto [start_col, local_cols_count] = CalculateColumnDistribution(rank, size, cols);
89 auto local_maxima = ComputeLocalMaxima(local_matrix, rows, start_col, local_cols_count);*/
90
91
3/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 26 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
56 GetOutput() = GatherResults(local_maxima, size, cols);
92 return true;
93 28 }
94
95 // Helper method 1: Get matrix dimensions
96 28 std::pair<int, int> UrinOMaxValInColOfMatMPI::GetMatrixDimensions(int rank) {
97 28 int rows = 0;
98 28 int cols = 0;
99
100
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
101 const auto &matrix = this->GetInput(); // Явное использование this->
102
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 if (matrix.empty() || matrix[0].empty()) {
103 rows = 0;
104 cols = 0;
105 } else {
106 14 rows = static_cast<int>(matrix.size());
107 14 cols = static_cast<int>(matrix[0].size());
108 }
109 }
110
111 28 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
112 28 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
113
114 28 return std::make_pair(rows, cols);
115 }
116
117 28 void UrinOMaxValInColOfMatMPI::DistributeMatrixData(int rank, int rows, int cols,
118 std::vector<std::vector<int>> &local_matrix) {
119
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
120 const auto &source_matrix = this->GetInput(); // Явное использование this->
121
2/2
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 14 times.
672 for (int i = 0; i < rows; ++i) {
122 658 std::copy(source_matrix[i].begin(), source_matrix[i].end(), local_matrix[i].begin());
123 658 MPI_Bcast(local_matrix[i].data(), cols, MPI_INT, 0, MPI_COMM_WORLD);
124 }
125 } else {
126
2/2
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 14 times.
672 for (int i = 0; i < rows; ++i) {
127 658 MPI_Bcast(local_matrix[i].data(), cols, MPI_INT, 0, MPI_COMM_WORLD);
128 }
129 }
130 28 }
131
132 std::pair<int, int> UrinOMaxValInColOfMatMPI::CalculateColumnDistribution(int rank, int size, int cols) {
133 28 int base_cols_per_process = cols / size;
134 28 int remainder = cols % size;
135
136 int start_col = 0;
137
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 28 times.
42 for (int i = 0; i < rank; ++i) {
138
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 6 times.
22 start_col += base_cols_per_process + (i < remainder ? 1 : 0);
139 }
140
141
3/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 6 times.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
50 int local_cols_count = base_cols_per_process + (rank < remainder ? 1 : 0);
142 return std::make_pair(start_col, local_cols_count);
143 }
144
145 28 std::vector<int> UrinOMaxValInColOfMatMPI::ComputeLocalMaxima(const std::vector<std::vector<int>> &matrix, int rows,
146 int start_col, int col_count) {
147 28 std::vector<int> maxima(col_count);
148
2/2
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 28 times.
686 for (int i = 0; i < col_count; ++i) {
149 658 int global_col = start_col + i;
150 658 int max_val = matrix[0][global_col];
151
2/2
✓ Branch 0 taken 259732 times.
✓ Branch 1 taken 658 times.
260390 for (int row = 1; row < rows; ++row) {
152
2/2
✓ Branch 0 taken 132600 times.
✓ Branch 1 taken 127132 times.
392332 max_val = std::max(matrix[row][global_col], max_val);
153 }
154 658 maxima[i] = max_val;
155 }
156 28 return maxima;
157 }
158
159 28 UrinOMaxValInColOfMatMPI::OutType UrinOMaxValInColOfMatMPI::GatherResults(const std::vector<int> &local_maxima,
160 int size, int cols) {
161 28 std::vector<int> counts(size);
162
2/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
28 std::vector<int> displs(size);
163
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 int local_count = static_cast<int>(local_maxima.size());
164
165
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Allgather(&local_count, 1, MPI_INT, counts.data(), 1, MPI_INT, MPI_COMM_WORLD);
166
167 28 displs[0] = 0;
168
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 for (int i = 1; i < size; ++i) {
169 28 displs[i] = displs[i - 1] + counts[i - 1];
170 }
171
172
2/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
28 OutType result(cols);
173
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Gatherv(local_maxima.data(), local_count, MPI_INT, result.data(), counts.data(), displs.data(), MPI_INT, 0,
174 MPI_COMM_WORLD);
175
176
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Bcast(result.data(), cols, MPI_INT, 0, MPI_COMM_WORLD);
177 28 return result;
178 }
179
180 28 bool UrinOMaxValInColOfMatMPI::PostProcessingImpl() {
181 28 return !GetOutput().empty();
182 }
183
184 } // namespace urin_o_max_val_in_col_of_mat
185 //
186