GCC Code Coverage Report


Directory: ./
File: tasks/chyokotov_min_val_by_columns/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 78 78 100.0%
Functions: 8 8 100.0%
Branches: 55 74 74.3%

Line Branch Exec Source
1 #include "chyokotov_min_val_by_columns/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <climits>
7 #include <cstddef>
8 #include <vector>
9
10 #include "chyokotov_min_val_by_columns/common/include/common.hpp"
11
12 namespace chyokotov_min_val_by_columns {
13
14
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 ChyokotovMinValByColumnsMPI::ChyokotovMinValByColumnsMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 GetInput().clear();
17
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 GetInput().reserve(in.size());
18
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (const auto &row : in) {
19
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 GetInput().push_back(row);
20 }
21
22 GetOutput().clear();
23 16 }
24
25
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 bool ChyokotovMinValByColumnsMPI::ValidationImpl() {
26
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 if (GetInput().empty()) {
27 return true;
28 }
29
30 size_t length_row = GetInput()[0].size();
31 return std::ranges::all_of(GetInput(), [length_row](const auto &row) { return row.size() == length_row; });
32 }
33
34 16 bool ChyokotovMinValByColumnsMPI::PreProcessingImpl() {
35 16 int rank{};
36 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
37
38 16 int cols = 0;
39
40
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
41 const auto &input_matrix = GetInput();
42
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
8 if (!input_matrix.empty() && !input_matrix[0].empty()) {
43 size_t rows = input_matrix.size();
44 7 cols = static_cast<int>(input_matrix[0].size());
45
46
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 std::vector<std::vector<int>> tmp(cols, std::vector<int>(rows));
47
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 7 times.
23 for (size_t i = 0; i < rows; i++) {
48
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 16 times.
51 for (int j = 0; j < cols; j++) {
49 35 tmp[j][i] = input_matrix[i][j];
50 }
51 }
52
53
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 GetInput() = tmp;
54 7 }
55 }
56
57 16 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
58
59 16 GetOutput().resize(cols, INT_MAX);
60
61 16 return true;
62 }
63 namespace {
64 14 void DistributeColumns(int rank, int size, int rows, int cols, int recv_size, int loc_start,
65 std::vector<std::vector<int>> &local_cols, const std::vector<std::vector<int>> &matrix) {
66
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (rank == 0) {
67
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 7 times.
18 for (int i = 0; i < recv_size; i++) {
68 11 local_cols[i] = matrix[loc_start + i];
69 }
70
71
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for (int dest = 1; dest < size; dest++) {
72 7 int dest_base = cols / size;
73 7 int dest_rem = cols % size;
74
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 int dest_size = dest_base + (dest < dest_rem ? 1 : 0);
75 7 int dest_start = (dest * dest_base) + std::min(dest, dest_rem);
76
77
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for (int i = 0; i < dest_size; i++) {
78 7 MPI_Send(matrix[dest_start + i].data(), rows, MPI_INT, dest, 0, MPI_COMM_WORLD);
79 }
80 }
81 } else {
82
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for (int i = 0; i < recv_size; i++) {
83 7 MPI_Recv(local_cols[i].data(), rows, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
84 }
85 }
86 14 }
87
88 14 std::vector<int> CalculateLocalMins(const std::vector<std::vector<int>> &local_cols, int recv_size) {
89 14 std::vector<int> local_mins(recv_size, INT_MAX);
90
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 14 times.
32 for (int i = 0; i < recv_size; i++) {
91
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 18 times.
53 for (size_t j = 0; j < local_cols[i].size(); j++) {
92 35 local_mins[i] = std::min(local_mins[i], local_cols[i][j]);
93 }
94 }
95 14 return local_mins;
96 }
97
98 14 void PrepareGathervParams(int cols, int size, std::vector<int> &counts, std::vector<int> &displs) {
99 14 int base = cols / size;
100 14 int rem = cols % size;
101
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
42 for (int i = 0; i < size; i++) {
102
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 8 times.
48 counts[i] = base + (i < rem ? 1 : 0);
103 28 displs[i] = (i * base) + std::min(i, rem);
104 }
105 14 }
106
107 } // namespace
108
109 16 bool ChyokotovMinValByColumnsMPI::RunImpl() {
110 16 int rank{};
111 16 int size{};
112 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
113 16 MPI_Comm_size(MPI_COMM_WORLD, &size);
114
115 16 int rows{};
116 16 int cols{};
117
118
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
119 const auto &matrix = GetInput();
120
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (matrix.empty()) {
121 rows = 0;
122 cols = 0;
123 } else {
124 7 rows = static_cast<int>(matrix[0].size());
125 7 cols = static_cast<int>(matrix.size());
126 }
127 }
128
129 16 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
130 16 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
131
132
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
16 if (rows == 0 || cols == 0) {
133 return true;
134 }
135
136 14 int base = cols / size;
137 14 int rem = cols % size;
138
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
14 int recv_size = base + (rank < rem ? 1 : 0);
139 14 int loc_start = (rank * base) + std::min(rank, rem);
140
141
2/4
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
28 std::vector<std::vector<int>> local_cols(recv_size, std::vector<int>(rows));
142
143 const auto &matrix = GetInput();
144
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 DistributeColumns(rank, size, rows, cols, recv_size, loc_start, local_cols, matrix);
145
146
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 std::vector<int> local_mins = CalculateLocalMins(local_cols, recv_size);
147
148
1/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
14 std::vector<int> counts(size);
149
1/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
14 std::vector<int> displs(size);
150 14 PrepareGathervParams(cols, size, counts, displs);
151
152
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 MPI_Allgatherv(local_mins.data(), recv_size, MPI_INT, GetOutput().data(), counts.data(), displs.data(), MPI_INT,
153 MPI_COMM_WORLD);
154 return true;
155 14 }
156
157 16 bool ChyokotovMinValByColumnsMPI::PostProcessingImpl() {
158 16 return true;
159 }
160
161 } // namespace chyokotov_min_val_by_columns
162