GCC Code Coverage Report


Directory: ./
File: tasks/bortsova_a_integrals_rectangle/all/src/ops_all.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 60 60 100.0%
Functions: 6 6 100.0%
Branches: 33 46 71.7%

Line Branch Exec Source
1 #include "bortsova_a_integrals_rectangle/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <cstdint>
8 #include <vector>
9
10 #include "bortsova_a_integrals_rectangle/common/include/common.hpp"
11 #include "util/include/util.hpp"
12
13 namespace bortsova_a_integrals_rectangle {
14
15
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 BortsovaAIntegralsRectangleALL::BortsovaAIntegralsRectangleALL(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 GetInput() = in;
18 20 GetOutput() = 0.0;
19 20 }
20
21
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 bool BortsovaAIntegralsRectangleALL::ValidationImpl() {
22 const auto &input = GetInput();
23
3/6
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
20 return input.func && !input.lower_bounds.empty() && input.lower_bounds.size() == input.upper_bounds.size() &&
24
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 input.num_steps > 0;
25 }
26
27 20 bool BortsovaAIntegralsRectangleALL::PreProcessingImpl() {
28 const auto &input = GetInput();
29 20 func_ = input.func;
30 20 num_steps_ = input.num_steps;
31 20 dims_ = static_cast<int>(input.lower_bounds.size());
32
33 20 midpoints_.resize(dims_);
34 20 volume_ = 1.0;
35 20 total_points_ = 1;
36
37
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 20 times.
54 for (int di = 0; di < dims_; di++) {
38 34 double step = (input.upper_bounds[di] - input.lower_bounds[di]) / static_cast<double>(num_steps_);
39 34 volume_ *= step;
40 34 total_points_ *= num_steps_;
41
42 34 midpoints_[di].resize(num_steps_);
43
2/2
✓ Branch 0 taken 5842 times.
✓ Branch 1 taken 34 times.
5876 for (int si = 0; si < num_steps_; si++) {
44 5842 midpoints_[di][si] = input.lower_bounds[di] + ((si + 0.5) * step);
45 }
46 }
47
48 20 return true;
49 }
50
51 40 double BortsovaAIntegralsRectangleALL::ComputePartialSum(int64_t begin, int64_t end) {
52 40 std::vector<int> indices(dims_, 0);
53
1/4
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
40 std::vector<double> point(dims_);
54
55 int64_t temp = begin;
56
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 40 times.
108 for (int di = dims_ - 1; di >= 0; di--) {
57 68 indices[di] = static_cast<int>(temp % num_steps_);
58 68 temp /= num_steps_;
59 }
60
61 double local_sum = 0.0;
62
2/2
✓ Branch 0 taken 48201 times.
✓ Branch 1 taken 40 times.
48241 for (int64_t pt = begin; pt < end; pt++) {
63
2/2
✓ Branch 0 taken 110201 times.
✓ Branch 1 taken 48201 times.
158402 for (int di = 0; di < dims_; di++) {
64 110201 point[di] = midpoints_[di][indices[di]];
65 }
66 48201 local_sum += func_(point);
67
68
2/2
✓ Branch 0 taken 49341 times.
✓ Branch 1 taken 10 times.
49351 for (int di = dims_ - 1; di >= 0; di--) {
69
2/2
✓ Branch 0 taken 1150 times.
✓ Branch 1 taken 48191 times.
49341 indices[di]++;
70
2/2
✓ Branch 0 taken 1150 times.
✓ Branch 1 taken 48191 times.
49341 if (indices[di] < num_steps_) {
71 break;
72 }
73 1150 indices[di] = 0;
74 }
75 }
76 40 return local_sum;
77 }
78
79 20 bool BortsovaAIntegralsRectangleALL::RunImpl() {
80 20 int rank = 0;
81 20 int size = 1;
82 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
83 20 MPI_Comm_size(MPI_COMM_WORLD, &size);
84
85 20 int64_t chunk = total_points_ / size;
86 20 int64_t remainder = total_points_ % size;
87
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1 times.
20 int64_t mpi_begin = (rank * chunk) + std::min(static_cast<int64_t>(rank), remainder);
88
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1 times.
20 int64_t mpi_end = mpi_begin + chunk + (static_cast<int64_t>(rank) < remainder ? 1 : 0);
89
90 20 int num_threads = ppc::util::GetNumThreads();
91 20 int64_t local_count = mpi_end - mpi_begin;
92 20 std::vector<double> thread_sums(num_threads, 0.0);
93
94 20 #pragma omp parallel num_threads(num_threads) default(none) shared(thread_sums, mpi_begin, local_count, num_threads)
95 {
96 int tid = omp_get_thread_num();
97 int64_t th_chunk = local_count / num_threads;
98 int64_t th_rem = local_count % num_threads;
99 int64_t th_begin = mpi_begin + (tid * th_chunk) + std::min(static_cast<int64_t>(tid), th_rem);
100 int64_t th_end = th_begin + th_chunk + (static_cast<int64_t>(tid) < th_rem ? 1 : 0);
101 thread_sums[tid] = ComputePartialSum(th_begin, th_end);
102 }
103
104 20 double local_sum = 0.0;
105
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int ti = 0; ti < num_threads; ti++) {
106 40 local_sum += thread_sums[ti];
107 }
108
109 20 double global_sum = 0.0;
110
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);
111
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Bcast(&global_sum, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
112
113
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 GetOutput() = global_sum * volume_;
114 20 return true;
115 }
116
117 20 bool BortsovaAIntegralsRectangleALL::PostProcessingImpl() {
118 20 return true;
119 }
120
121 } // namespace bortsova_a_integrals_rectangle
122