GCC Code Coverage Report


Directory: ./
File: tasks/romanova_v_jacobi_method/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 89 89 100.0%
Functions: 6 6 100.0%
Branches: 75 122 61.5%

Line Branch Exec Source
1 #include "romanova_v_jacobi_method/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <tuple>
9 #include <utility>
10 #include <vector>
11
12 #include "romanova_v_jacobi_method/common/include/common.hpp"
13
14 namespace romanova_v_jacobi_method {
15
16
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 RomanovaVJacobiMethodMPI::RomanovaVJacobiMethodMPI(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 GetInput() = in;
19 GetOutput();
20 22 }
21
22 22 bool RomanovaVJacobiMethodMPI::ValidationImpl() {
23 22 bool status = true;
24
25 22 int rank = 0;
26 22 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
27
28
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
29 11 std::vector<OutType> a = std::get<1>(GetInput());
30
31
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 OutType x = std::get<0>(GetInput());
32
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 OutType b = std::get<2>(GetInput());
33
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 status = status && !a.empty();
34
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 11 times.
57 for (size_t i = 0; i < a.size(); i++) {
35
2/4
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
46 status = status && (a.size() == a[i].size());
36 }
37
38
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 status = status && IsDiagonallyDominant(a);
39
40
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 status = status && (a.size() == x.size());
41
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
11 status = status && (a.size() == b.size());
42 11 }
43
44 22 MPI_Bcast(&status, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD);
45 22 return status;
46 }
47
48 22 bool RomanovaVJacobiMethodMPI::PreProcessingImpl() {
49 22 int rank = 0;
50 22 int n = 0;
51
52 22 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
53 22 MPI_Comm_size(MPI_COMM_WORLD, &n);
54
55 22 std::vector<int> send_counts_a(n);
56
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 vector_counts_ = std::vector<int>(n);
57
58
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> displs_scatt_a(n);
59
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 vector_displs_ = std::vector<int>(n);
60
61
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
62 11 n_ = std::get<1>(GetInput()).size();
63 }
64
65
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Bcast(&n_, 1, MPI_INT, 0, MPI_COMM_WORLD);
66
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 x_ = OutType(n_);
67
68
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
69
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 std::vector<OutType> temp_a;
70
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 std::tie(x_, temp_a, b_, eps_, maxIterations_) = GetInput();
71
72
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 11 times.
57 for (const auto &vec : temp_a) {
73
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
46 A_.insert(A_.end(), vec.begin(), vec.end());
74 }
75 11 }
76
77
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Bcast(&eps_, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
78
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Bcast(&maxIterations_, 1, MPI_INT, 0, MPI_COMM_WORLD);
79
80 22 size_t delta = n_ / n;
81 22 size_t extra = n_ % n;
82
83
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 local_n_ = delta + (std::cmp_less(rank, extra) ? 1 : 0);
84
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 st_row_ = (rank * delta) + (std::cmp_less(rank, extra) ? rank : extra);
85
86
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
87
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 send_counts_a = std::vector<int>(n, static_cast<int>(delta * n_));
88
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 vector_counts_ = std::vector<int>(n, static_cast<int>(delta));
89
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 11 times.
17 for (size_t i = 0; i < extra; i++) {
90 6 send_counts_a[i] += static_cast<int>(n_);
91 6 vector_counts_[i]++;
92 }
93
94
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 for (int i = 1; i < n; i++) {
95 11 displs_scatt_a[i] = displs_scatt_a[i - 1] + send_counts_a[i - 1];
96 11 vector_displs_[i] = vector_displs_[i - 1] + vector_counts_[i - 1];
97 }
98 }
99
100
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Bcast(vector_counts_.data(), n, MPI_INT, 0, MPI_COMM_WORLD);
101
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Bcast(vector_displs_.data(), n, MPI_INT, 0, MPI_COMM_WORLD);
102
103
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 OutType local_data = OutType(local_n_ * n_);
104
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 OutType local_b = OutType(local_n_);
105
106
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Bcast(x_.data(), static_cast<int>(n_), MPI_DOUBLE, 0, MPI_COMM_WORLD);
107
108
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
33 MPI_Scatterv(rank == 0 ? A_.data() : nullptr, send_counts_a.data(), displs_scatt_a.data(), MPI_DOUBLE,
109 local_data.data(), static_cast<int>(local_data.size()), MPI_DOUBLE, 0, MPI_COMM_WORLD);
110
111
3/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
33 MPI_Scatterv(rank == 0 ? b_.data() : nullptr, vector_counts_.data(), vector_displs_.data(), MPI_DOUBLE,
112 local_b.data(), static_cast<int>(local_b.size()), MPI_DOUBLE, 0, MPI_COMM_WORLD);
113
114 22 A_ = std::move(local_data);
115 22 b_ = std::move(local_b);
116
117 22 return true;
118 }
119
120 22 bool RomanovaVJacobiMethodMPI::RunImpl() {
121 size_t k = 0;
122 22 OutType prev(x_.size(), 0.0);
123
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 OutType local_x(local_n_);
124 22 double diff = 0.0;
125 22 double glob_diff = eps_;
126
4/4
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 730 times.
✓ Branch 3 taken 2 times.
752 while (glob_diff >= eps_ && k < maxIterations_) {
127 730 diff = 0.0;
128
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 prev = x_;
129
2/2
✓ Branch 0 taken 1422 times.
✓ Branch 1 taken 730 times.
2152 for (size_t i = 0; i < local_n_; i++) {
130 double sum = 0.0;
131
2/2
✓ Branch 0 taken 6786 times.
✓ Branch 1 taken 1422 times.
8208 for (size_t j = 0; j < n_; j++) {
132
2/2
✓ Branch 0 taken 5364 times.
✓ Branch 1 taken 1422 times.
6786 sum += ((st_row_ + i) != j ? A_[(i * n_) + j] * prev[j] : 0);
133 }
134 1422 local_x[i] = (b_[i] - sum) / A_[(i * (n_ + 1)) + st_row_];
135
136 1422 diff = std::max(diff, abs(local_x[i] - prev[st_row_ + i]));
137 }
138
139
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 MPI_Allgatherv(local_x.data(), static_cast<int>(local_n_), MPI_DOUBLE, x_.data(), vector_counts_.data(),
140 vector_displs_.data(), MPI_DOUBLE, MPI_COMM_WORLD);
141
142
1/2
✓ Branch 1 taken 730 times.
✗ Branch 2 not taken.
730 MPI_Allreduce(&diff, &glob_diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
143 730 k++;
144 }
145 22 return true;
146 }
147
148 22 bool RomanovaVJacobiMethodMPI::PostProcessingImpl() {
149 22 GetOutput() = x_;
150 22 return true;
151 }
152
153 11 bool RomanovaVJacobiMethodMPI::IsDiagonallyDominant(const std::vector<OutType> &matrix) {
154
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 11 times.
57 for (size_t i = 0; i < matrix.size(); i++) {
155 double sum = 0.0;
156
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 46 times.
292 for (size_t j = 0; j < matrix[i].size(); j++) {
157
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 46 times.
246 if (i != j) {
158 200 sum += matrix[i][j];
159 }
160 }
161
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (matrix[i][i] <= sum) {
162 return false;
163 }
164 }
165 return true;
166 }
167
168 } // namespace romanova_v_jacobi_method
169