| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "iskhakov_d_trapezoidal_integration/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <cmath> | ||
| 6 | #include <cstddef> | ||
| 7 | #include <tuple> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "iskhakov_d_trapezoidal_integration/common/include/common.hpp" | ||
| 11 | |||
| 12 | namespace iskhakov_d_trapezoidal_integration { | ||
| 13 | |||
| 14 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | IskhakovDTrapezoidalIntegrationMPI::IskhakovDTrapezoidalIntegrationMPI(const InType &in) { |
| 15 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 16 | GetInput() = in; | ||
| 17 | 30 | GetOutput() = 0; | |
| 18 | 30 | } | |
| 19 | |||
| 20 | 30 | bool IskhakovDTrapezoidalIntegrationMPI::ValidationImpl() { | |
| 21 | auto &input = GetInput(); | ||
| 22 | 30 | double lower_level = std::get<0>(input); | |
| 23 | 30 | double top_level = std::get<1>(input); | |
| 24 | 30 | int number_steps = std::get<3>(input); | |
| 25 | |||
| 26 |
2/4✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
|
30 | return (lower_level < top_level) && (number_steps > 0); |
| 27 | } | ||
| 28 | |||
| 29 | 30 | bool IskhakovDTrapezoidalIntegrationMPI::PreProcessingImpl() { | |
| 30 | 30 | return true; | |
| 31 | } | ||
| 32 | |||
| 33 | 30 | bool IskhakovDTrapezoidalIntegrationMPI::RunImpl() { | |
| 34 | 30 | int world_rank = 0; | |
| 35 | 30 | MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); | |
| 36 | |||
| 37 | 30 | int world_size = 0; | |
| 38 | 30 | MPI_Comm_size(MPI_COMM_WORLD, &world_size); | |
| 39 | |||
| 40 | auto &input = GetInput(); | ||
| 41 | |||
| 42 | 30 | double lower_level = 0.0; | |
| 43 | 30 | double top_level = 0.0; | |
| 44 | 30 | int number_steps = 0; | |
| 45 | |||
| 46 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
|
30 | if (world_rank == 0) { |
| 47 | 15 | lower_level = std::get<0>(input); | |
| 48 | 15 | top_level = std::get<1>(input); | |
| 49 | 15 | number_steps = std::get<3>(input); | |
| 50 | } | ||
| 51 | |||
| 52 | 30 | MPI_Bcast(&lower_level, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 53 | 30 | MPI_Bcast(&top_level, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); | |
| 54 | 30 | MPI_Bcast(&number_steps, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 55 | |||
| 56 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | if (number_steps == 0) { |
| 57 | ✗ | GetOutput() = 0.0; | |
| 58 | ✗ | return true; | |
| 59 | } | ||
| 60 | |||
| 61 | 30 | auto input_function = std::get<2>(input); | |
| 62 | 30 | double step = (top_level - lower_level) / static_cast<double>(number_steps); | |
| 63 | |||
| 64 | 30 | int base_count = number_steps / world_size; | |
| 65 | 30 | int remainder = number_steps % world_size; | |
| 66 | |||
| 67 |
1/4✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
30 | std::vector<int> elements_per_proc(static_cast<std::size_t>(world_size)); |
| 68 |
1/4✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
30 | std::vector<int> displacement(static_cast<std::size_t>(world_size)); |
| 69 | |||
| 70 | int offset = 0; | ||
| 71 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 30 times.
|
90 | for (int process_id = 0; process_id < world_size; ++process_id) { |
| 72 |
1/2✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
|
120 | elements_per_proc[static_cast<std::size_t>(process_id)] = base_count + (process_id < remainder ? 1 : 0); |
| 73 | 60 | displacement[static_cast<std::size_t>(process_id)] = offset; | |
| 74 | 60 | offset += elements_per_proc[static_cast<std::size_t>(process_id)]; | |
| 75 | } | ||
| 76 | |||
| 77 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
|
30 | int local_count = elements_per_proc[static_cast<std::size_t>(world_rank)]; |
| 78 | |||
| 79 | 30 | std::vector<double> all_points; | |
| 80 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
|
30 | if (world_rank == 0) { |
| 81 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | all_points.resize(static_cast<std::size_t>(number_steps) + 1); |
| 82 |
2/2✓ Branch 0 taken 204015 times.
✓ Branch 1 taken 15 times.
|
204030 | for (int step_index = 0; step_index <= number_steps; ++step_index) { |
| 83 | 204015 | all_points[static_cast<std::size_t>(step_index)] = lower_level + (static_cast<double>(step_index) * step); | |
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 |
2/6✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
30 | std::vector<double> local_points(static_cast<std::size_t>(local_count)); |
| 88 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | MPI_Scatterv(all_points.data(), elements_per_proc.data(), displacement.data(), MPI_DOUBLE, local_points.data(), |
| 89 | local_count, MPI_DOUBLE, 0, MPI_COMM_WORLD); | ||
| 90 | |||
| 91 | 30 | double local_sum = 0.0; | |
| 92 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 204000 times.
✓ Branch 2 taken 204000 times.
✓ Branch 3 taken 30 times.
|
204030 | for (double point : local_points) { |
| 93 | 204000 | local_sum += input_function(point); | |
| 94 | } | ||
| 95 | |||
| 96 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
|
30 | if (world_rank == 0) { |
| 97 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
30 | local_sum -= input_function(local_points.front()) * 0.5; |
| 98 | } | ||
| 99 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
|
30 | if (world_rank == world_size - 1) { |
| 100 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
30 | local_sum -= input_function(local_points.back()) * 0.5; |
| 101 | } | ||
| 102 | |||
| 103 | 30 | double result = 0.0; | |
| 104 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | MPI_Allreduce(&local_sum, &result, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); |
| 105 | |||
| 106 |
1/2✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
|
30 | GetOutput() = result * step; |
| 107 | |||
| 108 | return true; | ||
| 109 | } | ||
| 110 | |||
| 111 | 30 | bool IskhakovDTrapezoidalIntegrationMPI::PostProcessingImpl() { | |
| 112 | 30 | return true; | |
| 113 | } | ||
| 114 | |||
| 115 | } // namespace iskhakov_d_trapezoidal_integration | ||
| 116 |