GCC Code Coverage Report


Directory: ./
File: tasks/nazyrov_a_multidim_integral_rectangle/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 40 40 100.0%
Functions: 5 5 100.0%
Branches: 19 30 63.3%

Line Branch Exec Source
1 #include "nazyrov_a_multidim_integral_rectangle/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <cstdint>
9 #include <vector>
10
11 #include "nazyrov_a_multidim_integral_rectangle/common/include/common.hpp"
12
13 namespace nazyrov_a_multidim_integral_rectangle {
14
15
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 NazyrovAMultidimIntegralRectangleAll::NazyrovAMultidimIntegralRectangleAll(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 GetInput() = in;
18 20 GetOutput() = 0.0;
19 20 }
20
21 20 bool NazyrovAMultidimIntegralRectangleAll::ValidationImpl() {
22 20 int rank = 0;
23 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
24
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank != 0) {
25 return true;
26 }
27 const auto &func = std::get<0>(GetInput());
28 const auto &bounds = std::get<1>(GetInput());
29
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 const int n = std::get<2>(GetInput());
30
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 return func && n > 0 && !bounds.empty() && std::ranges::all_of(bounds, [](const auto &bd) {
31
3/6
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
21 return std::isfinite(bd.first) && std::isfinite(bd.second) && bd.first < bd.second;
32 });
33 }
34
35 20 bool NazyrovAMultidimIntegralRectangleAll::PreProcessingImpl() {
36 20 return true;
37 }
38
39 20 bool NazyrovAMultidimIntegralRectangleAll::RunImpl() {
40 20 int rank = 0;
41 20 int world_size = 1;
42 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
43 20 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
44
45 const auto &func = std::get<0>(GetInput());
46 const auto &bounds = std::get<1>(GetInput());
47 20 const int n = std::get<2>(GetInput());
48
49 20 const int dim = static_cast<int>(bounds.size());
50
51 20 std::vector<double> h(static_cast<std::size_t>(dim));
52 double cell_vol = 1.0;
53
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 20 times.
62 for (int i = 0; i < dim; ++i) {
54 42 h[i] = (bounds[i].second - bounds[i].first) / n;
55 42 cell_vol *= h[i];
56 }
57
58 std::int64_t total = 1;
59
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 20 times.
62 for (int i = 0; i < dim; ++i) {
60 42 total *= n;
61 }
62
63 20 const auto rk = static_cast<std::int64_t>(rank);
64 20 const auto ws = static_cast<std::int64_t>(world_size);
65 20 const std::int64_t cells_per_rank = total / ws;
66 20 const std::int64_t extra = total % ws;
67
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 const std::int64_t begin = (rk * cells_per_rank) + std::min(rk, extra);
68
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 const std::int64_t end = begin + cells_per_rank + (rk < extra ? 1LL : 0LL);
69
70 20 double local_sum = 0.0;
71
72 20 #pragma omp parallel default(none) shared(func, bounds, h, n, dim, begin, end, local_sum)
73 {
74 std::vector<double> point(static_cast<std::size_t>(dim));
75 double thread_sum = 0.0;
76
77 #pragma omp for schedule(static)
78 for (std::int64_t cell = begin; cell < end; ++cell) {
79 std::int64_t tmp = cell;
80 for (int i = dim - 1; i >= 0; --i) {
81 const int ki = static_cast<int>(tmp % n);
82 tmp /= n;
83 const double coordinate = bounds[i].first + ((ki + 0.5) * h[i]);
84 point[i] = coordinate;
85 }
86 thread_sum += func(point);
87 }
88
89 #pragma omp atomic
90 local_sum += thread_sum;
91 }
92
93 20 double global_sum = 0.0;
94
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
95
96
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
97 10 GetOutput() = global_sum * cell_vol;
98 }
99
100 20 return true;
101 }
102
103 20 bool NazyrovAMultidimIntegralRectangleAll::PostProcessingImpl() {
104 20 return true;
105 }
106
107 } // namespace nazyrov_a_multidim_integral_rectangle
108