GCC Code Coverage Report


Directory: ./
File: tasks/kosolapov_v_calc_mult_integrals_m_rectangles/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 77 83 92.8%
Functions: 10 14 71.4%
Branches: 26 38 68.4%

Line Branch Exec Source
1 #include "kosolapov_v_calc_mult_integrals_m_rectangles/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <future>
8 #include <tuple>
9 #include <vector>
10
11 #include "kosolapov_v_calc_mult_integrals_m_rectangles/common/include/common.hpp"
12 #include "util/include/util.hpp"
13
14 namespace kosolapov_v_calc_mult_integrals_m_rectangles {
15
16 16 KosolapovVCalcMultIntegralsMRectanglesALL::KosolapovVCalcMultIntegralsMRectanglesALL(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 16 GetInput() = InType(in);
19 GetOutput() = 0.0;
20 16 }
21
22 16 bool KosolapovVCalcMultIntegralsMRectanglesALL::ValidationImpl() {
23 16 int steps = std::get<0>(GetInput());
24 16 int func_id = std::get<1>(GetInput());
25
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 return steps > 0 && func_id >= 1 && func_id <= 4;
26 }
27
28 16 bool KosolapovVCalcMultIntegralsMRectanglesALL::PreProcessingImpl() {
29 16 return true;
30 }
31
32 16 bool KosolapovVCalcMultIntegralsMRectanglesALL::RunImpl() {
33 16 int steps = std::get<0>(GetInput());
34 16 int func_id = std::get<1>(GetInput());
35 16 std::tuple<double, double, double, double> temp = GetBounds(func_id);
36 16 double a = std::get<0>(temp);
37 16 double b = std::get<1>(temp);
38 16 double c = std::get<2>(temp);
39 16 double d = std::get<3>(temp);
40 16 double integral = RectanglesIntegral(func_id, steps, a, b, c, d);
41 16 GetOutput() = integral;
42 16 return true;
43 }
44
45 16 bool KosolapovVCalcMultIntegralsMRectanglesALL::PostProcessingImpl() {
46 16 return true;
47 }
48
49 double KosolapovVCalcMultIntegralsMRectanglesALL::Function1(double x, double y) {
50 // f(x,y) = x^2 + y^2
51 2000 return (x * x) + (y * y);
52 }
53 double KosolapovVCalcMultIntegralsMRectanglesALL::Function2(double x, double y) {
54 // f(x,y) = sin(x) * cos(y)
55 2000 return std::sin(x) * std::cos(y);
56 }
57 double KosolapovVCalcMultIntegralsMRectanglesALL::Function3(double x, double y) {
58 // f(x,y) = exp(-(x^2 + y^2))
59 2000 return std::exp(-((x * x) + (y * y)));
60 }
61 double KosolapovVCalcMultIntegralsMRectanglesALL::Function4(double x, double y) {
62 // f(x,y) = sin(x + y)
63 2000 return std::sin(x + y);
64 }
65 8000 double KosolapovVCalcMultIntegralsMRectanglesALL::CallFunction(int func_id, double x, double y) {
66
4/5
✓ Branch 0 taken 2000 times.
✓ Branch 1 taken 2000 times.
✓ Branch 2 taken 2000 times.
✓ Branch 3 taken 2000 times.
✗ Branch 4 not taken.
8000 switch (func_id) {
67 case 1:
68 2000 return Function1(x, y);
69 case 2:
70 2000 return Function2(x, y);
71 case 3:
72 2000 return Function3(x, y);
73 case 4:
74 2000 return Function4(x, y);
75 default:
76 return Function1(x, y);
77 }
78 }
79 16 std::tuple<double, double, double, double> KosolapovVCalcMultIntegralsMRectanglesALL::GetBounds(int func_id) {
80
4/5
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
16 switch (func_id) {
81 4 case 1:
82 return {0.0, 1.0, 0.0, 1.0};
83 4 case 2:
84 return {0.0, kPi, 0.0, kPi / 2.0};
85 4 case 3:
86 return {-1.0, 1.0, -1.0, 1.0};
87 4 case 4:
88 return {0.0, kPi, 0.0, kPi};
89 default:
90 return {0.0, 1.0, 0.0, 1.0};
91 }
92 }
93 16 double KosolapovVCalcMultIntegralsMRectanglesALL::ComputeLocalSum(int func_id, int steps, double a, double c, double hx,
94 double hy, int start_i, int end_i) {
95 16 auto my_rows = static_cast<unsigned int>(end_i - start_i);
96
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (my_rows == 0) {
97 return 0.0;
98 }
99
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 unsigned int num_threads = ppc::util::GetNumThreads();
100 16 num_threads = std::min(num_threads, my_rows);
101 16 unsigned int rows_per_thread = my_rows / num_threads;
102 16 unsigned int thread_remainder = my_rows % num_threads;
103
104 16 std::vector<std::future<double>> futures;
105
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 futures.reserve(num_threads);
106
107 unsigned int offset = 0;
108
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (unsigned int tid = 0; tid < num_threads; ++tid) {
109 unsigned int t_start = offset;
110
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 unsigned int t_end = t_start + rows_per_thread + (tid < thread_remainder ? 1U : 0U);
111 offset = t_end;
112
113
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
64 futures.push_back(std::async(std::launch::async, [=]() -> double {
114 double part_sum = 0.0;
115
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 32 times.
272 for (unsigned int idx = t_start; idx < t_end; ++idx) {
116 240 int i = start_i + static_cast<int>(idx);
117 240 double x = a + ((static_cast<double>(i) + 0.5) * hx);
118
2/2
✓ Branch 0 taken 8000 times.
✓ Branch 1 taken 240 times.
8240 for (int j = 0; j < steps; ++j) {
119 8000 double y = c + ((static_cast<double>(j) + 0.5) * hy);
120 8000 part_sum += CallFunction(func_id, x, y);
121 }
122 }
123 32 return part_sum;
124 }));
125 }
126
127 double local_sum = 0.0;
128
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (auto &fut : futures) {
129
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 local_sum += fut.get();
130 }
131 return local_sum;
132 16 }
133 16 double KosolapovVCalcMultIntegralsMRectanglesALL::RectanglesIntegral(int func_id, int steps, double a, double b,
134 double c, double d) {
135 16 double hx = (b - a) / static_cast<double>(steps);
136 16 double hy = (d - c) / static_cast<double>(steps);
137
138 16 int rank = 0;
139 16 int size = 1;
140 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
141 16 MPI_Comm_size(MPI_COMM_WORLD, &size);
142 16 int rows_per_proc = steps / size;
143 16 int remainder = steps % size;
144
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 int start_i = (rank * rows_per_proc) + std::min(rank, remainder);
145
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 int end_i = start_i + rows_per_proc + (rank < remainder ? 1 : 0);
146 16 double local_sum = ComputeLocalSum(func_id, steps, a, c, hx, hy, start_i, end_i);
147 16 double global_sum = 0.0;
148 16 MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
149 16 MPI_Bcast(&global_sum, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
150 16 MPI_Barrier(MPI_COMM_WORLD);
151 16 return global_sum * hx * hy;
152 }
153
154 } // namespace kosolapov_v_calc_mult_integrals_m_rectangles
155