GCC Code Coverage Report


Directory: ./
File: tasks/samoylenko_i_integral_trapezoid/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 70 70 100.0%
Functions: 7 7 100.0%
Branches: 58 85 68.2%

Line Branch Exec Source
1 #include "samoylenko_i_integral_trapezoid/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <cstddef>
7 #include <cstdint>
8 #include <functional>
9 #include <vector>
10
11 #include "samoylenko_i_integral_trapezoid/common/include/common.hpp"
12 #include "util/include/util.hpp"
13
14 namespace samoylenko_i_integral_trapezoid {
15
16 namespace {
17 10 std::function<double(const std::vector<double> &)> GetIntegrationFunction(int64_t choice) {
18
4/5
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
10 switch (choice) {
19 case 0:
20 return [](const std::vector<double> &values) {
21 double sum = 0.0;
22
2/2
✓ Branch 0 taken 21403 times.
✓ Branch 1 taken 11202 times.
32605 for (double val : values) {
23 21403 sum += val;
24 }
25 return sum;
26 };
27 case 1:
28 return [](const std::vector<double> &values) {
29 double mult = 1.0;
30
2/2
✓ Branch 0 taken 20402 times.
✓ Branch 1 taken 10201 times.
30603 for (double val : values) {
31 20402 mult *= val;
32 }
33 return mult;
34 };
35 case 2:
36 return [](const std::vector<double> &values) {
37 double sum = 0.0;
38
2/2
✓ Branch 0 taken 397953 times.
✓ Branch 1 taken 132651 times.
530604 for (double val : values) {
39 397953 sum += val * val;
40 }
41 return sum;
42 };
43 case 3:
44 return [](const std::vector<double> &values) {
45 double sum = 0.0;
46
2/2
✓ Branch 0 taken 1001 times.
✓ Branch 1 taken 1001 times.
2002 for (double val : values) {
47 1001 sum += val;
48 }
49 1001 return std::sin(sum);
50 };
51 default:
52 return [](const std::vector<double> &) { return 0.0; };
53 }
54 }
55
56 20 double GetLocalSum(int64_t start, int64_t end, int dimensions, const std::vector<int64_t> &dim_sizes,
57 const std::vector<double> &h, const auto &in, auto &integral_function) {
58 20 std::vector<double> current_point(dimensions);
59
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> coords(dimensions);
60 double local_sum = 0.0;
61
62 int64_t rem_index = start;
63
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 20 times.
56 for (int dim = 0; dim < dimensions; dim++) {
64 36 coords[dim] = static_cast<int>(rem_index % dim_sizes[dim]);
65 36 rem_index /= dim_sizes[dim];
66 }
67
68
2/2
✓ Branch 0 taken 155055 times.
✓ Branch 1 taken 20 times.
155075 for (int64_t pnt = start; pnt < end; pnt++) {
69 int weight = 1;
70
71
2/2
✓ Branch 0 taken 440759 times.
✓ Branch 1 taken 155055 times.
595814 for (int dim = 0; dim < dimensions; dim++) {
72
2/2
✓ Branch 0 taken 432550 times.
✓ Branch 1 taken 8209 times.
440759 current_point[dim] = in.a[dim] + (coords[dim] * h[dim]);
73
74
4/4
✓ Branch 0 taken 432550 times.
✓ Branch 1 taken 8209 times.
✓ Branch 2 taken 424341 times.
✓ Branch 3 taken 8209 times.
440759 if (coords[dim] > 0 && coords[dim] < in.n[dim]) {
75 424341 weight *= 2;
76 }
77 }
78
79 155055 local_sum += integral_function(current_point) * weight;
80
81
2/2
✓ Branch 0 taken 157909 times.
✓ Branch 1 taken 5 times.
157914 for (int dim = 0; dim < dimensions; dim++) {
82
2/2
✓ Branch 0 taken 2859 times.
✓ Branch 1 taken 155050 times.
157909 coords[dim]++;
83
2/2
✓ Branch 0 taken 2859 times.
✓ Branch 1 taken 155050 times.
157909 if (coords[dim] < dim_sizes[dim]) {
84 break;
85 }
86 2859 coords[dim] = 0;
87 }
88 }
89
90 20 return local_sum;
91 }
92 } // namespace
93
94
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 SamoylenkoIIntegralTrapezoidALL::SamoylenkoIIntegralTrapezoidALL(const InType &in) {
95 SetTypeOfTask(GetStaticTypeOfTask());
96
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 GetInput() = in;
97 10 GetOutput() = 0.0;
98 10 }
99
100
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 bool SamoylenkoIIntegralTrapezoidALL::ValidationImpl() {
101 const auto &in = GetInput();
102
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
10 if (in.a.empty() || in.a.size() != in.b.size() || in.a.size() != in.n.size()) {
103 return false;
104 }
105
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
28 for (size_t i = 0; i < in.a.size(); ++i) {
106
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
18 if (in.n[i] <= 0 || in.a[i] >= in.b[i]) {
107 return false;
108 }
109 }
110 10 return in.function_choice >= 0 && in.function_choice <= 3;
111 }
112
113 10 bool SamoylenkoIIntegralTrapezoidALL::PreProcessingImpl() {
114 10 GetOutput() = 0.0;
115 10 return true;
116 }
117
118
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 bool SamoylenkoIIntegralTrapezoidALL::RunImpl() {
119 const auto &in = GetInput();
120 10 const int dimensions = static_cast<int>(in.a.size());
121 10 auto integral_function = GetIntegrationFunction(in.function_choice);
122
123
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<double> h(dimensions);
124
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
28 for (int i = 0; i < dimensions; i++) {
125 18 h[i] = (in.b[i] - in.a[i]) / in.n[i];
126 }
127
128
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int64_t> dim_sizes(dimensions);
129 int64_t points = 1;
130
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
28 for (int i = 0; i < dimensions; i++) {
131 18 dim_sizes[i] = in.n[i] + 1;
132 18 points *= dim_sizes[i];
133 }
134
135 10 int rank = 0;
136 10 int size = 0;
137
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
138
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Comm_size(MPI_COMM_WORLD, &size);
139
140 10 int64_t start = (points * rank) / size;
141 10 int64_t end = (points * (rank + 1)) / size;
142
143
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 const int num_threads = ppc::util::GetNumThreads();
144
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<double> local_sums(num_threads, 0.0);
145
146 10 #pragma omp parallel for num_threads(num_threads) default(none) \
147 shared(num_threads, start, end, dimensions, dim_sizes, h, in, integral_function, local_sums)
148 for (int thr = 0; thr < num_threads; thr++) {
149 int64_t local_start = start + (((end - start) * thr) / num_threads);
150 int64_t local_end = start + (((end - start) * (thr + 1)) / num_threads);
151 local_sums[thr] = GetLocalSum(local_start, local_end, dimensions, dim_sizes, h, in, integral_function);
152 }
153
154 10 double sum = 0.0;
155
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int thr = 0; thr < num_threads; thr++) {
156 20 sum += local_sums[thr];
157 }
158
159 10 double total_sum = 0.0;
160
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Allreduce(&sum, &total_sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
161
162 double h_mult = 1.0;
163
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
28 for (int i = 0; i < dimensions; i++) {
164 18 h_mult *= h[i];
165 }
166
167
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 GetOutput() = total_sum * (h_mult / std::pow(2.0, dimensions));
168
169 10 return true;
170 }
171
172 10 bool SamoylenkoIIntegralTrapezoidALL::PostProcessingImpl() {
173 10 return true;
174 }
175
176 } // namespace samoylenko_i_integral_trapezoid
177