GCC Code Coverage Report


Directory: ./
File: tasks/dolov_v_monte_carlo_integration/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 68 68 100.0%
Functions: 5 5 100.0%
Branches: 37 56 66.1%

Line Branch Exec Source
1 #include "dolov_v_monte_carlo_integration/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <cstddef>
7 #include <random>
8 #include <vector>
9
10 #include "dolov_v_monte_carlo_integration/common/include/common.hpp"
11
12 namespace dolov_v_monte_carlo_integration {
13
14
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 DolovVMonteCarloIntegrationMPI::DolovVMonteCarloIntegrationMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GetInput() = in;
17 12 GetOutput() = 0.0;
18 12 }
19
20 12 bool DolovVMonteCarloIntegrationMPI::ValidationImpl() {
21 12 int rank = 0;
22 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
23 12 bool is_valid = true;
24
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
25 const auto &in = GetInput();
26
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 is_valid = in.func && (in.samples_count > 0) && (in.dimension > 0) &&
27
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
12 (in.center.size() == static_cast<size_t>(in.dimension)) && (in.radius > 0.0);
28 }
29 12 MPI_Bcast(&is_valid, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD);
30 12 return is_valid;
31 }
32
33 12 bool DolovVMonteCarloIntegrationMPI::PreProcessingImpl() {
34 12 GetOutput() = 0.0;
35 12 return true;
36 }
37
38 12 bool DolovVMonteCarloIntegrationMPI::RunImpl() {
39 12 int current_rank = 0;
40 12 int total_procs = 0;
41 12 MPI_Comm_rank(MPI_COMM_WORLD, &current_rank);
42 12 MPI_Comm_size(MPI_COMM_WORLD, &total_procs);
43
44 12 InType params = GetInput();
45 12 int dim = params.dimension;
46 12 int total_samples = params.samples_count;
47 12 double rad = params.radius;
48 12 int domain_type_int = static_cast<int>(params.domain_type);
49
50
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Bcast(&dim, 1, MPI_INT, 0, MPI_COMM_WORLD);
51
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Bcast(&total_samples, 1, MPI_INT, 0, MPI_COMM_WORLD);
52
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Bcast(&rad, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
53
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Bcast(&domain_type_int, 1, MPI_INT, 0, MPI_COMM_WORLD);
54
55
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (current_rank != 0) {
56 6 params.dimension = dim;
57 6 params.samples_count = total_samples;
58 6 params.radius = rad;
59 6 params.domain_type = static_cast<IntegrationDomain>(domain_type_int);
60
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 params.center.resize(dim);
61 }
62
63
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (dim > 0) {
64
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Bcast(params.center.data(), dim, MPI_DOUBLE, 0, MPI_COMM_WORLD);
65 }
66
67 12 int local_samples = total_samples / total_procs;
68
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (current_rank == total_procs - 1) {
69 6 local_samples += total_samples % total_procs;
70 }
71
72 12 const double r_sq = params.radius * params.radius;
73
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 std::random_device rd;
74 12 std::mt19937 random_generator(rd());
75 12 std::uniform_real_distribution<double> value_distributor(-params.radius, params.radius);
76
77 12 double local_sum_of_f = 0.0;
78
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 std::vector<double> sample_point(params.dimension);
79
80
2/2
✓ Branch 0 taken 520000 times.
✓ Branch 1 taken 12 times.
520012 for (int i = 0; i < local_samples; ++i) {
81
2/2
✓ Branch 0 taken 1040000 times.
✓ Branch 1 taken 520000 times.
1560000 for (int dim_idx = 0; dim_idx < params.dimension; ++dim_idx) {
82 1040000 sample_point[dim_idx] = params.center[dim_idx] + value_distributor(random_generator);
83 }
84
85 bool is_valid_point = true;
86
2/2
✓ Branch 0 taken 260000 times.
✓ Branch 1 taken 260000 times.
520000 if (params.domain_type == IntegrationDomain::kHyperSphere) {
87 double distance_sq = 0.0;
88
2/2
✓ Branch 0 taken 520000 times.
✓ Branch 1 taken 260000 times.
780000 for (int dim_idx = 0; dim_idx < params.dimension; ++dim_idx) {
89 520000 double diff = sample_point[dim_idx] - params.center[dim_idx];
90 520000 distance_sq += diff * diff;
91 }
92 is_valid_point = (distance_sq <= r_sq);
93 }
94
95
2/2
✓ Branch 0 taken 204453 times.
✓ Branch 1 taken 55547 times.
260000 if (is_valid_point) {
96 464453 local_sum_of_f += params.func(sample_point);
97 }
98 }
99
100 12 double global_sum_of_f = 0.0;
101
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Reduce(&local_sum_of_f, &global_sum_of_f, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
102
103 12 double final_result = 0.0;
104
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (current_rank == 0) {
105 6 const double volume = std::pow(2.0 * params.radius, params.dimension);
106 6 final_result = volume * (global_sum_of_f / total_samples);
107 }
108
109
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Bcast(&final_result, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
110
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 GetOutput() = final_result;
111 12 return std::isfinite(GetOutput());
112 12 }
113
114 12 bool DolovVMonteCarloIntegrationMPI::PostProcessingImpl() {
115 12 return true;
116 }
117
118 } // namespace dolov_v_monte_carlo_integration
119