GCC Code Coverage Report


Directory: ./
File: tasks/makovskiy_i_min_value_in_matrix_rows/mpi/src/ops_mpi.cpp
Date: 2025-12-13 04:24:21
Exec Total Coverage
Lines: 81 82 98.8%
Functions: 9 9 100.0%
Branches: 49 70 70.0%

Line Branch Exec Source
1 #include "makovskiy_i_min_value_in_matrix_rows/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <vector>
7
8 #include "makovskiy_i_min_value_in_matrix_rows/common/include/common.hpp"
9
10 namespace makovskiy_i_min_value_in_matrix_rows {
11
12 namespace {
13 6 void SendDataToWorkers(const InType &matrix, int size, int rows_per_proc, int remaining_rows, int &current_row_idx) {
14
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int i = 1; i < size; ++i) {
15
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 const int rows_for_this_proc = rows_per_proc + (i < remaining_rows ? 1 : 0);
16 6 MPI_Send(&rows_for_this_proc, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
17
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
11 for (int j = 0; j < rows_for_this_proc; ++j) {
18 5 const auto &row = matrix[current_row_idx++];
19 5 const auto row_size = static_cast<int>(row.size());
20 5 MPI_Send(&row_size, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
21
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (row_size > 0) {
22 5 MPI_Send(row.data(), row_size, MPI_INT, i, 2, MPI_COMM_WORLD);
23 }
24 }
25 }
26 6 }
27 } // namespace
28
29 6 void MinValueMPI::ProcessRankZero(std::vector<int> &local_min_values) {
30 const auto &matrix = this->GetInput();
31 6 int size = 0;
32 6 MPI_Comm_size(MPI_COMM_WORLD, &size);
33
34
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (size == 0) {
35 return;
36 }
37
38 6 const auto num_rows = static_cast<int>(matrix.size());
39 6 const int rows_per_proc = num_rows / size;
40 6 const int remaining_rows = num_rows % size;
41 6 int current_row_idx = 0;
42
43
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 const int rows_for_root = rows_per_proc + (0 < remaining_rows ? 1 : 0);
44
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 6 times.
15 for (int j = 0; j < rows_for_root; ++j) {
45
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 const auto &row = matrix[current_row_idx++];
46
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (!row.empty()) {
47 local_min_values.push_back(*std::ranges::min_element(row));
48 }
49 }
50
51
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (size > 1) {
52 6 SendDataToWorkers(matrix, size, rows_per_proc, remaining_rows, current_row_idx);
53 }
54 }
55
56 6 void MinValueMPI::ProcessWorkerRank(std::vector<int> &local_min_values) {
57 6 int num_local_rows = 0;
58 6 MPI_Recv(&num_local_rows, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
59
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
11 for (int i = 0; i < num_local_rows; ++i) {
60 5 int row_size = 0;
61 5 MPI_Recv(&row_size, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
62
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (row_size > 0) {
63 5 std::vector<int> received_row(row_size);
64
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 MPI_Recv(received_row.data(), row_size, MPI_INT, 0, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
65 local_min_values.push_back(*std::ranges::min_element(received_row));
66 }
67 }
68 6 }
69
70 12 void MinValueMPI::GatherResults(const std::vector<int> &local_min_values) {
71 12 int rank = 0;
72 12 int size = 0;
73 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
74 12 MPI_Comm_size(MPI_COMM_WORLD, &size);
75
76 12 const auto local_results_count = static_cast<int>(local_min_values.size());
77 12 std::vector<int> recvcounts;
78
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
79
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 recvcounts.resize(size);
80 }
81
82
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
18 MPI_Gather(&local_results_count, 1, MPI_INT, (rank == 0 ? recvcounts.data() : nullptr), 1, MPI_INT, 0,
83 MPI_COMM_WORLD);
84
85 12 std::vector<int> displs;
86
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 if (rank == 0 && size > 0) {
87
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 displs.resize(size, 0);
88
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int i = 1; i < size; ++i) {
89 6 displs[i] = displs[i - 1] + recvcounts[i - 1];
90 }
91 }
92
93
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
24 MPI_Gatherv(local_min_values.data(), local_results_count, MPI_INT, (rank == 0 ? this->GetOutput().data() : nullptr),
94
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 (rank == 0 ? recvcounts.data() : nullptr), (rank == 0 ? displs.data() : nullptr), MPI_INT, 0,
95 MPI_COMM_WORLD);
96 12 }
97
98
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MinValueMPI::MinValueMPI(const InType &in) {
99
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 InType temp(in);
100 this->GetInput().swap(temp);
101 SetTypeOfTask(GetStaticTypeOfTask());
102 12 }
103
104 12 bool MinValueMPI::ValidationImpl() {
105 12 int rank = 0;
106 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
107
108 12 int is_valid = 0;
109
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
110 const auto &mat = this->GetInput();
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 is_valid = !mat.empty() ? 1 : 0;
112 }
113 12 MPI_Bcast(&is_valid, 1, MPI_INT, 0, MPI_COMM_WORLD);
114 12 return is_valid == 1;
115 }
116
117 12 bool MinValueMPI::PreProcessingImpl() {
118 12 int rank = 0;
119 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
120
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
121 const auto &mat = this->GetInput();
122 this->GetOutput().clear();
123 6 this->GetOutput().resize(mat.size());
124 }
125 12 return true;
126 }
127
128 12 bool MinValueMPI::RunImpl() {
129 12 int rank = 0;
130 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
131
132 12 std::vector<int> local_min_values;
133
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
134
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 ProcessRankZero(local_min_values);
135 } else {
136
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 ProcessWorkerRank(local_min_values);
137 }
138
139
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GatherResults(local_min_values);
140
141 12 return true;
142 }
143
144 12 bool MinValueMPI::PostProcessingImpl() {
145 12 return true;
146 }
147
148 } // namespace makovskiy_i_min_value_in_matrix_rows
149