GCC Code Coverage Report


Directory: ./
File: tasks/romanov_m_horizontal_matrix_vector/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 86 88 97.7%
Functions: 6 6 100.0%
Branches: 53 76 69.7%

Line Branch Exec Source
1 #include "romanov_m_horizontal_matrix_vector/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <tuple>
7 #include <vector>
8
9 #include "romanov_m_horizontal_matrix_vector/common/include/common.hpp"
10
11 namespace romanov_m_horizontal_matrix_vector {
12
13
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 RomanovMHorizontalMatrixVectorMPI::RomanovMHorizontalMatrixVectorMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15
16 16 int rank = 0;
17
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
18
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
19 GetInput() = in;
20 }
21 16 GetOutput() = std::vector<double>{};
22 16 }
23
24 16 bool RomanovMHorizontalMatrixVectorMPI::ValidationImpl() {
25 16 int rank = 0;
26 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
27
28 16 int check = 1;
29
30
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
31 const auto &input = GetInput();
32 const auto &matrix = std::get<0>(input);
33 8 const int rows = std::get<1>(input);
34 8 const int cols = std::get<2>(input);
35 const auto &vec = std::get<3>(input);
36
37
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (rows <= 0 || cols <= 0) {
38 check = 0;
39 } else {
40 8 bool mat_ok = (matrix.size() == static_cast<size_t>(rows) * static_cast<size_t>(cols));
41 bool vec_ok = (vec.size() == static_cast<size_t>(cols));
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!mat_ok || !vec_ok) {
43 check = 0;
44 }
45 }
46 }
47
48 16 MPI_Bcast(&check, 1, MPI_INT, 0, MPI_COMM_WORLD);
49
50 16 return check == 1;
51 }
52
53 16 bool RomanovMHorizontalMatrixVectorMPI::PreProcessingImpl() {
54 16 int rank = 0;
55 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
56
57 16 int rows = 0;
58
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
59 8 rows = std::get<1>(GetInput());
60 }
61 16 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
62
63
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (rows > 0) {
64 16 GetOutput().resize(static_cast<size_t>(rows));
65 }
66
67 16 return true;
68 }
69
70 16 void RomanovMHorizontalMatrixVectorMPI::CalculateDistribution(int rows, int proc_num, std::vector<int> &counts,
71 std::vector<int> &displs) {
72 16 int rows_per_proc = rows / proc_num;
73 16 int remainder = rows % proc_num;
74
75 16 counts.resize(static_cast<size_t>(proc_num));
76 16 displs.resize(static_cast<size_t>(proc_num));
77
78 int current_disp = 0;
79
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int i = 0; i < proc_num; ++i) {
80
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 26 times.
32 counts[static_cast<size_t>(i)] = rows_per_proc;
81
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 26 times.
32 if (i < remainder) {
82 6 counts[static_cast<size_t>(i)]++;
83 }
84 32 displs[static_cast<size_t>(i)] = current_disp;
85 32 current_disp += counts[static_cast<size_t>(i)];
86 }
87 16 }
88
89 16 bool RomanovMHorizontalMatrixVectorMPI::RunImpl() {
90 16 int rank = 0;
91 16 int size = 0;
92 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
93 16 MPI_Comm_size(MPI_COMM_WORLD, &size);
94
95 16 int rows = 0;
96 16 int cols = 0;
97 16 std::vector<double> vec;
98
99
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
100 8 rows = std::get<1>(GetInput());
101
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 cols = std::get<2>(GetInput());
102
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 vec = std::get<3>(GetInput());
103 }
104
105
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
106
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
107
108
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank != 0) {
109
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 vec.resize(static_cast<size_t>(cols));
110 }
111
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (cols > 0) {
112
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Bcast(vec.data(), cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
113 }
114
115 16 std::vector<int> rows_counts;
116 16 std::vector<int> rows_displs;
117
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 CalculateDistribution(rows, size, rows_counts, rows_displs);
118
119
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 std::vector<int> send_counts(static_cast<size_t>(size));
120
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 std::vector<int> send_displs(static_cast<size_t>(size));
121
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int i = 0; i < size; ++i) {
122 32 send_counts[static_cast<size_t>(i)] = rows_counts[static_cast<size_t>(i)] * cols;
123 32 send_displs[static_cast<size_t>(i)] = rows_displs[static_cast<size_t>(i)] * cols;
124 }
125
126
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 int my_rows = rows_counts[static_cast<size_t>(rank)];
127 16 int my_data_size = my_rows * cols;
128
129 16 std::vector<double> local_matrix;
130
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 if (my_data_size > 0) {
131
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 local_matrix.resize(static_cast<size_t>(my_data_size));
132 }
133
134 const double *sendbuf = nullptr;
135
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
136 sendbuf = std::get<0>(GetInput()).data();
137 }
138
139
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
30 MPI_Scatterv(sendbuf, send_counts.data(), send_displs.data(), MPI_DOUBLE,
140 (my_data_size > 0) ? local_matrix.data() : nullptr, my_data_size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
141
142 16 std::vector<double> local_res;
143
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 if (my_rows > 0) {
144
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 local_res.resize(static_cast<size_t>(my_rows));
145 }
146
147
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 16 times.
37 for (int i = 0; i < my_rows; ++i) {
148 double sum = 0.0;
149
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 21 times.
103 for (int j = 0; j < cols; ++j) {
150 82 const std::size_t idx =
151 82 (static_cast<std::size_t>(i) * static_cast<std::size_t>(cols)) + static_cast<std::size_t>(j);
152 82 sum += local_matrix[idx] * vec[static_cast<std::size_t>(j)];
153 }
154 21 local_res[static_cast<size_t>(i)] = sum;
155 }
156
157
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
30 MPI_Allgatherv((my_rows > 0) ? local_res.data() : nullptr, my_rows, MPI_DOUBLE, GetOutput().data(),
158 rows_counts.data(), rows_displs.data(), MPI_DOUBLE, MPI_COMM_WORLD);
159
160 16 return true;
161 }
162
163 16 bool RomanovMHorizontalMatrixVectorMPI::PostProcessingImpl() {
164 16 return true;
165 }
166
167 } // namespace romanov_m_horizontal_matrix_vector
168