GCC Code Coverage Report


Directory: ./
File: tasks/kiselev_i_max_value_in_strings/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 83 83 100.0%
Functions: 8 8 100.0%
Branches: 59 84 70.2%

Line Branch Exec Source
1 #include "kiselev_i_max_value_in_strings/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <limits>
8 #include <utility>
9 #include <vector>
10
11 #include "kiselev_i_max_value_in_strings/common/include/common.hpp"
12
13 namespace kiselev_i_max_value_in_strings {
14
15
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 KiselevITestTaskMPI::KiselevITestTaskMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 auto in_copy = in;
18 32 GetInput() = std::move(in_copy);
19 GetOutput().clear();
20 32 }
21
22 32 bool KiselevITestTaskMPI::ValidationImpl() {
23 const auto &matrix = GetInput();
24 if (matrix.empty()) {
25 return true;
26 }
27 return true;
28 }
29
30 32 bool KiselevITestTaskMPI::PreProcessingImpl() {
31 const auto &matrix = GetInput();
32 32 GetOutput().resize(matrix.size());
33 32 return true;
34 }
35
36 32 void KiselevITestTaskMPI::DistributeRowLengths(const std::vector<std::vector<int>> &matrix, int total_rows,
37 int world_rank, int world_size, std::vector<int> &local_row_lengths,
38 std::vector<int> &len_counts, std::vector<int> &len_displs) {
39 32 std::vector<int> all_row_lengths;
40 32 int base = total_rows / world_size;
41 32 int rem = total_rows % world_size;
42
43
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (world_rank == 0) {
44
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 all_row_lengths.resize(static_cast<size_t>(total_rows));
45
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 16 times.
60 for (int i = 0; i < total_rows; ++i) {
46 44 all_row_lengths[static_cast<size_t>(i)] = static_cast<int>(matrix[static_cast<size_t>(i)].size());
47 }
48
49 int offset = 0;
50
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int pr = 0; pr < world_size; ++pr) {
51
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 12 times.
52 len_counts[pr] = base + (pr < rem ? 1 : 0);
52 32 len_displs[pr] = offset;
53 32 offset += len_counts[pr];
54 }
55 }
56
57
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MPI_Scatterv(all_row_lengths.data(), len_counts.data(), len_displs.data(), MPI_INT, local_row_lengths.data(),
58 static_cast<int>(local_row_lengths.size()), MPI_INT, 0, MPI_COMM_WORLD);
59 32 }
60
61 32 void KiselevITestTaskMPI::DistributeValues(const std::vector<std::vector<int>> &matrix, int world_rank, int world_size,
62 const std::vector<int> &len_counts, const std::vector<int> &len_displs,
63 std::vector<int> &local_values) {
64 32 std::vector<int> val_counts(world_size);
65
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<int> val_displs(world_size);
66
67
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (world_rank == 0) {
68 int offset = 0;
69
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int pr = 0; pr < world_size; ++pr) {
70 int count = 0;
71
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 32 times.
76 for (int i = 0; i < len_counts[pr]; ++i) {
72 44 count += static_cast<int>(matrix[len_displs[pr] + i].size());
73 }
74 32 val_counts[pr] = count;
75 32 val_displs[pr] = offset;
76 32 offset += count;
77 }
78 }
79
80
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MPI_Bcast(val_counts.data(), world_size, MPI_INT, 0, MPI_COMM_WORLD);
81
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MPI_Bcast(val_displs.data(), world_size, MPI_INT, 0, MPI_COMM_WORLD);
82
83 32 std::vector<int> flat_matrix;
84
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (world_rank == 0) {
85
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 int total_elements = val_displs[world_size - 1] + val_counts[world_size - 1];
86
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 flat_matrix.reserve(static_cast<size_t>(total_elements));
87
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 16 times.
60 for (const auto &row : matrix) {
88 44 flat_matrix.insert(flat_matrix.end(), row.begin(), row.end());
89 }
90 }
91
92
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 9 times.
32 int my_count = val_counts[world_rank];
93
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 9 times.
32 if (my_count > 0) {
94
1/2
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
23 local_values.resize(my_count);
95 } else {
96 local_values.clear();
97 }
98
99
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MPI_Scatterv(flat_matrix.data(), val_counts.data(), val_displs.data(), MPI_INT, local_values.data(), my_count,
100 MPI_INT, 0, MPI_COMM_WORLD);
101 32 }
102
103
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 7 times.
32 void KiselevITestTaskMPI::ComputeLocalMax(const std::vector<int> &local_values,
104 const std::vector<int> &local_row_lengths, std::vector<int> &local_result) {
105 size_t n_rows = local_row_lengths.size();
106
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 7 times.
32 if (n_rows == 0) {
107 return;
108 }
109
110 25 local_result.resize(n_rows);
111 int pos = 0;
112
113
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 25 times.
69 for (size_t rw = 0; rw < n_rows; ++rw) {
114 44 int len = local_row_lengths[rw];
115
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 40 times.
44 if (len == 0) {
116 // пустая строка → используем минимальное значение int
117 4 local_result[rw] = std::numeric_limits<int>::min();
118 } else {
119 40 int tmp_max = local_values[pos];
120
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 40 times.
189 for (int j = 1; j < len; ++j) {
121
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 89 times.
209 tmp_max = std::max(tmp_max, local_values[pos + j]);
122 }
123 40 local_result[rw] = tmp_max;
124 }
125 44 pos += len;
126 }
127 }
128
129 32 bool KiselevITestTaskMPI::RunImpl() {
130 const auto &matrix = GetInput();
131 auto &result_vector = GetOutput();
132
133 32 int world_rank = 0;
134 32 int world_size = 0;
135 32 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
136 32 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
137
138 32 int total_rows = static_cast<int>(matrix.size());
139 32 MPI_Bcast(&total_rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
140
141 32 int base = total_rows / world_size;
142 32 int rem = total_rows % world_size;
143
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 12 times.
32 int local_row_count = base + (world_rank < rem ? 1 : 0);
144
145 32 std::vector<int> local_row_lengths(local_row_count);
146
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<int> len_counts(world_size);
147
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<int> len_displs(world_size);
148
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 DistributeRowLengths(matrix, total_rows, world_rank, world_size, local_row_lengths, len_counts, len_displs);
149
150 32 std::vector<int> local_values;
151
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 DistributeValues(matrix, world_rank, world_size, len_counts, len_displs, local_values);
152
153 32 std::vector<int> local_result;
154
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 ComputeLocalMax(local_values, local_row_lengths, local_result);
155
156
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (world_rank == 0) {
157
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 result_vector.resize(total_rows);
158 }
159
160
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MPI_Gatherv(local_result.data(), local_row_count, MPI_INT, result_vector.data(), len_counts.data(), len_displs.data(),
161 MPI_INT, 0, MPI_COMM_WORLD);
162
163
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 4 times.
32 if (total_rows > 0) {
164
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Bcast(result_vector.data(), total_rows, MPI_INT, 0, MPI_COMM_WORLD);
165 }
166
167 32 return true;
168 }
169
170 32 bool KiselevITestTaskMPI::PostProcessingImpl() {
171 32 return true;
172 }
173
174 } // namespace kiselev_i_max_value_in_strings
175