GCC Code Coverage Report


Directory: ./
File: tasks/liulin_y_matrix_max_column/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 78 78 100.0%
Functions: 9 9 100.0%
Branches: 65 92 70.7%

Line Branch Exec Source
1 #include "liulin_y_matrix_max_column/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <limits>
8 #include <vector>
9
10 #include "liulin_y_matrix_max_column/common/include/common.hpp"
11
12 namespace liulin_y_matrix_max_column {
13
14
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 int LiulinYMatrixMaxColumnMPI::TournamentMax(const std::vector<int> &column) {
15
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 if (column.empty()) {
16 return std::numeric_limits<int>::min();
17 }
18
19 49 int size = static_cast<int>(column.size());
20 49 std::vector<int> temp = column;
21
22
2/2
✓ Branch 0 taken 153 times.
✓ Branch 1 taken 49 times.
202 while (size > 1) {
23 int new_size = 0;
24
2/2
✓ Branch 0 taken 594 times.
✓ Branch 1 taken 153 times.
747 for (int i = 0; i < size; i += 2) {
25
4/4
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 250 times.
✓ Branch 3 taken 272 times.
844 temp[new_size] = (i + 1 < size) ? std::max(temp[i], temp[i + 1]) : temp[i];
26 594 ++new_size;
27 }
28 size = new_size;
29 }
30 49 return temp[0];
31 }
32
33
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 LiulinYMatrixMaxColumnMPI::LiulinYMatrixMaxColumnMPI(const InType &in) {
34 SetTypeOfTask(GetStaticTypeOfTask());
35
36 GetInput().clear();
37
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 GetInput().reserve(in.size());
38
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 24 times.
166 for (const auto &row : in) {
39
1/2
✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
142 GetInput().push_back(row);
40 }
41
42 GetOutput().clear();
43 24 }
44
45 24 bool LiulinYMatrixMaxColumnMPI::ValidationImpl() {
46 const auto &in = GetInput();
47
48 if (in.empty() || in[0].empty()) {
49 return true;
50 }
51
52 const std::size_t cols = in[0].size();
53
54 for (const auto &row : in) {
55 if (row.size() != cols) {
56 return true;
57 }
58 }
59
60 return true;
61 }
62
63 24 bool LiulinYMatrixMaxColumnMPI::PreProcessingImpl() {
64 24 return true;
65 }
66
67 namespace {
68 20 void PrepareCounts(int rows, int cols, int world_size, std::vector<int> &sendcounts, std::vector<int> &displs) {
69 20 sendcounts.assign(world_size, 0);
70 20 displs.assign(world_size, 0);
71
72 20 int base_cols = cols / world_size;
73 20 int remainder = cols % world_size;
74
75
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int proc = 0; proc < world_size; ++proc) {
76
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 14 times.
40 int local_cols = base_cols + (proc < remainder ? 1 : 0);
77
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
40 sendcounts[proc] = local_cols * rows;
78
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
40 if (proc > 0) {
79 20 displs[proc] = displs[proc - 1] + sendcounts[proc - 1];
80 }
81 }
82 20 }
83
84 10 void FillFlatMatrix(const InType &in, int rows, int cols, std::vector<int> &flat_matrix) {
85 10 flat_matrix.resize(static_cast<std::size_t>(rows) * static_cast<std::size_t>(cols));
86
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 10 times.
59 for (int col = 0; col < cols; ++col) {
87
2/2
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 49 times.
620 for (int row = 0; row < rows; ++row) {
88 571 flat_matrix[(col * rows) + row] = in[row][col];
89 }
90 }
91 10 }
92
93 20 std::vector<int> ComputeLocalMaxes(const std::vector<int> &local_data, int rows, int local_cols) {
94 20 std::vector<int> local_maxes(local_cols, std::numeric_limits<int>::min());
95
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 20 times.
69 for (int col_idx = 0; col_idx < local_cols; ++col_idx) {
96
1/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
49 std::vector<int> column(rows);
97
2/2
✓ Branch 0 taken 571 times.
✓ Branch 1 taken 49 times.
620 for (int row = 0; row < rows; ++row) {
98 571 column[row] = local_data[(col_idx * rows) + row];
99 }
100
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
49 local_maxes[col_idx] = LiulinYMatrixMaxColumnMPI::TournamentMax(column);
101 }
102 20 return local_maxes;
103 }
104 } // namespace
105
106 24 bool LiulinYMatrixMaxColumnMPI::RunImpl() {
107 const auto &in = GetInput();
108 auto &out = GetOutput();
109
110 24 int world_size = 0;
111 24 int world_rank = 0;
112 24 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
113 24 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
114
115 24 int rows = 0;
116 24 int cols = 0;
117
6/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 1 times.
24 if (world_rank == 0 && !in.empty() && !in[0].empty()) {
118 10 rows = static_cast<int>(in.size());
119 10 cols = static_cast<int>(in[0].size());
120 }
121
122 24 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
123 24 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
124
125
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
24 if (rows <= 0 || cols <= 0) {
126 out.clear();
127 4 return true;
128 }
129
130 20 out.assign(cols, std::numeric_limits<int>::min());
131
132 20 std::vector<int> sendcounts;
133 20 std::vector<int> displs;
134
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 PrepareCounts(rows, cols, world_size, sendcounts, displs);
135
136 20 std::vector<int> flat_matrix;
137
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (world_rank == 0) {
138
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 FillFlatMatrix(in, rows, cols, flat_matrix);
139 }
140
141
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 int local_cols = sendcounts[world_rank] / rows;
142 20 int local_elements = local_cols * rows;
143
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
20 std::vector<int> local_data(local_elements);
144
145
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
30 MPI_Scatterv(world_rank == 0 ? flat_matrix.data() : nullptr, sendcounts.data(), displs.data(), MPI_INT,
146 local_data.data(), local_elements, MPI_INT, 0, MPI_COMM_WORLD);
147
148
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<int> local_maxes = ComputeLocalMaxes(local_data, rows, local_cols);
149
150
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> recvcounts(world_size);
151
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> displs_gather(world_size, 0);
152
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int proc = 0; proc < world_size; ++proc) {
153
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
40 recvcounts[proc] = sendcounts[proc] / rows;
154
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
40 if (proc > 0) {
155 20 displs_gather[proc] = displs_gather[proc - 1] + recvcounts[proc - 1];
156 }
157 }
158
159
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Gatherv(local_maxes.data(), local_cols, MPI_INT, out.data(), recvcounts.data(), displs_gather.data(), MPI_INT, 0,
160 MPI_COMM_WORLD);
161
162
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Bcast(out.data(), cols, MPI_INT, 0, MPI_COMM_WORLD);
163
164 return true;
165 }
166
167 24 bool LiulinYMatrixMaxColumnMPI::PostProcessingImpl() {
168 24 return true;
169 }
170
171 } // namespace liulin_y_matrix_max_column
172