GCC Code Coverage Report


Directory: ./
File: tasks/gonozov_l_global_search/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 92 92 100.0%
Functions: 10 10 100.0%
Branches: 59 88 67.0%

Line Branch Exec Source
1 #include "gonozov_l_global_search/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <functional>
8 #include <limits>
9 #include <tuple>
10 #include <utility>
11 #include <vector>
12
13 #include "gonozov_l_global_search/common/include/common.hpp"
14
15 namespace gonozov_l_global_search {
16
17
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 GonozovLGlobalSearchMPI::GonozovLGlobalSearchMPI(const InType &in) {
18 SetTypeOfTask(GetStaticTypeOfTask());
19 GetInput() = in;
20 8 GetOutput() = 0.0;
21 8 }
22
23 8 bool GonozovLGlobalSearchMPI::ValidationImpl() {
24
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 return (std::get<1>(GetInput()) > 1.0) && (std::get<2>(GetInput()) < std::get<3>(GetInput())) &&
25
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 (std::get<4>(GetInput()) > 0);
26 }
27
28 8 bool GonozovLGlobalSearchMPI::PreProcessingImpl() {
29 8 return true;
30 }
31
32 namespace {
33
34 259 double CountM(int t, double highm, const std::vector<double> &x, const std::function<double(double)> &f) {
35
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 255 times.
259 if (highm == -std::numeric_limits<double>::infinity()) {
36
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
12 return std::abs((f(x[1]) - f(x[0])) / (x[1] - x[0]));
37 }
38
39
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 255 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 255 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 255 times.
765 double highm1 = std::abs((f(x.back()) - f(x[t - 1])) / (x.back() - x[t - 1]));
40
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 255 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 255 times.
765 double highm2 = std::abs((f(x[t]) - f(x.back())) / (x[t] - x.back()));
41
42 double high = std::max(highm, highm1);
43 return std::max(high, highm2);
44 }
45
46 double IntervalCharacteristic(double x1, double x2, double f1, double f2, double m) {
47 11932 double dx = x2 - x1;
48 11932 return (m * dx) + ((f2 - f1) * (f2 - f1) / (m * dx)) - (2.0 * (f1 + f2));
49 }
50
51 8 void InizialzationStartParameters(int proc_rank, std::vector<double> &test_sequence,
52 const std::function<double(double)> &function, double &global_min_x,
53 double &global_min_value, double a, double b) {
54
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (proc_rank == 0) {
55
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 test_sequence = {a, b};
56
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (function(b) < global_min_value) {
57
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 global_min_x = b;
58 2 global_min_value = function(b);
59 }
60 }
61 8 }
62
63 518 void FormNewtestSequence(int proc_rank, std::vector<double> &test_sequence, int *n) {
64
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 259 times.
518 if (proc_rank == 0) {
65 259 *n = static_cast<int>(test_sequence.size());
66 }
67 518 MPI_Bcast(n, 1, MPI_INT, 0, MPI_COMM_WORLD);
68
69
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 259 times.
518 if (proc_rank != 0) {
70 259 test_sequence.resize(*n);
71 }
72
73 518 MPI_Bcast(test_sequence.data(), *n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
74
75 518 std::ranges::sort(test_sequence.begin(), test_sequence.end());
76 518 }
77
78 518 void FormNewParameters(int proc_rank, double &m, double &highm, double r, int t,
79 const std::vector<double> &test_sequence, const std::function<double(double)> &function) {
80
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 259 times.
518 if (proc_rank == 0) {
81 259 highm = CountM(t, highm, test_sequence, function);
82
2/2
✓ Branch 0 taken 258 times.
✓ Branch 1 taken 1 times.
259 m = (highm == 0.0) ? 1.0 : r * highm;
83 }
84 518 MPI_Bcast(&m, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
85 518 }
86
87 518 void CountingNewCoordinateContinueIteration(int proc_rank, int glob, bool &continue_iteration,
88 std::vector<double> &test_sequence, int &t,
89 const std::function<double(double)> &function, double &global_min_x,
90 double &global_min_value, double m, double eps) {
91
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 259 times.
518 if (proc_rank == 0) {
92
1/2
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
259 if (glob <= 0 || std::cmp_greater_equal(glob, test_sequence.size())) {
93 continue_iteration = false;
94 } else {
95 259 t = glob;
96 if (t < 1) {
97 continue_iteration = false;
98 }
99
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
259 double x_new = (0.5 * (test_sequence[t] + test_sequence[t - 1])) -
101
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 259 times.
518 ((function(test_sequence[t]) - function(test_sequence[t - 1])) / (2.0 * m));
102
103 259 double fx = function(x_new);
104
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 243 times.
259 if (fx < global_min_value) {
105 16 global_min_value = fx;
106 16 global_min_x = x_new;
107 }
108 test_sequence.push_back(x_new);
109 }
110
111 259 continue_iteration = std::abs(test_sequence[t] - test_sequence[t - 1]) > eps;
112 }
113
114 518 MPI_Bcast(&continue_iteration, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD);
115 518 }
116 } // namespace
117 8 bool GonozovLGlobalSearchMPI::RunImpl() {
118 8 auto function = std::get<0>(GetInput());
119 8 double r = std::get<1>(GetInput());
120 8 double a = std::get<2>(GetInput());
121 8 double b = std::get<3>(GetInput());
122 8 double eps = std::get<4>(GetInput());
123
124 8 int proc_num = 0;
125 8 int proc_rank = 0;
126
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
127
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Comm_size(MPI_COMM_WORLD, &proc_num);
128
129 8 std::vector<double> test_sequence;
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 double global_min_x = a;
131 8 double global_min_value = function(a);
132
133 8 int t = 1;
134 8 double highm = -std::numeric_limits<double>::infinity();
135
136
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 InizialzationStartParameters(proc_rank, test_sequence, function, global_min_x, global_min_value, a, b);
137
138 8 bool continue_iteration = true;
139
140
2/2
✓ Branch 0 taken 518 times.
✓ Branch 1 taken 8 times.
526 while (continue_iteration) {
141 518 int n = 0;
142
1/2
✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
518 FormNewtestSequence(proc_rank, test_sequence, &n);
143
144 518 double m = 0.0;
145
146
1/2
✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
518 FormNewParameters(proc_rank, m, highm, r, t, test_sequence, function);
147
148 518 int intervals = n - 1;
149 518 int per_proc = intervals / proc_num;
150 518 int rem = intervals % proc_num;
151
152
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 130 times.
518 int l = (proc_rank * per_proc) + std::min(proc_rank, rem);
153
2/2
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 130 times.
518 int r_i = l + per_proc + (proc_rank < rem ? 1 : 0);
154
155 double local_max = -std::numeric_limits<double>::infinity();
156 int local_idx = -1;
157
158
2/2
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 4 times.
518 if (l < r_i) {
159
2/2
✓ Branch 0 taken 11932 times.
✓ Branch 1 taken 514 times.
12446 for (int i = l + 1; i <= r_i; ++i) {
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11932 times.
11932 double highr = IntervalCharacteristic(test_sequence[i - 1], test_sequence[i], function(test_sequence[i - 1]),
161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11932 times.
11932 function(test_sequence[i]), m);
162
2/2
✓ Branch 0 taken 2552 times.
✓ Branch 1 taken 9380 times.
11932 if (highr > local_max) {
163 local_max = highr;
164 local_idx = i;
165 }
166 }
167 }
168
169 struct {
170 double val;
171 int idx;
172 518 } loc{}, glob{};
173 518 loc.val = local_max;
174 518 loc.idx = local_idx;
175
176
1/2
✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
518 MPI_Reduce(&loc, &glob, 1, MPI_DOUBLE_INT, MPI_MAXLOC, 0, MPI_COMM_WORLD);
177
178
1/2
✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
518 CountingNewCoordinateContinueIteration(proc_rank, glob.idx, continue_iteration, test_sequence, t, function,
179 global_min_x, global_min_value, m, eps);
180 }
181
182 // рассылаем результат всем процессам
183
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(&global_min_x, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
184
185
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 GetOutput() = global_min_x;
186
187 8 return true;
188 }
189
190 8 bool GonozovLGlobalSearchMPI::PostProcessingImpl() {
191 8 return true;
192 }
193
194 } // namespace gonozov_l_global_search
195