| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "savva_d_monte_carlo/all/include/ops_all.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | #include <omp.h> | ||
| 5 | |||
| 6 | #include <cstddef> | ||
| 7 | #include <cstdint> | ||
| 8 | #include <random> | ||
| 9 | #include <utility> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | #include "savva_d_monte_carlo/common/include/common.hpp" | ||
| 13 | |||
| 14 | namespace savva_d_monte_carlo { | ||
| 15 | |||
| 16 |
1/2✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 | SavvaDMonteCarloALL::SavvaDMonteCarloALL(const InType &in) { |
| 17 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 18 |
1/2✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 | GetInput() = in; |
| 19 | 34 | GetOutput() = 0.0; | |
| 20 | 34 | } | |
| 21 | |||
| 22 | 34 | bool SavvaDMonteCarloALL::ValidationImpl() { | |
| 23 | const auto &input = GetInput(); | ||
| 24 | |||
| 25 | // Проверка количества точек | ||
| 26 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | if (input.count_points == 0) { |
| 27 | return false; | ||
| 28 | } | ||
| 29 | |||
| 30 | // Проверка наличия функции | ||
| 31 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | if (!input.f) { |
| 32 | return false; | ||
| 33 | } | ||
| 34 | |||
| 35 | // Проверка размерности | ||
| 36 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | if (input.Dimension() == 0) { |
| 37 | return false; | ||
| 38 | } | ||
| 39 | |||
| 40 | // Проверка корректности границ | ||
| 41 |
2/2✓ Branch 0 taken 84 times.
✓ Branch 1 taken 34 times.
|
118 | for (size_t i = 0; i < input.Dimension(); ++i) { |
| 42 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
|
84 | if (input.lower_bounds[i] > input.upper_bounds[i]) { |
| 43 | return false; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | return true; | ||
| 48 | } | ||
| 49 | |||
| 50 | 34 | bool SavvaDMonteCarloALL::PreProcessingImpl() { | |
| 51 | 34 | return true; | |
| 52 | } | ||
| 53 | |||
| 54 | 34 | bool SavvaDMonteCarloALL::RunImpl() { | |
| 55 | 34 | int rank = 0; | |
| 56 | 34 | int size = 1; | |
| 57 | 34 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 58 | 34 | MPI_Comm_size(MPI_COMM_WORLD, &size); | |
| 59 | const auto &input = GetInput(); | ||
| 60 | |||
| 61 | const size_t dim = input.Dimension(); | ||
| 62 | 34 | const uint64_t n_total = input.count_points; | |
| 63 | |||
| 64 | // 1. Распределение нагрузки | ||
| 65 | 34 | uint64_t n_local = n_total / size; | |
| 66 | 34 | uint64_t remainder = n_total % size; | |
| 67 |
1/2✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
|
34 | if (std::cmp_less(rank, remainder)) { |
| 68 | ✗ | n_local++; | |
| 69 | } | ||
| 70 | |||
| 71 | 34 | double local_sum = 0.0; | |
| 72 | 34 | const auto &func = input.f; | |
| 73 | |||
| 74 | // 2. Параллельные вычисления внутри узла через OMP | ||
| 75 | 34 | #pragma omp parallel default(none) shared(input, func, dim, n_local, rank) reduction(+ : local_sum) | |
| 76 | { | ||
| 77 | auto seed = static_cast<uint32_t>((rank * omp_get_num_threads()) + omp_get_thread_num()); | ||
| 78 | std::minstd_rand gen(seed ^ 0x9e3779b9U); | ||
| 79 | |||
| 80 | std::vector<std::uniform_real_distribution<double>> dists(dim); | ||
| 81 | for (size_t i = 0; i < dim; ++i) { | ||
| 82 | dists[i] = std::uniform_real_distribution<double>(input.lower_bounds[i], input.upper_bounds[i]); | ||
| 83 | } | ||
| 84 | |||
| 85 | std::vector<double> point(dim); | ||
| 86 | |||
| 87 | #pragma omp for schedule(static) | ||
| 88 | for (uint64_t i = 0; i < n_local; ++i) { | ||
| 89 | for (size_t j = 0; j < dim; ++j) { | ||
| 90 | point[j] = dists[j](gen); | ||
| 91 | } | ||
| 92 | local_sum += func(point); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | // 3. Глобальная редукция через MPI | ||
| 97 | 34 | double total_sum = 0.0; | |
| 98 | 34 | MPI_Reduce(&local_sum, &total_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); | |
| 99 | |||
| 100 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 17 times.
|
34 | if (rank == 0) { |
| 101 | double vol = input.Volume(); | ||
| 102 | 17 | GetOutput() = (total_sum / static_cast<double>(n_total)) * vol; | |
| 103 | } | ||
| 104 | 34 | MPI_Bcast(&GetOutput(), 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 105 | 34 | return true; | |
| 106 | } | ||
| 107 | |||
| 108 | 34 | bool SavvaDMonteCarloALL::PostProcessingImpl() { | |
| 109 | 34 | return true; | |
| 110 | } | ||
| 111 | |||
| 112 | } // namespace savva_d_monte_carlo | ||
| 113 |