GCC Code Coverage Report


Directory: ./
File: tasks/zaharov_g_seidel_int_met/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 81 84 96.4%
Functions: 5 5 100.0%
Branches: 63 104 60.6%

Line Branch Exec Source
1 #include "zaharov_g_seidel_int_met/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <vector>
9
10 #include "zaharov_g_seidel_int_met/common/include/common.hpp"
11
12 namespace zaharov_g_seidel_int_met {
13
14
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 ZaharovGSeidelIntMetMPI::ZaharovGSeidelIntMetMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GetInput() = in;
17 12 GetOutput() = OutType();
18 12 }
19
20
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 bool ZaharovGSeidelIntMetMPI::ValidationImpl() {
21 const InType &input = GetInput();
22
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (input.size() < 3) {
23 return false;
24 }
25
26
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
12 if (input[0] <= 0 || input[1] <= 0.0 || input[2] <= 0) {
27 return false;
28 }
29
30 12 const int system_size = static_cast<int>(input[0]);
31 12 const int max_iterations = static_cast<int>(input[2]);
32
33
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 return (static_cast<double>(system_size) == input[0]) && (static_cast<double>(max_iterations) == input[2]);
34 }
35
36 12 bool ZaharovGSeidelIntMetMPI::PreProcessingImpl() {
37 try {
38
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Comm_rank(MPI_COMM_WORLD, &rank_);
39
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Comm_size(MPI_COMM_WORLD, &size_);
40
41 12 system_size_ = static_cast<int>(GetInput()[0]);
42 12 epsilon_ = GetInput()[1];
43 12 max_iterations_ = static_cast<int>(GetInput()[2]);
44
45 12 rows_per_process_ = system_size_ / size_;
46 12 remainder_ = system_size_ % size_;
47
48
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 start_row_ = (rank_ * rows_per_process_) + std::min(rank_, remainder_);
49
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 end_row_ = start_row_ + rows_per_process_ + (rank_ < remainder_ ? 1 : 0);
50 12 local_rows_ = end_row_ - start_row_;
51
52
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 local_A_.resize(local_rows_);
53
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 local_b_.resize(local_rows_);
54
55
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 12 times.
232 for (int local_i = 0; local_i < local_rows_; ++local_i) {
56 220 const int global_i = start_row_ + local_i;
57
1/2
✓ Branch 1 taken 220 times.
✗ Branch 2 not taken.
220 local_A_[local_i].resize(system_size_);
58
59
2/2
✓ Branch 0 taken 14000 times.
✓ Branch 1 taken 220 times.
14220 for (int j = 0; j < system_size_; ++j) {
60
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 13780 times.
14000 if (global_i == j) {
61 220 local_A_[local_i][j] = system_size_ + 1.0;
62 } else {
63 13780 local_A_[local_i][j] = 1.0 / (static_cast<double>(std::abs(global_i - j)) + 1.0);
64 }
65 }
66
67 220 local_b_[local_i] = static_cast<double>(global_i + 1);
68 }
69
70
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 x_.resize(system_size_, 0.0);
71
72 12 return true;
73 } catch (...) {
74 return false;
75 }
76 }
77
78 12 bool ZaharovGSeidelIntMetMPI::RunImpl() {
79
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (system_size_ == 0) {
80 return false;
81 }
82
83 12 std::vector<double> prev_x(system_size_, 0.0);
84
1/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
12 std::vector<double> local_x_new(local_rows_, 0.0);
85
86
1/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
12 std::vector<int> recvcounts(size_);
87
1/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
12 std::vector<int> displs(size_);
88
89
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 for (int i = 0; i < size_; ++i) {
90
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 const int i_start = (i * rows_per_process_) + std::min(i, remainder_);
91
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 const int i_end = i_start + rows_per_process_ + (i < remainder_ ? 1 : 0);
92 24 recvcounts[i] = i_end - i_start;
93 24 displs[i] = i_start;
94 }
95
96
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 for (int iter = 0; iter < max_iterations_; ++iter) {
97 std::ranges::copy(x_, prev_x.begin());
98
99
2/2
✓ Branch 0 taken 1540 times.
✓ Branch 1 taken 100 times.
1640 for (int local_i = 0; local_i < local_rows_; ++local_i) {
100 1540 const int global_i = start_row_ + local_i;
101 1540 double sum = local_b_[local_i];
102 const auto &row = local_A_[local_i];
103
104
2/2
✓ Branch 0 taken 43930 times.
✓ Branch 1 taken 1540 times.
45470 for (int j = 0; j < global_i; ++j) {
105 43930 sum -= row[j] * x_[j];
106 }
107
108
2/2
✓ Branch 0 taken 43930 times.
✓ Branch 1 taken 1540 times.
45470 for (int j = global_i + 1; j < system_size_; ++j) {
109 43930 sum -= row[j] * prev_x[j];
110 }
111
112 1540 local_x_new[local_i] = sum / row[global_i];
113 }
114
115
1/2
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
100 MPI_Allgatherv(local_x_new.data(), local_rows_, MPI_DOUBLE, x_.data(), recvcounts.data(), displs.data(), MPI_DOUBLE,
116 MPI_COMM_WORLD);
117
118 100 double local_max_diff = 0.0;
119
2/2
✓ Branch 0 taken 1540 times.
✓ Branch 1 taken 100 times.
1640 for (int local_i = 0; local_i < local_rows_; ++local_i) {
120 1540 const int global_i = start_row_ + local_i;
121 1540 const double diff = std::abs(x_[global_i] - prev_x[global_i]);
122 1540 local_max_diff = std::max(diff, local_max_diff);
123 }
124
125 100 double global_max_diff = 0.0;
126
1/2
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
100 MPI_Allreduce(&local_max_diff, &global_max_diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
127
128
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 12 times.
100 if (global_max_diff < epsilon_) {
129 break;
130 }
131 }
132
133
2/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
24 GetOutput() = std::vector<double>(x_.begin(), x_.end());
134
135 return true;
136 }
137
138 12 bool ZaharovGSeidelIntMetMPI::PostProcessingImpl() {
139 try {
140
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank_ != 0) {
141 return true;
142 }
143
144
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (x_.size() != static_cast<std::size_t>(system_size_)) {
145 return false;
146 }
147
148
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 std::vector<std::vector<double>> matrix_a(system_size_, std::vector<double>(system_size_));
149
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::vector<double> vector_b(system_size_);
150
151
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 6 times.
226 for (int i = 0; i < system_size_; ++i) {
152 220 vector_b[i] = static_cast<double>(i + 1);
153
2/2
✓ Branch 0 taken 14000 times.
✓ Branch 1 taken 220 times.
14220 for (int j = 0; j < system_size_; ++j) {
154
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 13780 times.
14000 if (i == j) {
155 220 matrix_a[i][j] = system_size_ + 1.0;
156 } else {
157 13780 matrix_a[i][j] = 1.0 / (static_cast<double>(std::abs(i - j)) + 1.0);
158 }
159 }
160 }
161
162 double residual_norm = 0.0;
163
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 6 times.
226 for (int i = 0; i < system_size_; ++i) {
164 double sum = 0.0;
165
2/2
✓ Branch 0 taken 14000 times.
✓ Branch 1 taken 220 times.
14220 for (int j = 0; j < system_size_; ++j) {
166 14000 sum += matrix_a[i][j] * x_[j];
167 }
168 220 residual_norm += std::abs(sum - vector_b[i]);
169 }
170
171 6 residual_norm /= static_cast<double>(system_size_);
172
173
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 return residual_norm < (epsilon_ * 1000.0);
174 6 } catch (...) {
175 return false;
176 }
177 }
178
179 } // namespace zaharov_g_seidel_int_met
180