GCC Code Coverage Report


Directory: ./
File: tasks/mityaeva_d_min_v_rows_matrix/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 71 76 93.4%
Functions: 7 7 100.0%
Branches: 48 82 58.5%

Line Branch Exec Source
1 #include "mityaeva_d_min_v_rows_matrix/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "mityaeva_d_min_v_rows_matrix/common/include/common.hpp"
10
11 namespace mityaeva_d_min_v_rows_matrix {
12
13
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MinValuesInRowsMPI::MinValuesInRowsMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GetInput() = in;
16
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GetOutput() = std::vector<int>{0};
17 12 }
18
19
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 bool MinValuesInRowsMPI::ValidationImpl() {
20 const auto &input = GetInput();
21
22
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 if (input.empty() || input.size() < 2) {
23 return false;
24 }
25
26 12 int rows = input[0];
27 12 int cols = input[1];
28
29
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (rows <= 0 || cols <= 0) {
30 return false;
31 }
32
33 12 size_t expected_size = 2 + (static_cast<size_t>(rows) * static_cast<size_t>(cols));
34 12 return input.size() == expected_size;
35 }
36
37 12 bool MinValuesInRowsMPI::PreProcessingImpl() {
38 12 return true;
39 }
40
41 12 std::vector<int> ProcessLocalRows(const std::vector<int> &input, int start_row, int my_rows, int cols) {
42 12 std::vector<int> local_result;
43
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 local_result.reserve(my_rows);
44
45
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 12 times.
26 for (int i = 0; i < my_rows; ++i) {
46 14 int global_row = start_row + i;
47 14 int row_start_index = 2 + (global_row * cols);
48
49
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (cols == 0) {
50 local_result.push_back(0);
51 continue;
52 }
53
54 14 int min_val = input[row_start_index];
55
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 14 times.
39 for (int j = 1; j < cols; ++j) {
56 25 int current_val = input[row_start_index + j];
57 25 min_val = std::min(current_val, min_val);
58 }
59 local_result.push_back(min_val);
60 }
61
62 12 return local_result;
63 }
64
65 12 void GatherResults(int rank, int size, int rows, int rows_per_process, int remainder,
66 const std::vector<int> &local_result, std::vector<int> &output) {
67
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
68 6 std::vector<int> global_result;
69
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 global_result.reserve(rows);
70
71 6 global_result.insert(global_result.end(), local_result.begin(), local_result.end());
72
73
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int src = 1; src < size; ++src) {
74 int src_rows = rows_per_process;
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (src < remainder) {
76 src_rows++;
77 }
78
79
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (src_rows > 0) {
80
2/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4 std::vector<int> recv_buffer(src_rows);
81
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Recv(recv_buffer.data(), src_rows, MPI_INT, src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
82
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 global_result.insert(global_result.end(), recv_buffer.begin(), recv_buffer.end());
83 }
84 }
85
86 output.clear();
87
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 output.reserve(rows + 1);
88 output.push_back(rows);
89 6 output.insert(output.end(), global_result.begin(), global_result.end());
90
91 6 int output_size = static_cast<int>(output.size());
92
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int dst = 1; dst < size; ++dst) {
93
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Send(output.data(), output_size, MPI_INT, dst, 0, MPI_COMM_WORLD);
94 }
95
96 } else {
97
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (!local_result.empty()) {
98 4 int local_size = static_cast<int>(local_result.size());
99 4 MPI_Send(local_result.data(), local_size, MPI_INT, 0, 0, MPI_COMM_WORLD);
100 }
101
102 6 int result_size = 0;
103 MPI_Status status;
104 6 MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
105 6 MPI_Get_count(&status, MPI_INT, &result_size);
106
107 6 std::vector<int> recv_buffer(result_size);
108
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Recv(recv_buffer.data(), result_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
109
110
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 output = recv_buffer;
111 }
112 12 }
113
114
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 bool MinValuesInRowsMPI::RunImpl() {
115 const auto &input = GetInput();
116
117 try {
118 12 int rank = 0;
119 12 int size = 0;
120
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
121
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Comm_size(MPI_COMM_WORLD, &size);
122
123 12 int rows = input[0];
124 12 int cols = input[1];
125
126 12 int rows_per_process = rows / size;
127 12 int remainder = rows % size;
128
129 int my_rows = rows_per_process;
130
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (rank < remainder) {
131 4 my_rows++;
132 }
133
134 int start_row = 0;
135
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
18 for (int i = 0; i < rank; ++i) {
136 int previous_rows = rows_per_process;
137
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (i < remainder) {
138 4 previous_rows++;
139 }
140 6 start_row += previous_rows;
141 }
142
143
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 std::vector<int> local_result = ProcessLocalRows(input, start_row, my_rows, cols);
144
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GatherResults(rank, size, rows, rows_per_process, remainder, local_result, GetOutput());
145
146
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Barrier(MPI_COMM_WORLD);
147 return true;
148
149 } catch (...) {
150 return false;
151 }
152 }
153
154
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 bool MinValuesInRowsMPI::PostProcessingImpl() {
155 const auto &output = GetOutput();
156
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 return !output.empty() && output[0] > 0;
157 }
158
159 } // namespace mityaeva_d_min_v_rows_matrix
160