GCC Code Coverage Report


Directory: ./
File: tasks/kamaletdinov_r_max_matrix_rows_elem/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 75 75 100.0%
Functions: 8 8 100.0%
Branches: 47 74 63.5%

Line Branch Exec Source
1 #include "kamaletdinov_r_max_matrix_rows_elem/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 "kamaletdinov_r_max_matrix_rows_elem/common/include/common.hpp"
11
12 namespace kamaletdinov_r_max_matrix_rows_elem {
13
14 namespace {
15 10 void PrepareScattervArrays(int mpi_size, std::size_t total_size, std::vector<int> &sendcounts,
16 std::vector<int> &displs) {
17 10 std::size_t procesess_step = total_size / mpi_size;
18 10 std::size_t remainder = total_size % mpi_size;
19
20
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int i = 0; i < mpi_size; i++) {
21
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
20 sendcounts[i] = static_cast<int>(procesess_step);
22 if (std::cmp_less(i, remainder)) {
23 4 sendcounts[i]++;
24 }
25
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 displs[i] = (i == 0) ? 0 : displs[i - 1] + sendcounts[i - 1];
26 }
27 10 }
28
29 10 void ProcessLocalMatrix(const std::vector<int> &local_matrix, std::size_t start, std::size_t end, std::size_t m,
30 std::vector<int> &max_rows_elem) {
31
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 std::size_t row = start / m;
32 std::size_t local_idx = 0;
33
34
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (!local_matrix.empty()) {
35 10 max_rows_elem[row] = local_matrix[local_idx];
36 }
37
38
2/2
✓ Branch 0 taken 1006890 times.
✓ Branch 1 taken 10 times.
1006900 for (std::size_t i = start; i < end; i++) {
39
2/2
✓ Branch 0 taken 1098 times.
✓ Branch 1 taken 1005792 times.
1006890 if (i == ((row + 1) * m)) {
40 row++;
41
1/2
✓ Branch 0 taken 1098 times.
✗ Branch 1 not taken.
1098 if (local_idx < local_matrix.size()) {
42 1098 max_rows_elem[row] = local_matrix[local_idx];
43 }
44 }
45
1/2
✓ Branch 0 taken 1006890 times.
✗ Branch 1 not taken.
1006890 if (local_idx < local_matrix.size()) {
46 1006890 max_rows_elem[row] = std::max(max_rows_elem[row], local_matrix[local_idx]);
47 }
48 1006890 local_idx++;
49 }
50 10 }
51
52 10 void MergeResults(int rank, int mpi_size, std::size_t n, std::vector<int> &max_rows_elem) {
53 10 std::vector<int> gathered_data;
54 10 std::vector<int> recvcounts;
55 10 std::vector<int> displs;
56
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
57
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 gathered_data.resize(n * mpi_size);
58
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 recvcounts.resize(mpi_size);
59
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 displs.resize(mpi_size);
60
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5 times.
15 for (int i = 0; i < mpi_size; i++) {
61 10 recvcounts[i] = static_cast<int>(n);
62 10 displs[i] = static_cast<int>(i * n);
63 }
64 }
65
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Gatherv(max_rows_elem.data(), static_cast<int>(n), MPI_INT, gathered_data.data(), recvcounts.data(),
66 displs.data(), MPI_INT, 0, MPI_COMM_WORLD);
67
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
68
2/2
✓ Branch 0 taken 1106 times.
✓ Branch 1 taken 5 times.
1111 for (std::size_t i = 0; i < n; i++) {
69
2/2
✓ Branch 0 taken 2212 times.
✓ Branch 1 taken 1106 times.
3318 for (int j = 0; j < mpi_size; j++) {
70
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 1658 times.
2766 max_rows_elem[i] = std::max(max_rows_elem[i], gathered_data[(j * n) + i]);
71 }
72 }
73 }
74
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Bcast(max_rows_elem.data(), static_cast<int>(n), MPI_INT, 0, MPI_COMM_WORLD);
75 10 }
76 } // namespace
77
78
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 KamaletdinovRMaxMatrixRowsElemMPI::KamaletdinovRMaxMatrixRowsElemMPI(const InType &in) {
79 SetTypeOfTask(GetStaticTypeOfTask());
80 GetInput() = in;
81 10 GetOutput() = std::vector<int>();
82 10 }
83
84 10 bool KamaletdinovRMaxMatrixRowsElemMPI::ValidationImpl() {
85 10 std::size_t m = std::get<0>(GetInput());
86 10 std::size_t n = std::get<1>(GetInput());
87 std::vector<int> &val = std::get<2>(GetInput());
88
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 valid_ = (n > 0) && (m > 0) && (val.size() == (n * m));
89 10 return valid_;
90 }
91
92 10 bool KamaletdinovRMaxMatrixRowsElemMPI::PreProcessingImpl() {
93
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (valid_) {
94 10 std::size_t m = std::get<0>(GetInput());
95 10 std::size_t n = std::get<1>(GetInput());
96 std::vector<int> &val = std::get<2>(GetInput());
97 10 t_matrix_ = std::vector<int>(n * m);
98
2/2
✓ Branch 0 taken 2188 times.
✓ Branch 1 taken 10 times.
2198 for (std::size_t i = 0; i < m; i++) {
99
2/2
✓ Branch 0 taken 2013780 times.
✓ Branch 1 taken 2188 times.
2015968 for (std::size_t j = 0; j < n; j++) {
100 2013780 t_matrix_[(j * m) + i] = val[(i * n) + j];
101 }
102 }
103 return true;
104 }
105 return false;
106 }
107
108 10 bool KamaletdinovRMaxMatrixRowsElemMPI::RunImpl() {
109 // проверка корректности данных
110
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (!valid_) {
111 return false;
112 }
113 // получение размера матрицы
114 10 std::size_t m = std::get<0>(GetInput());
115 10 std::size_t n = std::get<1>(GetInput());
116
117 // debug
118 // std::string deb = "\n\n-----------\n";
119 // for(std::size_t i = 0; i < n; i++) {
120 // for(std::size_t j = 0; j < m; j++) {
121 // deb += std::to_string(t_matrix_[i*m + j]) + " ";
122 // }
123 // deb += "\n";
124 // }
125 // std::cout << deb;
126
127 // данные о процессе
128 10 int rank = 0;
129 10 int mpi_size = 0;
130 10 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
131 10 MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
132
133 // Подготовка массивов для MPI_Scatterv
134 10 std::vector<int> sendcounts(mpi_size);
135
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
10 std::vector<int> displs(mpi_size);
136 10 PrepareScattervArrays(mpi_size, t_matrix_.size(), sendcounts, displs);
137
138 // Выделение памяти для локальной части матрицы
139
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> local_matrix(sendcounts[rank]);
140
141 // Распределение матрицы с помощью MPI_Scatterv
142
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(t_matrix_.data(), sendcounts.data(), displs.data(), MPI_INT, local_matrix.data(), sendcounts[rank],
143 MPI_INT, 0, MPI_COMM_WORLD);
144
145 // Обработка локальной части матрицы
146
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 std::size_t start = displs[rank];
147 10 std::size_t end = start + sendcounts[rank];
148
149 // выделение памяти для сохранения максимального элемента
150
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> max_rows_elem(n, 0);
151
152 10 ProcessLocalMatrix(local_matrix, start, end, m, max_rows_elem);
153
154 // Объединение результатов от всех процессов
155
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MergeResults(rank, mpi_size, n, max_rows_elem);
156
157 // debug output
158 // std::cout << rank << ":";
159 // for(std::size_t i = 0; i < n; i++) {
160 // std::cout << max_rows_elem[i] << " ";
161 // }
162 // std::cout << std::endl;
163
164
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 GetOutput() = max_rows_elem;
165
166 return true;
167 }
168
169 10 bool KamaletdinovRMaxMatrixRowsElemMPI::PostProcessingImpl() {
170 10 return true;
171 }
172
173 } // namespace kamaletdinov_r_max_matrix_rows_elem
174