GCC Code Coverage Report


Directory: ./
File: tasks/batushin_i_max_val_rows_matrix/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 65 65 100.0%
Functions: 8 8 100.0%
Branches: 31 46 67.4%

Line Branch Exec Source
1 #include "batushin_i_max_val_rows_matrix/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <utility>
8 #include <vector>
9
10 #include "batushin_i_max_val_rows_matrix/common/include/common.hpp"
11
12 namespace batushin_i_max_val_rows_matrix {
13
14
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 BatushinIMaxValRowsMatrixMPI::BatushinIMaxValRowsMatrixMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 GetInput() = in;
17 30 GetOutput() = std::vector<double>();
18 30 }
19
20 30 bool BatushinIMaxValRowsMatrixMPI::ValidationImpl() {
21 const auto &input = GetInput();
22 30 const size_t rows = std::get<0>(input);
23 30 const size_t columns = std::get<1>(input);
24 const auto &matrix = std::get<2>(input);
25
26
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (rows == 0 || columns == 0) {
27 return false;
28 }
29
30
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (matrix.size() != rows * columns) {
31 return false;
32 }
33
34 30 return GetOutput().empty();
35 }
36
37 30 bool BatushinIMaxValRowsMatrixMPI::PreProcessingImpl() {
38 const auto &input = GetInput();
39 30 const size_t rows = std::get<0>(input);
40 30 const size_t columns = std::get<1>(input);
41 const auto &matrix = std::get<2>(input);
42
43
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 return (rows > 0) && (columns > 0) && (matrix.size() == rows * columns);
44 }
45
46 namespace {
47
48 std::pair<size_t, size_t> GetRowRange(int rank, int proc, size_t rows) {
49 45 size_t base_rows = rows / proc;
50 45 size_t extra_rows = rows % proc;
51
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 size_t start_row = (rank * base_rows) + std::min<size_t>(rank, extra_rows);
53
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
45 size_t end_row = start_row + base_rows + (std::cmp_less(rank, extra_rows) ? 1 : 0);
54
55 return {start_row, end_row};
56 }
57
58 30 std::vector<double> CalcLocalMax(size_t start_row, size_t end_row, size_t columns, const std::vector<double> &matrix) {
59 30 std::vector<double> loc_max;
60
61
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 30 times.
177 for (size_t i = start_row; i < end_row; i++) {
62 147 double max_val = matrix[i * columns];
63
2/2
✓ Branch 0 taken 9969 times.
✓ Branch 1 taken 147 times.
10116 for (size_t j = 1; j < columns; j++) {
64 9969 double val = matrix[(i * columns) + j];
65 9969 max_val = std::max(val, max_val);
66 }
67 loc_max.push_back(max_val);
68 }
69
70 30 return loc_max;
71 }
72
73 30 void CollectResults(int rank, int proc, size_t rows, const std::vector<double> &loc_max, size_t start_row,
74 std::vector<double> &res) {
75
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
76
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 15 times.
94 for (size_t i = 0; i < loc_max.size(); i++) {
77 79 res[start_row + i] = loc_max[i];
78 }
79
80
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 for (int src = 1; src < proc; src++) {
81 auto [src_start, src_end] = GetRowRange(src, proc, rows);
82 15 size_t src_size = src_end - src_start;
83
84 15 std::vector<double> recv_buf(src_size);
85
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 MPI_Recv(recv_buf.data(), static_cast<int>(src_size), MPI_DOUBLE, src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
86
87
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 15 times.
83 for (size_t i = 0; i < src_size; i++) {
88 68 res[src_start + i] = recv_buf[i];
89 }
90 }
91 } else {
92 15 MPI_Send(loc_max.data(), static_cast<int>(loc_max.size()), MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
93 }
94 30 }
95
96 30 void SynchronizationResult(int rank, std::vector<double> &res) {
97
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
98 15 int res_size = static_cast<int>(res.size());
99 15 MPI_Bcast(&res_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
100 15 MPI_Bcast(res.data(), res_size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
101 } else {
102 15 int res_size = 0;
103 15 MPI_Bcast(&res_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
104 15 res.resize(res_size);
105 15 MPI_Bcast(res.data(), res_size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
106 }
107 30 }
108
109 } // namespace
110
111 30 bool BatushinIMaxValRowsMatrixMPI::RunImpl() {
112 30 int rank = 0;
113 30 int proc = 0;
114
115 30 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
116 30 MPI_Comm_size(MPI_COMM_WORLD, &proc);
117
118 30 size_t rows = std::get<0>(GetInput());
119
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 size_t columns = std::get<1>(GetInput());
120 const auto &matrix = std::get<2>(GetInput());
121
122
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 auto [start_row, end_row] = GetRowRange(rank, proc, rows);
123 30 auto loc_max = CalcLocalMax(start_row, end_row, columns, matrix);
124
125 30 std::vector<double> res;
126
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
127
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 res.resize(rows);
128 }
129
130
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 CollectResults(rank, proc, rows, loc_max, start_row, res);
131
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 SynchronizationResult(rank, res);
132
133
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 GetOutput() = res;
134 30 return true;
135 }
136
137 30 bool BatushinIMaxValRowsMatrixMPI::PostProcessingImpl() {
138 30 return !GetOutput().empty();
139 }
140
141 } // namespace batushin_i_max_val_rows_matrix
142