GCC Code Coverage Report


Directory: ./
File: tasks/kapanova_s_min_of_matrix_elements/mpi/src/ops_mpi.cpp
Date: 2026-01-09 01:27:18
Exec Total Coverage
Lines: 60 60 100.0%
Functions: 6 6 100.0%
Branches: 34 44 77.3%

Line Branch Exec Source
1 #include "kapanova_s_min_of_matrix_elements/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <climits>
7 #include <cstddef>
8 #include <utility> // ДОБАВИТЬ для std::pair
9 #include <vector>
10
11 #include "kapanova_s_min_of_matrix_elements/common/include/common.hpp"
12
13 namespace kapanova_s_min_of_matrix_elements {
14
15
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 KapanovaSMinOfMatrixElementsMPI::KapanovaSMinOfMatrixElementsMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 GetInput().resize(in.size());
18
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 20 times.
62 for (size_t i = 0; i < in.size(); ++i) {
19
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 GetInput()[i] = in[i];
20 }
21 20 GetOutput() = 0;
22 20 }
23
24
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
20 bool KapanovaSMinOfMatrixElementsMPI::ValidationImpl() {
25 const auto &matrix = GetInput();
26
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
20 if (matrix.empty()) {
27 return true;
28 }
29
30 const size_t cols = matrix[0].size();
31 return std::ranges::all_of(matrix, [cols](const auto &row) { return row.size() == cols; });
32 }
33
34 20 bool KapanovaSMinOfMatrixElementsMPI::PreProcessingImpl() {
35 20 GetOutput() = INT_MAX;
36 20 return true;
37 }
38
39 namespace {
40
41 // Вспомогательные функции для уменьшения когнитивной сложности
42
43 std::pair<int, int> GetMatrixDimensions(int rank, const InType &matrix) {
44 int total_rows = 0;
45 int total_cols = 0;
46
47 20 if (rank == 0) {
48
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 if (!matrix.empty()) {
49 9 total_rows = static_cast<int>(matrix.size());
50 9 total_cols = static_cast<int>(matrix[0].size());
51 }
52 }
53
54 return {total_rows, total_cols};
55 }
56
57 18 std::vector<int> PrepareAndBroadcastMatrix(int rank, int total_rows, int total_cols, const InType &matrix) {
58 18 std::vector<int> flat_matrix;
59 18 const size_t total_elements = static_cast<size_t>(total_rows) * static_cast<size_t>(total_cols);
60
61
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (rank == 0) {
62
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 flat_matrix.resize(total_elements);
63
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9 times.
30 for (int i = 0; i < total_rows; ++i) {
64
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 21 times.
71 for (int j = 0; j < total_cols; ++j) {
65 // ИСПРАВЛЕНО: добавлены скобки
66 50 const size_t index = (static_cast<size_t>(i) * static_cast<size_t>(total_cols)) + static_cast<size_t>(j);
67 50 flat_matrix[index] = matrix[i][j];
68 }
69 }
70 } else {
71
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 flat_matrix.resize(total_elements);
72 }
73
74
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 MPI_Bcast(flat_matrix.data(), static_cast<int>(total_elements), MPI_INT, 0, MPI_COMM_WORLD);
75 18 return flat_matrix;
76 }
77
78 std::pair<int, int> CalculateLocalRange(int rank, int size, int total_rows, int total_cols) {
79 18 const int total_elements = total_rows * total_cols;
80 18 const int elements_per_process = total_elements / size;
81 18 const int remainder = total_elements % size;
82
83 int start_element = 0;
84 int end_element = 0;
85
86 18 if (rank < remainder) {
87 4 start_element = rank * (elements_per_process + 1);
88 4 end_element = start_element + elements_per_process + 1;
89 } else {
90 // ИСПРАВЛЕНО: добавлены скобки
91 14 start_element = (rank * elements_per_process) + remainder;
92 14 end_element = start_element + elements_per_process;
93 }
94
95 return {start_element, end_element};
96 }
97
98 int FindLocalMinimum(const std::vector<int> &flat_matrix, int start_element, int end_element, int total_cols) {
99 18 int local_min = INT_MAX;
100
101
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 18 times.
68 for (int elem_idx = start_element; elem_idx < end_element; ++elem_idx) {
102 const int row = elem_idx / total_cols;
103 const int col = elem_idx % total_cols;
104 // ИСПРАВЛЕНО: добавлены скобки
105 const int index = (row * total_cols) + col;
106
107 // ИСПРАВЛЕНО: используем std::min вместо сравнения
108
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 30 times.
70 local_min = std::min(flat_matrix[index], local_min);
109 }
110
111 18 return local_min;
112 }
113
114 int FindGlobalMinimum(int local_min, int size) {
115 18 int global_min = local_min;
116
117
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (size > 1) {
118
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 MPI_Allreduce(&local_min, &global_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
119 }
120
121 18 return global_min;
122 }
123
124 } // namespace
125
126 20 bool KapanovaSMinOfMatrixElementsMPI::RunImpl() {
127 20 int rank = 0;
128 20 int size = 0;
129 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
130 20 MPI_Comm_size(MPI_COMM_WORLD, &size);
131
132 // 1. Получаем размеры матрицы
133
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 auto [total_rows, total_cols] = GetMatrixDimensions(rank, GetInput());
134 20 MPI_Bcast(&total_rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
135 20 MPI_Bcast(&total_cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
136
137 // 2. Проверяем пустую матрицу
138
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
20 if (total_rows == 0 || total_cols == 0) {
139 2 GetOutput() = INT_MAX;
140 2 return true;
141 }
142
143 // 3. Подготавливаем и рассылаем матрицу
144 18 std::vector<int> flat_matrix = PrepareAndBroadcastMatrix(rank, total_rows, total_cols, GetInput());
145
146 // 4. Определяем диапазон для текущего процесса
147
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 14 times.
18 auto [start_element, end_element] = CalculateLocalRange(rank, size, total_rows, total_cols);
148
149 // 5. Находим локальный минимум
150 int local_min = FindLocalMinimum(flat_matrix, start_element, end_element, total_cols);
151
152 // 6. Находим глобальный минимум
153 18 int global_min = FindGlobalMinimum(local_min, size);
154
155
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 GetOutput() = global_min;
156 return true;
157 }
158
159 20 bool KapanovaSMinOfMatrixElementsMPI::PostProcessingImpl() {
160 20 return true;
161 }
162
163 } // namespace kapanova_s_min_of_matrix_elements
164