GCC Code Coverage Report


Directory: ./
File: tasks/titaev_m_metod_pryamougolnikov/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 54 58 93.1%
Functions: 6 7 85.7%
Branches: 36 52 69.2%

Line Branch Exec Source
1 #include "titaev_m_metod_pryamougolnikov/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "titaev_m_metod_pryamougolnikov/common/include/common.hpp"
10 namespace titaev_m_metod_pryamougolnikov {
11
12 namespace {
13
14 double Function(const std::vector<double> &coords) {
15 double sum = 0.0;
16
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 600 times.
✓ Branch 3 taken 300 times.
900 for (double x : coords) {
17 600 sum += x;
18 }
19 return sum;
20 }
21
22 6 double ComputeLocalSum(int start_index, int end_index, int partitions, const std::vector<double> &step_sizes,
23 const std::vector<double> &left_bounds) {
24 double local_sum = 0.0;
25 6 const int dimensions = static_cast<int>(left_bounds.size());
26
27 6 std::vector<int> indices(dimensions, 0);
28 int total_points = 1;
29
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for (int dimension = 0; dimension < dimensions; ++dimension) {
30 12 total_points *= partitions;
31 }
32
33
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 6 times.
606 for (int point_idx = 0; point_idx < total_points; ++point_idx) {
34 int temp = point_idx;
35
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 600 times.
1800 for (int dimension = 0; dimension < dimensions; ++dimension) {
36 1200 indices[dimension] = temp % partitions;
37 1200 temp /= partitions;
38 }
39
4/4
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 150 times.
✓ Branch 3 taken 300 times.
600 if (indices[0] < start_index || indices[0] > end_index) {
40 300 continue;
41 }
42
43
1/2
✓ Branch 1 taken 300 times.
✗ Branch 2 not taken.
300 std::vector<double> point(dimensions);
44
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 300 times.
900 for (int dimension = 0; dimension < dimensions; ++dimension) {
45 600 point[dimension] = left_bounds[dimension] + ((indices[dimension] + 0.5) * step_sizes[dimension]);
46 }
47
48
1/2
✓ Branch 0 taken 300 times.
✗ Branch 1 not taken.
300 local_sum += Function(point);
49 }
50
51 6 return local_sum;
52 }
53
54 } // namespace
55
56
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 TitaevMMetodPryamougolnikovMPI::TitaevMMetodPryamougolnikovMPI(const InType &input) {
57 SetTypeOfTask(GetStaticTypeOfTask());
58 GetInput() = input;
59 6 GetOutput() = 0.0;
60 6 }
61
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 bool TitaevMMetodPryamougolnikovMPI::ValidationImpl() {
63 const auto &input = GetInput();
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (input.left_bounds.size() != input.right_bounds.size()) {
65 return false;
66 }
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (input.partitions <= 0) {
68 return false;
69 }
70
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for (std::size_t i = 0; i < input.left_bounds.size(); ++i) {
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (input.right_bounds[i] <= input.left_bounds[i]) {
72 return false;
73 }
74 }
75 return true;
76 }
77
78 6 bool TitaevMMetodPryamougolnikovMPI::PreProcessingImpl() {
79 6 GetOutput() = 0.0;
80 6 return true;
81 }
82
83 double TitaevMMetodPryamougolnikovMPI::IntegrandFunction(const std::vector<double> &coords) {
84 return Function(coords);
85 }
86
87 6 bool TitaevMMetodPryamougolnikovMPI::RunImpl() {
88 6 int rank = 0;
89 6 int size = 1;
90 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
91 6 MPI_Comm_size(MPI_COMM_WORLD, &size);
92
93 const auto &input = GetInput();
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 const int partitions = input.partitions;
95 6 const int dimensions = static_cast<int>(input.left_bounds.size());
96
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (dimensions == 0) {
98 GetOutput() = 0.0;
99 return true;
100 }
101
102 6 std::vector<double> step_sizes(dimensions);
103
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for (int dimension = 0; dimension < dimensions; ++dimension) {
104 12 step_sizes[dimension] = (input.right_bounds[dimension] - input.left_bounds[dimension]) / partitions;
105 }
106
107 6 const int chunk_size = partitions / size;
108 6 const int remainder = partitions % size;
109
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 const int start_index = (rank * chunk_size) + std::min(rank, remainder);
110
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 const int end_index = start_index + chunk_size - 1 + (rank < remainder ? 1 : 0);
111
112
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 double local_sum = ComputeLocalSum(start_index, end_index, partitions, step_sizes, input.left_bounds);
113
114 6 double global_sum = 0.0;
115
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
116
117 double volume_element = 1.0;
118
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for (double h : step_sizes) {
119 12 volume_element *= h;
120 }
121
122
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
123 3 GetOutput() = global_sum * volume_element;
124 }
125
126
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(&GetOutput(), 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
127 return true;
128 }
129
130 6 bool TitaevMMetodPryamougolnikovMPI::PostProcessingImpl() {
131 6 return true;
132 }
133
134 } // namespace titaev_m_metod_pryamougolnikov
135