| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "telnov_a_integral_rectangle/stl/include/ops_stl.hpp" | ||
| 2 | |||
| 3 | #include <algorithm> | ||
| 4 | #include <cmath> | ||
| 5 | #include <cstdint> | ||
| 6 | #include <thread> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "telnov_a_integral_rectangle/common/include/common.hpp" | ||
| 10 | #include "util/include/util.hpp" | ||
| 11 | |||
| 12 | namespace telnov_a_integral_rectangle { | ||
| 13 | |||
| 14 | 64 | TelnovAIntegralRectangleSTL::TelnovAIntegralRectangleSTL(const InType &in) { | |
| 15 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 16 | GetInput() = in; | ||
| 17 | GetOutput() = 0.0; | ||
| 18 | 64 | } | |
| 19 | |||
| 20 | 64 | bool TelnovAIntegralRectangleSTL::ValidationImpl() { | |
| 21 |
2/4✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
|
64 | return GetInput().first > 0 && GetInput().second > 0; |
| 22 | } | ||
| 23 | |||
| 24 | 64 | bool TelnovAIntegralRectangleSTL::PreProcessingImpl() { | |
| 25 | 64 | GetOutput() = 0.0; | |
| 26 | 64 | return true; | |
| 27 | } | ||
| 28 | |||
| 29 | 64 | bool TelnovAIntegralRectangleSTL::RunImpl() { | |
| 30 | 64 | const int n = GetInput().first; | |
| 31 | 64 | const int d = GetInput().second; | |
| 32 | |||
| 33 | const double a = 0.0; | ||
| 34 | const double b = 1.0; | ||
| 35 | 64 | const double h = (b - a) / static_cast<double>(n); | |
| 36 | |||
| 37 | 64 | const auto total_points = static_cast<int64_t>(std::pow(n, d)); | |
| 38 | |||
| 39 | 64 | int thread_count = ppc::util::GetNumThreads(); | |
| 40 |
4/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 22 times.
|
70 | thread_count = std::max(1, std::min(thread_count, static_cast<int>(total_points))); |
| 41 | |||
| 42 | 64 | std::vector<std::thread> threads(thread_count); | |
| 43 |
1/2✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
|
64 | std::vector<double> partial_sums(thread_count, 0.0); |
| 44 | |||
| 45 | 64 | const int64_t block = total_points / thread_count; | |
| 46 | 64 | const int64_t remainder = total_points % thread_count; | |
| 47 | |||
| 48 | 64 | auto calculate_part = [n, d, a, h](int64_t begin, int64_t end) { | |
| 49 | double local_sum = 0.0; | ||
| 50 | |||
| 51 |
2/2✓ Branch 0 taken 301352 times.
✓ Branch 1 taken 148 times.
|
301500 | for (int64_t idx = begin; idx < end; ++idx) { |
| 52 | int64_t current = idx; | ||
| 53 | double f_value = 0.0; | ||
| 54 | |||
| 55 |
2/2✓ Branch 0 taken 1423928 times.
✓ Branch 1 taken 301352 times.
|
1725280 | for (int dim = 0; dim < d; ++dim) { |
| 56 | 1423928 | const int coord_index = static_cast<int>(current % n); | |
| 57 | 1423928 | current /= n; | |
| 58 | |||
| 59 | 1423928 | const double x = a + ((static_cast<double>(coord_index) + 0.5) * h); | |
| 60 | 1423928 | f_value += x; | |
| 61 | } | ||
| 62 | |||
| 63 | 301352 | local_sum += f_value; | |
| 64 | } | ||
| 65 | |||
| 66 | return local_sum; | ||
| 67 | 64 | }; | |
| 68 | |||
| 69 | int64_t begin = 0; | ||
| 70 |
2/2✓ Branch 0 taken 148 times.
✓ Branch 1 taken 64 times.
|
212 | for (int i = 0; i < thread_count; ++i) { |
| 71 |
2/2✓ Branch 0 taken 118 times.
✓ Branch 1 taken 30 times.
|
148 | const int64_t current_block = block + (i < remainder ? 1 : 0); |
| 72 | 148 | const int64_t end = begin + current_block; | |
| 73 | |||
| 74 |
2/6✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 148 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
296 | threads[i] = std::thread([&, i, begin, end]() { partial_sums[i] = calculate_part(begin, end); }); |
| 75 | |||
| 76 | begin = end; | ||
| 77 | } | ||
| 78 | |||
| 79 |
2/2✓ Branch 0 taken 148 times.
✓ Branch 1 taken 64 times.
|
212 | for (auto &thread : threads) { |
| 80 |
1/2✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
|
148 | thread.join(); |
| 81 | } | ||
| 82 | |||
| 83 | double result = 0.0; | ||
| 84 |
2/2✓ Branch 0 taken 148 times.
✓ Branch 1 taken 64 times.
|
212 | for (const auto &value : partial_sums) { |
| 85 | 148 | result += value; | |
| 86 | } | ||
| 87 | |||
| 88 |
1/2✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
|
64 | GetOutput() = result * std::pow(h, d); |
| 89 | 64 | return true; | |
| 90 | 64 | } | |
| 91 | |||
| 92 | 64 | bool TelnovAIntegralRectangleSTL::PostProcessingImpl() { | |
| 93 | 64 | return true; | |
| 94 | } | ||
| 95 | |||
| 96 | } // namespace telnov_a_integral_rectangle | ||
| 97 |