GCC Code Coverage Report


Directory: ./
File: tasks/kruglova_a_vertical_ribbon_matvec/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 74 75 98.7%
Functions: 7 7 100.0%
Branches: 42 68 61.8%

Line Branch Exec Source
1 #include "kruglova_a_vertical_ribbon_matvec/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <vector>
7
8 #include "kruglova_a_vertical_ribbon_matvec/common/include/common.hpp"
9
10 namespace kruglova_a_vertical_ribbon_matvec {
11
12
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 KruglovaAVerticalRibbMatMPI::KruglovaAVerticalRibbMatMPI(const InType &in) {
13 SetTypeOfTask(GetStaticTypeOfTask());
14 GetInput() = in;
15 GetOutput() = {};
16 10 }
17
18 10 bool KruglovaAVerticalRibbMatMPI::ValidationImpl() {
19 10 int rank = 0;
20 10 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
21
22
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
23 5 const int rows = std::get<0>(GetInput());
24 5 const int cols = std::get<1>(GetInput());
25 const std::vector<double> &matrix = std::get<2>(GetInput());
26 const std::vector<double> &vec = std::get<3>(GetInput());
27
28
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (rows <= 0 || cols <= 0) {
29 return false;
30 }
31
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (matrix.size() != static_cast<size_t>(rows) * static_cast<size_t>(cols)) {
32 return false;
33 }
34
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (vec.size() != static_cast<size_t>(cols)) {
35 return false;
36 }
37 }
38 return true;
39 }
40
41 10 bool KruglovaAVerticalRibbMatMPI::PreProcessingImpl() {
42 10 int rank = 0;
43 10 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
44
45 10 int rows = 0;
46
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
47 5 rows = std::get<0>(GetInput());
48 }
49
50 10 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
51
52 10 GetOutput().assign(rows, 0.0);
53
54 10 return true;
55 }
56
57 namespace {
58
59 10 std::vector<int> ComputeSendCountsAndDispls(int cols, int size, std::vector<int> &displs) {
60 10 std::vector<int> sendcounts(size);
61 10 const int base_cols = cols / size;
62 10 const int rem_cols = cols % size;
63 int offset = 0;
64
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int i = 0; i < size; ++i) {
65
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
40 sendcounts[i] = base_cols + (i < rem_cols ? 1 : 0);
66 20 displs[i] = offset;
67 20 offset += sendcounts[i];
68 }
69 10 return sendcounts;
70 }
71
72 void TransposeMatrix(const std::vector<double> &matrix, std::vector<double> &transposed, int rows, int cols) {
73
2/2
✓ Branch 0 taken 760 times.
✓ Branch 1 taken 5 times.
765 for (int i = 0; i < rows; ++i) {
74
2/2
✓ Branch 0 taken 112600 times.
✓ Branch 1 taken 760 times.
113360 for (int j = 0; j < cols; ++j) {
75 112600 transposed[(static_cast<size_t>(j) * rows) + i] = matrix[(static_cast<size_t>(i) * cols) + j];
76 }
77 }
78 }
79
80 10 void LocalMatVecMul(const std::vector<double> &local_matrix, const std::vector<double> &local_b,
81 std::vector<double> &local_res, int rows, int local_cols) {
82
2/2
✓ Branch 0 taken 760 times.
✓ Branch 1 taken 10 times.
770 for (int j = 0; j < local_cols; ++j) {
83 760 const double b_val = local_b[j];
84
2/2
✓ Branch 0 taken 112600 times.
✓ Branch 1 taken 760 times.
113360 for (int i = 0; i < rows; ++i) {
85 112600 local_res[i] += local_matrix[(static_cast<size_t>(j) * rows) + i] * b_val;
86 }
87 }
88 10 }
89
90 } // namespace
91
92 10 bool KruglovaAVerticalRibbMatMPI::RunImpl() {
93 10 int rank = 0;
94 10 int size = 0;
95 10 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
96 10 MPI_Comm_size(MPI_COMM_WORLD, &size);
97
98 10 int rows = 0;
99 10 int cols = 0;
100
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
101 5 rows = std::get<0>(GetInput());
102 5 cols = std::get<1>(GetInput());
103 }
104
105 10 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
106 10 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
107
108 10 std::vector<int> displs(size);
109
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 std::vector<int> sendcounts = ComputeSendCountsAndDispls(cols, size, displs);
110
111
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 int local_cols = sendcounts[rank];
112
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<double> local_b(local_cols);
113
114
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 const double *global_b_ptr = (rank == 0) ? std::get<3>(GetInput()).data() : nullptr;
115
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(global_b_ptr, sendcounts.data(), displs.data(), MPI_DOUBLE, local_b.data(), local_cols, MPI_DOUBLE, 0,
116 MPI_COMM_WORLD);
117
118 10 std::vector<double> transposed_matrix;
119
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
120 const auto &matrix = std::get<2>(GetInput());
121
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 transposed_matrix.resize(static_cast<size_t>(rows) * cols);
122 5 TransposeMatrix(matrix, transposed_matrix, rows, cols);
123 }
124
125
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> mat_sendcounts(size);
126
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> mat_displs(size);
127
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int i = 0; i < size; ++i) {
128 20 mat_sendcounts[i] = sendcounts[i] * rows;
129 20 mat_displs[i] = displs[i] * rows;
130 }
131
132
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<double> local_matrix(static_cast<size_t>(local_cols) * rows);
133
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
15 MPI_Scatterv(rank == 0 ? transposed_matrix.data() : nullptr, mat_sendcounts.data(), mat_displs.data(), MPI_DOUBLE,
134 local_matrix.data(), local_cols * rows, MPI_DOUBLE, 0, MPI_COMM_WORLD);
135
136
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<double> local_res(rows, 0.0);
137 10 LocalMatVecMul(local_matrix, local_b, local_res, rows, local_cols);
138
139
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 double *global_res_ptr = (rank == 0) ? GetOutput().data() : nullptr;
140
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Reduce(local_res.data(), global_res_ptr, rows, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
141
142 10 return true;
143 }
144
145 10 bool KruglovaAVerticalRibbMatMPI::PostProcessingImpl() {
146 10 return true;
147 }
148
149 } // namespace kruglova_a_vertical_ribbon_matvec
150