GCC Code Coverage Report


Directory: ./
File: tasks/dorofeev_i_monte_carlo_integration/mpi/src/ops_mpi.cpp
Date: 2025-12-13 04:24:21
Exec Total Coverage
Lines: 68 68 100.0%
Functions: 5 5 100.0%
Branches: 45 70 64.3%

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