GCC Code Coverage Report


Directory: ./
File: tasks/mityaeva_d_striped_horizontal_matrix_vector/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 77 79 97.5%
Functions: 7 7 100.0%
Branches: 40 78 51.3%

Line Branch Exec Source
1 #include "mityaeva_d_striped_horizontal_matrix_vector/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "mityaeva_d_striped_horizontal_matrix_vector/common/include/common.hpp"
10
11 namespace mityaeva_d_striped_horizontal_matrix_vector {
12
13 namespace {
14
15 void CalcRows(int rows, int size, int rank, int &my_rows, int &start_row) {
16 16 const int base = rows / size;
17 16 const int rem = rows % size;
18
19 16 my_rows = base + static_cast<int>(rank < rem);
20
21 start_row = 0;
22 for (int rr = 0; rr < rank; ++rr) {
23 start_row += base + static_cast<int>(rr < rem);
24 }
25 }
26
27 16 void BuildScatter(int rows, int cols, int size, std::vector<int> &counts, std::vector<int> &displs) {
28 16 counts.resize(size);
29 16 displs.resize(size);
30
31 16 const int base = rows / size;
32 16 const int rem = rows % size;
33
34 int disp = 0;
35
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int rr = 0; rr < size; ++rr) {
36 32 const int rr_rows = base + static_cast<int>(rr < rem);
37 32 counts[rr] = rr_rows * cols;
38 32 displs[rr] = disp;
39 32 disp += counts[rr];
40 }
41 16 }
42
43 16 void BuildGather(int rows, int size, std::vector<int> &counts, std::vector<int> &displs) {
44 16 counts.resize(size);
45 16 displs.resize(size);
46
47 16 const int base = rows / size;
48 16 const int rem = rows % size;
49
50 int disp = 0;
51
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int rr = 0; rr < size; ++rr) {
52 32 const int rr_rows = base + static_cast<int>(rr < rem);
53 32 counts[rr] = rr_rows;
54 32 displs[rr] = disp;
55 32 disp += counts[rr];
56 }
57 16 }
58
59 } // namespace
60
61
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 StripedHorizontalMatrixVectorMPI::StripedHorizontalMatrixVectorMPI(const InType &in) {
62 SetTypeOfTask(GetStaticTypeOfTask());
63
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 GetInput() = in;
64
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 GetOutput() = std::vector<double>{0.0};
65 16 }
66
67
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 bool StripedHorizontalMatrixVectorMPI::ValidationImpl() {
68 const auto &input = GetInput();
69
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (input.size() < 3) {
70 return false;
71 }
72
73 16 const int rows = static_cast<int>(input[0]);
74 16 const int cols = static_cast<int>(input[1]);
75
76
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (rows <= 0 || cols <= 0) {
77 return false;
78 }
79
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (static_cast<int>(input[2]) != cols) {
80 return false;
81 }
82
83 16 const size_t expected = 3 + (static_cast<size_t>(rows) * static_cast<size_t>(cols)) + static_cast<size_t>(cols);
84 16 return input.size() == expected;
85 }
86
87 16 bool StripedHorizontalMatrixVectorMPI::PreProcessingImpl() {
88 16 return true;
89 }
90
91 16 bool StripedHorizontalMatrixVectorMPI::RunImpl() {
92 const auto &input = GetInput();
93 try {
94 16 int rank = 0;
95 16 int size = 0;
96
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
97
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Comm_size(MPI_COMM_WORLD, &size);
98
99 16 const int rows = static_cast<int>(input[0]);
100 16 const int cols = static_cast<int>(input[1]);
101
102 int my_rows = 0;
103 int start_row = 0;
104 16 CalcRows(rows, size, rank, my_rows, start_row);
105
106 16 std::vector<int> sendcounts;
107 16 std::vector<int> sdispls;
108 16 std::vector<int> recvcounts;
109 16 std::vector<int> rdispls;
110
111
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 BuildScatter(rows, cols, size, sendcounts, sdispls);
112
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 BuildGather(rows, size, recvcounts, rdispls);
113
114 const size_t matrix_start = 3;
115
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 const size_t vector_start = matrix_start + (static_cast<size_t>(rows) * static_cast<size_t>(cols));
116
117 16 const double *a_ptr = input.data() + matrix_start;
118 16 const double *x_all_ptr = input.data() + vector_start;
119
120
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 std::vector<double> local_a(static_cast<size_t>(my_rows) * static_cast<size_t>(cols));
121
122
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 std::vector<double> x(static_cast<size_t>(cols), 0.0);
123
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
124 8 std::copy(x_all_ptr, x_all_ptr + cols, x.begin());
125 }
126
127
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
24 MPI_Scatterv((rank == 0) ? a_ptr : nullptr, sendcounts.data(), sdispls.data(), MPI_DOUBLE, local_a.data(),
128 my_rows * cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
129
130
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Bcast(x.data(), cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
131
132
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 std::vector<double> y_local(static_cast<size_t>(my_rows), 0.0);
133
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 16 times.
35 for (int i = 0; i < my_rows; ++i) {
134 double sum = 0.0;
135 19 const size_t row_base = static_cast<size_t>(i) * static_cast<size_t>(cols);
136
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 19 times.
70 for (int j = 0; j < cols; ++j) {
137 51 sum += local_a[row_base + static_cast<size_t>(j)] * x[static_cast<size_t>(j)];
138 }
139 19 y_local[static_cast<size_t>(i)] = sum;
140 }
141
142
2/6
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16 std::vector<double> y(static_cast<size_t>(rows), 0.0);
143
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Allgatherv(y_local.data(), my_rows, MPI_DOUBLE, y.data(), recvcounts.data(), rdispls.data(), MPI_DOUBLE,
144 MPI_COMM_WORLD);
145
146 auto &out = GetOutput();
147 out.clear();
148
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 out.reserve(static_cast<size_t>(rows) + 1);
149
2/6
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16 out.push_back(static_cast<double>(rows));
150
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 out.insert(out.end(), y.begin(), y.end());
151
152 return true;
153 } catch (...) {
154 return false;
155 }
156 }
157
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 bool StripedHorizontalMatrixVectorMPI::PostProcessingImpl() {
159 const auto &output = GetOutput();
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (output.empty()) {
161 return false;
162 }
163
164 16 const int rows = static_cast<int>(GetInput()[0]);
165
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 return static_cast<int>(output[0]) == rows && output.size() == static_cast<size_t>(rows) + 1;
166 }
167
168 } // namespace mityaeva_d_striped_horizontal_matrix_vector
169