GCC Code Coverage Report


Directory: ./
File: tasks/kiselev_i_trapezoidal_method_for_multidimensional_integrals/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 66 66 100.0%
Functions: 8 8 100.0%
Branches: 29 39 74.4%

Line Branch Exec Source
1 #include "kiselev_i_trapezoidal_method_for_multidimensional_integrals/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <vector>
8
9 #ifdef _OPENMP
10 # include <omp.h>
11 #endif
12
13 #include "kiselev_i_trapezoidal_method_for_multidimensional_integrals/common/include/common.hpp"
14
15 namespace kiselev_i_trapezoidal_method_for_multidimensional_integrals {
16
17 namespace {
18
19 2267789 double EvaluateFunction(int type_function, double x, double y) {
20
5/5
✓ Branch 0 taken 830410 times.
✓ Branch 1 taken 201202 times.
✓ Branch 2 taken 291803 times.
✓ Branch 3 taken 402966 times.
✓ Branch 4 taken 541408 times.
2267789 switch (type_function) {
21 830410 case 0:
22 830410 return (x * x) + (y * y);
23
24 201202 case 1:
25 201202 return std::sin(x) * std::cos(y);
26
27 291803 case 2:
28 291803 return std::sin(x) + std::cos(y);
29
30 402966 case 3:
31 402966 return std::exp(x + y);
32
33 541408 default:
34 541408 return x + y;
35 }
36 }
37
38 58 double ComputeLocalIntegral(const InType &in, const std::vector<int> &steps, int begin, int end) {
39 58 const int nx = steps[0];
40 58 const int ny = steps[1];
41
42 58 const double hx = (in.right_bounds[0] - in.left_bounds[0]) / static_cast<double>(nx);
43 58 const double hy = (in.right_bounds[1] - in.left_bounds[1]) / static_cast<double>(ny);
44
45 double local_sum = 0.0;
46
47 58 #pragma omp parallel for reduction(+ : local_sum) schedule(static) default(none) \
48 shared(in, steps, begin, end, hx, hy, nx, ny)
49 for (int i = begin; i < end; ++i) {
50 for (int j = 0; j <= ny; ++j) {
51 const double x = in.left_bounds[0] + (static_cast<double>(i) * hx);
52 const double y = in.left_bounds[1] + (static_cast<double>(j) * hy);
53 const double wx = ((i == 0) || (i == nx)) ? 0.5 : 1.0;
54 const double wy = ((j == 0) || (j == ny)) ? 0.5 : 1.0;
55
56 local_sum += wx * wy * EvaluateFunction(in.type_function, x, y);
57 }
58 }
59
60 58 return local_sum * hx * hy;
61 }
62
63 } // namespace
64
65
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 KiselevITestTaskALL::KiselevITestTaskALL(const InType &in) {
66 SetTypeOfTask(GetStaticTypeOfTask());
67
68
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 GetInput() = in;
69
70 36 GetOutput() = 0.0;
71 36 }
72
73 36 bool KiselevITestTaskALL::ValidationImpl() {
74 36 return true;
75 }
76
77 36 bool KiselevITestTaskALL::PreProcessingImpl() {
78 36 GetOutput() = 0.0;
79
80 36 return true;
81 }
82
83 58 double KiselevITestTaskALL::ComputeIntegral(const std::vector<int> &steps) {
84 const auto &in = GetInput();
85
86 58 int mpi_initialized = 0;
87
88 58 MPI_Initialized(&mpi_initialized);
89
90 58 int rank = 0;
91 58 int size = 1;
92
93
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 if (mpi_initialized != 0) {
94 58 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
95 58 MPI_Comm_size(MPI_COMM_WORLD, &size);
96 }
97
98 58 const int total_rows = steps[0] + 1;
99 58 const int rows_per_proc = total_rows / size;
100 58 const int remainder = total_rows % size;
101
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 29 times.
58 const int begin = (rank * rows_per_proc) + std::min(rank, remainder);
102
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 29 times.
58 const int local_rows = rows_per_proc + ((rank < remainder) ? 1 : 0);
103 58 const int end = begin + local_rows;
104
105 58 double local_result = ComputeLocalIntegral(in, steps, begin, end);
106 58 double global_result = local_result;
107
108
2/4
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
58 if ((mpi_initialized != 0) && (size > 1)) {
109 58 MPI_Allreduce(&local_result, &global_result, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
110 }
111
112 58 return global_result;
113 }
114
115 36 bool KiselevITestTaskALL::RunImpl() {
116 36 std::vector<int> steps = GetInput().step_n_size;
117
118 const auto &in = GetInput();
119
120
6/6
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 30 times.
36 if ((in.left_bounds.size() != 2) || (in.right_bounds.size() != 2) || (in.step_n_size.size() != 2)) {
121 6 GetOutput() = 0.0;
122
123 6 return true;
124 }
125
126 30 const double epsilon = in.epsilon;
127
128
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 28 times.
30 if (epsilon <= 0.0) {
129
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 GetOutput() = ComputeIntegral(steps);
130
131 2 return true;
132 }
133
134
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 double prev = ComputeIntegral(steps);
135
136 double current = prev;
137
138 constexpr int kMaxIter = 1;
139
140
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 for (int iter = 0; iter < kMaxIter; ++iter) {
141
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
84 for (auto &s : steps) {
142 56 s *= 2;
143 }
144
145
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 current = ComputeIntegral(steps);
146
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (std::abs(current - prev) < epsilon) {
148 break;
149 }
150
151 prev = current;
152 }
153
154 28 GetOutput() = current;
155
156 28 return true;
157 }
158
159 36 bool KiselevITestTaskALL::PostProcessingImpl() {
160 36 return true;
161 }
162
163 } // namespace kiselev_i_trapezoidal_method_for_multidimensional_integrals
164