GCC Code Coverage Report


Directory: ./
File: tasks/dergynov_s_integrals_multistep_rectangle/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 45 45 100.0%
Functions: 5 5 100.0%
Branches: 27 48 56.2%

Line Branch Exec Source
1 #include "dergynov_s_integrals_multistep_rectangle/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <cmath>
8 #include <cstddef>
9 #include <cstdint>
10 #include <functional>
11 #include <utility>
12 #include <vector>
13
14 #include "dergynov_s_integrals_multistep_rectangle/common/include/common.hpp"
15 #include "util/include/util.hpp"
16
17 namespace dergynov_s_integrals_multistep_rectangle {
18
19
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 DergynovSIntegralsMultistepRectangleALL::DergynovSIntegralsMultistepRectangleALL(const InType &in) {
20 SetTypeOfTask(GetStaticTypeOfTask());
21 GetInput() = in;
22 38 GetOutput() = 0.0;
23 38 }
24
25
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 bool DergynovSIntegralsMultistepRectangleALL::ValidationImpl() {
26 const auto &[func, borders, n] = GetInput();
27
28
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (borders.empty()) {
29 return false;
30 }
31
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 38 times.
104 for (const auto &[left, right] : borders) {
32
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 66 times.
66 if (!std::isfinite(left) || !std::isfinite(right)) {
33 return false;
34 }
35
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (left >= right) {
36 return false;
37 }
38 }
39
40
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
38 return func && (n > 0);
41 }
42
43 38 bool DergynovSIntegralsMultistepRectangleALL::PreProcessingImpl() {
44 38 GetOutput() = 0.0;
45 38 return true;
46 }
47
48 namespace {
49
50 void FillPoint(size_t linear_idx, int n, int dim, const std::vector<std::pair<double, double>> &borders,
51 const std::vector<double> &h, std::vector<double> &point) {
52 size_t tmp = linear_idx;
53 for (int axis = dim - 1; axis >= 0; --axis) {
54 int idx_val = static_cast<int>(tmp % static_cast<size_t>(n));
55 tmp /= static_cast<size_t>(n);
56 point[axis] = borders[axis].first + ((static_cast<double>(idx_val) + 0.5) * h[axis]);
57 }
58 }
59
60 } // namespace
61
62 38 bool DergynovSIntegralsMultistepRectangleALL::RunImpl() {
63 const auto &input = GetInput();
64 const auto &func = std::get<0>(input);
65 const auto &borders = std::get<1>(input);
66 38 const int n = std::get<2>(input);
67 38 const int dim = static_cast<int>(borders.size());
68
69 38 std::vector<double> h(dim);
70 double cell_volume = 1.0;
71
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 38 times.
104 for (int i = 0; i < dim; ++i) {
72 66 h[i] = (borders[i].second - borders[i].first) / static_cast<double>(n);
73 66 cell_volume *= h[i];
74 }
75
76 int64_t total_points = 1;
77
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 38 times.
104 for (int i = 0; i < dim; ++i) {
78 66 total_points *= static_cast<int64_t>(n);
79 }
80
81 38 int rank = 0;
82 38 int world_size = 1;
83
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 const bool is_mpi = ppc::util::IsUnderMpirun();
84
85
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 if (is_mpi) {
86
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
87
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
88 }
89
90 38 const int64_t chunk = total_points / world_size;
91 38 const int64_t rem = total_points % world_size;
92
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 const int64_t start = (rank * chunk) + std::min(rank, static_cast<int>(rem));
93
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 const int64_t end = start + chunk + (rank < rem ? 1 : 0);
94
95 38 double local_sum = 0.0;
96 38 bool error_flag = false;
97
98
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 const auto func_copy = func;
99
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 const auto borders_copy = borders;
100
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 const auto h_copy = h;
101 const int n_copy = n;
102 const int dim_copy = dim;
103 const int64_t start_copy = start;
104 const int64_t end_copy = end;
105
106 38 #pragma omp parallel for schedule(static) reduction(+ : local_sum) shared(error_flag) default(none) \
107 firstprivate(func_copy, borders_copy, h_copy, n_copy, dim_copy, start_copy, end_copy)
108 for (int64_t linear_idx = start_copy; linear_idx < end_copy; ++linear_idx) {
109 if (error_flag) {
110 continue;
111 }
112
113 std::vector<double> point(dim_copy);
114 FillPoint(static_cast<size_t>(linear_idx), n_copy, dim_copy, borders_copy, h_copy, point);
115
116 double f_val = func_copy(point);
117 if (!std::isfinite(f_val)) {
118 #pragma omp atomic write
119 error_flag = true;
120 continue;
121 }
122 local_sum += f_val;
123 }
124
125
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 if (error_flag) {
126 return false;
127 }
128
129 38 double global_sum = local_sum;
130
2/4
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
38 if (is_mpi && world_size > 1) {
131
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 MPI_Allreduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
132 }
133
134 38 GetOutput() = global_sum * cell_volume;
135 38 return std::isfinite(GetOutput());
136 }
137
138 38 bool DergynovSIntegralsMultistepRectangleALL::PostProcessingImpl() {
139 38 return std::isfinite(GetOutput());
140 }
141
142 } // namespace dergynov_s_integrals_multistep_rectangle
143