| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "dorofeev_i_monte_carlo_integration/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cstddef> | ||
| 7 | #include <random> | ||
| 8 | #include <ranges> | ||
| 9 | #include <utility> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | #include "dorofeev_i_monte_carlo_integration/common/include/common.hpp" | ||
| 13 | |||
| 14 | namespace dorofeev_i_monte_carlo_integration_processes { | ||
| 15 | |||
| 16 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | DorofeevIMonteCarloIntegrationMPI::DorofeevIMonteCarloIntegrationMPI(const InType &in) { |
| 17 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 18 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | GetInput() = in; |
| 19 | 16 | GetOutput() = 0; | |
| 20 | 16 | } | |
| 21 | |||
| 22 | 16 | bool DorofeevIMonteCarloIntegrationMPI::ValidationImpl() { | |
| 23 | 16 | int rank = 0; | |
| 24 | 16 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 25 | |||
| 26 | 16 | bool valid = true; | |
| 27 | |||
| 28 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 29 | const auto &in = GetInput(); | ||
| 30 | 8 | valid = | |
| 31 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
|
16 | in.func && !in.a.empty() && in.a.size() == in.b.size() && |
| 32 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
16 | std::ranges::all_of(std::views::iota(size_t{0}, in.a.size()), [&](size_t i) { return in.b[i] > in.a[i]; }) && |
| 33 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | in.samples > 0; |
| 34 | } | ||
| 35 | |||
| 36 | 16 | MPI_Bcast(&valid, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD); | |
| 37 | 16 | return valid; | |
| 38 | } | ||
| 39 | |||
| 40 | 16 | bool DorofeevIMonteCarloIntegrationMPI::PreProcessingImpl() { | |
| 41 | 16 | GetOutput() = 0.0; | |
| 42 | 16 | return true; | |
| 43 | } | ||
| 44 | |||
| 45 | 16 | bool DorofeevIMonteCarloIntegrationMPI::RunImpl() { | |
| 46 | 16 | int rank = 0; | |
| 47 | 16 | int size = 0; | |
| 48 | 16 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 49 | 16 | MPI_Comm_size(MPI_COMM_WORLD, &size); | |
| 50 | |||
| 51 | // BROADCAST INPUT | ||
| 52 | InType in; | ||
| 53 | |||
| 54 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 55 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | in = GetInput(); |
| 56 | } | ||
| 57 | |||
| 58 | // BROADCAST DIMS | ||
| 59 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | int dims = static_cast<int>(rank == 0 ? in.a.size() : 0); |
| 60 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(&dims, 1, MPI_INT, 0, MPI_COMM_WORLD); |
| 61 | |||
| 62 | // resize on other ranks | ||
| 63 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank != 0) { |
| 64 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | in.a.resize(dims); |
| 65 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | in.b.resize(dims); |
| 66 | } | ||
| 67 | |||
| 68 | // BROADCAST BOUNDS | ||
| 69 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(in.a.data(), dims, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 70 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(in.b.data(), dims, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 71 | |||
| 72 | // BROADCAST SAMPLES | ||
| 73 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(&in.samples, 1, MPI_INT, 0, MPI_COMM_WORLD); |
| 74 | |||
| 75 | // BROADCAST FUNC ID | ||
| 76 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | int func_id = (rank == 0 ? 1 : 0); |
| 77 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(&func_id, 1, MPI_INT, 0, MPI_COMM_WORLD); |
| 78 | |||
| 79 | // restore the function | ||
| 80 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | switch (func_id) { |
| 81 | 16 | case 1: | |
| 82 | 16 | in.func = [](const std::vector<double> &x) { return x[0] * x[0]; }; | |
| 83 | 16 | break; | |
| 84 | default: | ||
| 85 | in.func = nullptr; | ||
| 86 | } | ||
| 87 | |||
| 88 | // CALCULATIONS | ||
| 89 | 16 | int n_total = in.samples; | |
| 90 | 16 | int n_local = n_total / size; | |
| 91 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == size - 1) { |
| 92 | 8 | n_local += n_total % size; | |
| 93 | } | ||
| 94 | |||
| 95 | 16 | std::vector<std::uniform_real_distribution<double>> dist; | |
| 96 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | dist.reserve(dims); |
| 97 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | for (int dim = 0; std::cmp_less(dim, dims); dim++) { |
| 98 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | dist.emplace_back(in.a[dim], in.b[dim]); |
| 99 | } | ||
| 100 | |||
| 101 | 16 | std::mt19937 gen(rank + 777); | |
| 102 | 16 | double local_sum = 0.0; | |
| 103 | |||
| 104 | 16 | std::vector<double> x; | |
| 105 |
1/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
16 | x.assign(static_cast<size_t>(dims), 0.0); |
| 106 | |||
| 107 |
2/2✓ Branch 0 taken 159001 times.
✓ Branch 1 taken 16 times.
|
159017 | for (int i = 0; i < n_local; ++i) { |
| 108 |
2/2✓ Branch 0 taken 159001 times.
✓ Branch 1 taken 159001 times.
|
318002 | for (int dim = 0; std::cmp_less(dim, dims); dim++) { |
| 109 | 159001 | x[static_cast<size_t>(dim)] = dist[dim](gen); | |
| 110 | } | ||
| 111 | 159001 | local_sum += in.func(x); | |
| 112 | } | ||
| 113 | |||
| 114 | // REDUCE | ||
| 115 | 16 | double global_sum = 0.0; | |
| 116 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); |
| 117 | |||
| 118 | // RESULT | ||
| 119 | 16 | double result = 0.0; | |
| 120 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 121 | double volume = 1.0; | ||
| 122 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | for (int dim = 0; std::cmp_less(dim, dims); dim++) { |
| 123 | 8 | volume *= (in.b[dim] - in.a[dim]); | |
| 124 | } | ||
| 125 | 8 | result = (global_sum / n_total) * volume; | |
| 126 | } | ||
| 127 | |||
| 128 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | MPI_Bcast(&result, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); |
| 129 | |||
| 130 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | GetOutput() = result; |
| 131 | 16 | return true; | |
| 132 | 16 | } | |
| 133 | |||
| 134 | 16 | bool DorofeevIMonteCarloIntegrationMPI::PostProcessingImpl() { | |
| 135 | 16 | return true; | |
| 136 | } | ||
| 137 | |||
| 138 | } // namespace dorofeev_i_monte_carlo_integration_processes | ||
| 139 |