GCC Code Coverage Report


Directory: ./
File: tasks/shkryleva_s_vec_min_val/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 58 59 98.3%
Functions: 7 7 100.0%
Branches: 31 40 77.5%

Line Branch Exec Source
1 #include "shkryleva_s_vec_min_val/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <climits>
7 #include <cstdint>
8 #include <limits>
9 #include <vector>
10
11 #include "shkryleva_s_vec_min_val/common/include/common.hpp"
12
13 namespace shkryleva_s_vec_min_val {
14
15 namespace {
16
17 struct DistributionInfo {
18 std::vector<int> sendcounts;
19 std::vector<int> displacements;
20 int local_count = 0;
21 };
22
23 12 DistributionInfo CalculateDistribution(int total_size, int world_size) {
24 12 DistributionInfo info;
25
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 info.sendcounts.resize(world_size);
26
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 info.displacements.resize(world_size);
27
28 12 const int base_size = total_size / world_size;
29 12 const int extra_items = total_size % world_size;
30
31 int offset = 0;
32
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 for (int i = 0; i < world_size; ++i) {
33
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
44 info.sendcounts[i] = base_size + (i < extra_items ? 1 : 0);
34 24 info.displacements[i] = offset;
35 24 offset += info.sendcounts[i];
36 }
37
38 12 return info;
39 }
40
41 void BroadcastVectorSize(uint64_t &total_size_uint64) {
42 14 MPI_Bcast(&total_size_uint64, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD);
43 }
44
45 int ComputeLocalMinimum(const std::vector<int> &local_data) {
46
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1 times.
12 if (local_data.empty()) {
47 return INT_MAX;
48 }
49
50 int local_min = INT_MAX;
51
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 11 times.
35 for (int value : local_data) {
52 local_min = std::min(value, local_min);
53 }
54 return local_min;
55 }
56
57 12 std::vector<int> ScatterVectorData(const std::vector<int> *input_data_ptr, const DistributionInfo &info,
58 int world_rank) {
59 12 std::vector<int> local_data;
60
61
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1 times.
12 if (info.local_count > 0) {
62
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 local_data.resize(info.local_count);
63
64
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5 times.
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
17 MPI_Scatterv((world_rank == 0) ? input_data_ptr->data() : nullptr, info.sendcounts.data(),
65
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5 times.
11 info.displacements.data(), MPI_INT, local_data.data(), info.local_count, MPI_INT, 0, MPI_COMM_WORLD);
66 }
67
68 12 return local_data;
69 }
70
71 int PerformGlobalReduction(int local_min) {
72 14 int total_min = INT_MAX;
73 14 MPI_Allreduce(&local_min, &total_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
74 14 return total_min;
75 }
76
77 } // namespace
78
79
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 ShkrylevaSVecMinValMPI::ShkrylevaSVecMinValMPI(const InType &in) {
80 SetTypeOfTask(GetStaticTypeOfTask());
81
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 GetInput() = in;
82 14 GetOutput() = 0;
83 14 }
84
85 14 bool ShkrylevaSVecMinValMPI::ValidationImpl() {
86 14 int world_rank = 0;
87 14 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
88
89 bool is_valid = true;
90
91
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (world_rank == 0) {
92
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if (!GetInput().empty()) {
93 auto size = static_cast<uint64_t>(GetInput().size());
94 is_valid = (size <= static_cast<uint64_t>(std::numeric_limits<int>::max()));
95 }
96 }
97
98
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int validation_result = is_valid ? 1 : 0;
99 14 MPI_Bcast(&validation_result, 1, MPI_INT, 0, MPI_COMM_WORLD);
100
101 14 return validation_result != 0;
102 }
103
104 14 bool ShkrylevaSVecMinValMPI::PreProcessingImpl() {
105 14 GetOutput() = INT_MAX;
106 14 return true;
107 }
108
109 14 bool ShkrylevaSVecMinValMPI::RunImpl() {
110 14 int world_rank = 0;
111 14 int world_size = 0;
112 14 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
113 14 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
114
115 14 uint64_t total_size_uint64 = 0;
116 const std::vector<int> *input_data_ptr = nullptr;
117
118
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (world_rank == 0) {
119 input_data_ptr = &GetInput();
120 7 total_size_uint64 = static_cast<uint64_t>(input_data_ptr->size());
121 }
122
123 BroadcastVectorSize(total_size_uint64);
124
125 14 const int total_size = static_cast<int>(total_size_uint64);
126 int local_min = INT_MAX;
127
128
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 if (total_size > 0) {
129 12 DistributionInfo info = CalculateDistribution(total_size, world_size);
130
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 info.local_count = info.sendcounts[world_rank];
131
132
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 std::vector<int> local_data = ScatterVectorData(input_data_ptr, info, world_rank);
133
134 local_min = ComputeLocalMinimum(local_data);
135 12 }
136
137 14 int total_min = PerformGlobalReduction(local_min);
138
139 14 GetOutput() = total_min;
140 14 return true;
141 }
142
143 14 bool ShkrylevaSVecMinValMPI::PostProcessingImpl() {
144 14 return true;
145 }
146
147 } // namespace shkryleva_s_vec_min_val
148