GCC Code Coverage Report


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

Line Branch Exec Source
1 #include "galkin_d_multidim_integrals_rectangles/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <climits>
8 #include <cmath>
9 #include <cstddef>
10 #include <cstdint>
11 #include <limits>
12 #include <tuple>
13 #include <vector>
14
15 #include "galkin_d_multidim_integrals_rectangles/common/include/common.hpp"
16 #include "util/include/util.hpp"
17
18 namespace galkin_d_multidim_integrals_rectangles {
19
20
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
46 GalkinDMultidimIntegralsRectanglesALL::GalkinDMultidimIntegralsRectanglesALL(const InType &in) {
21 SetTypeOfTask(GetStaticTypeOfTask());
22 GetInput() = in;
23 46 GetOutput() = 0.0;
24 46 }
25
26 46 bool GalkinDMultidimIntegralsRectanglesALL::ValidationImpl() {
27 const auto &func = std::get<0>(GetInput());
28 const auto &borders = std::get<1>(GetInput());
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 const int n = std::get<2>(GetInput());
30
31
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (borders.empty()) {
32 return false;
33 }
34
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 46 times.
126 for (const auto &[left_border, right_border] : borders) {
35
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
80 if (!std::isfinite(left_border) || !std::isfinite(right_border)) {
36 return false;
37 }
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (left_border >= right_border) {
39 return false;
40 }
41 }
42
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 46 times.
46 return func && (n > 0) && (GetOutput() == 0.0);
43 }
44
45 46 bool GalkinDMultidimIntegralsRectanglesALL::PreProcessingImpl() {
46 46 GetOutput() = 0.0;
47 46 return true;
48 }
49
50 46 bool GalkinDMultidimIntegralsRectanglesALL::RunImpl() {
51 const InType &input = GetInput();
52 const auto &func = std::get<0>(input);
53 const auto &borders = std::get<1>(input);
54 46 const int n = std::get<2>(input);
55 const std::size_t dim = borders.size();
56
57 46 std::vector<double> h(dim);
58 double cell_v = 1.0;
59
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 46 times.
126 for (std::size_t i = 0; i < dim; ++i) {
60
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 h[i] = (borders[i].second - borders[i].first) / static_cast<double>(n);
61
2/4
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
80 if (!(h[i] > 0.0) || !std::isfinite(h[i])) {
62 return false;
63 }
64 80 cell_v *= h[i];
65 }
66
67 std::size_t total = 1;
68
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 46 times.
126 for (std::size_t i = 0; i < dim; ++i) {
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (total > (std::numeric_limits<std::size_t>::max() / static_cast<std::size_t>(n))) {
70 return false;
71 }
72 80 total *= static_cast<std::size_t>(n);
73 }
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (total > static_cast<std::size_t>(LLONG_MAX)) {
75 return false;
76 }
77 const auto total_i64 = static_cast<std::int64_t>(total);
78
79 46 int rank = 0;
80 46 int world_size = 1;
81
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
46 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
82
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
46 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
83
84 46 const std::int64_t chunk = total_i64 / world_size;
85 46 const std::int64_t rem = total_i64 % world_size;
86 const std::int64_t mpi_begin =
87
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 (static_cast<std::int64_t>(rank) * chunk) + std::min(static_cast<std::int64_t>(rank), rem);
88
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 const std::int64_t mpi_end = mpi_begin + chunk + (static_cast<std::int64_t>(rank) < rem ? 1 : 0);
89
90 46 double local_sum = 0.0;
91
92 46 #pragma omp parallel for reduction(+ : local_sum) schedule(static) \
93
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
46 num_threads(std::max(1, ppc::util::GetNumThreads())) default(none) \
94 shared(borders, h, dim, func, n, mpi_begin, mpi_end)
95 for (std::int64_t linear_idx = mpi_begin; linear_idx < mpi_end; ++linear_idx) {
96 std::vector<double> x(dim);
97 auto tmp = static_cast<std::size_t>(linear_idx);
98 for (std::size_t i = 0; i < dim; ++i) {
99 const std::size_t idx_i = tmp % static_cast<std::size_t>(n);
100 tmp /= static_cast<std::size_t>(n);
101 x[i] = borders[i].first + ((static_cast<double>(idx_i) + 0.5) * h[i]);
102 }
103 local_sum += func(x);
104 }
105
106 46 double global_sum = 0.0;
107
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
46 MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
108
1/2
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
46 MPI_Bcast(&global_sum, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
109
110 46 GetOutput() = global_sum * cell_v;
111 46 return std::isfinite(GetOutput());
112 }
113
114 46 bool GalkinDMultidimIntegralsRectanglesALL::PostProcessingImpl() {
115 46 return std::isfinite(GetOutput());
116 }
117
118 } // namespace galkin_d_multidim_integrals_rectangles
119