GCC Code Coverage Report


Directory: ./
File: tasks/guseva_a_jarvis/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 78 78 100.0%
Functions: 5 5 100.0%
Branches: 68 112 60.7%

Line Branch Exec Source
1 #include "guseva_a_jarvis/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstdint>
8 #include <utility>
9 #include <vector>
10
11 #include "guseva_a_jarvis/common/include/common.hpp"
12
13 namespace guseva_a_jarvis {
14
15
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 GusevaAJarvisMPI::GusevaAJarvisMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 GetInput() = in;
18 22 GetOutput() = std::vector<int>();
19
20
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Comm_rank(MPI_COMM_WORLD, &rank_);
21
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Comm_size(MPI_COMM_WORLD, &size_);
22 22 }
23
24 22 bool GusevaAJarvisMPI::ValidationImpl() {
25 const auto &[width, height, image] = GetInput();
26
27
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank_ == 0) {
28 11 const bool is_size_match = static_cast<int>(image.size()) == width * height;
29 bool is_image_binary = true;
30
2/2
✓ Branch 0 taken 22198 times.
✓ Branch 1 taken 11 times.
22209 for (const int pixel_value : image) {
31
1/2
✓ Branch 0 taken 22198 times.
✗ Branch 1 not taken.
22198 if (pixel_value != 0 && pixel_value != 1) {
32 is_image_binary = false;
33 break;
34 }
35 }
36
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 const bool is_size_possible = width > 0 && height > 0;
37
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 return is_image_binary && is_size_possible && is_size_match;
38 }
39
40 return true;
41 }
42
43 22 bool GusevaAJarvisMPI::PreProcessingImpl() {
44 const auto &input_tuple = GetInput();
45 22 const int width = std::get<0>(input_tuple);
46
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 const int height = std::get<1>(input_tuple);
47 const std::vector<int> &image = std::get<2>(input_tuple);
48
49 points_.clear();
50 22 int rows_per_process = height / size_;
51 22 int remainder = height % size_;
52
53
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
22 int start_row = (rank_ * rows_per_process) + std::min(rank_, remainder);
54
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
22 int end_row = start_row + rows_per_process + (rank_ < remainder ? 1 : 0);
55
56
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 22 times.
500 for (int yy = start_row; yy < end_row; ++yy) {
57
2/2
✓ Branch 0 taken 22198 times.
✓ Branch 1 taken 478 times.
22676 for (int xx = 0; xx < width; ++xx) {
58
2/2
✓ Branch 0 taken 11090 times.
✓ Branch 1 taken 11108 times.
22198 if (image[(yy * width) + xx] == 1) {
59 11090 points_.emplace_back(xx, yy);
60 }
61 }
62 }
63
64 22 return true;
65 }
66
67 22 bool GusevaAJarvisMPI::RunImpl() {
68 22 std::vector<std::pair<int, int>> local_hull = BuildConvexHull(points_);
69
70 22 int local_hull_size = static_cast<int>(local_hull.size());
71
2/6
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
22 std::vector<int> all_hull_sizes(size_, 0);
72
73
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Gather(&local_hull_size, 1, MPI_INT, all_hull_sizes.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
74
75
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> displacements(size_, 0);
76
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> recv_counts(size_, 0);
77 int64_t total_points = 0;
78
79
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank_ == 0) {
80
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 11 times.
33 for (int i = 0; i < size_; ++i) {
81 22 recv_counts[i] = all_hull_sizes[i] * 2;
82 22 displacements[i] = static_cast<int>(total_points) * 2;
83 22 total_points += all_hull_sizes[i];
84 }
85 }
86
87
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> local_data(static_cast<int64_t>(local_hull_size) * 2);
88
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 22 times.
149 for (int64_t i = 0; i < local_hull_size; ++i) {
89 127 local_data[i * 2] = local_hull[i].first;
90 127 local_data[(i * 2) + 1] = local_hull[i].second;
91 }
92
93 22 std::vector<int> all_data;
94
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank_ == 0) {
95
1/4
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
11 all_data.resize(total_points * 2, 0);
96 }
97
98
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Gatherv(local_data.data(), local_hull_size * 2, MPI_INT, all_data.data(), recv_counts.data(),
99 displacements.data(), MPI_INT, 0, MPI_COMM_WORLD);
100
101
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank_ == 0) {
102 11 std::vector<std::pair<int, int>> all_points;
103
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 all_points.reserve(total_points);
104
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 11 times.
138 for (int64_t i = 0; i < total_points; ++i) {
105
1/2
✓ Branch 1 taken 127 times.
✗ Branch 2 not taken.
127 all_points.emplace_back(all_data[i * 2], all_data[(i * 2) + 1]);
106 }
107
108
2/6
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
22 hull_ = BuildConvexHull(all_points);
109 }
110
111 22 return true;
112 }
113
114 22 bool GusevaAJarvisMPI::PostProcessingImpl() {
115 const auto &input_tuple = GetInput();
116 22 const int width = std::get<0>(input_tuple);
117 22 const int height = std::get<1>(input_tuple);
118
119 22 int hull_size = 0;
120
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank_ == 0) {
121 11 hull_size = static_cast<int>(hull_.size());
122 }
123
124 22 MPI_Bcast(&hull_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
125
126 22 std::vector<int> hull_data;
127
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank_ == 0) {
128
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 hull_data.resize(static_cast<int64_t>(hull_size) * 2, 0);
129
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 11 times.
77 for (int64_t i = 0; i < hull_size; ++i) {
130 66 hull_data[i * 2] = hull_[i].first;
131 66 hull_data[(i * 2) + 1] = hull_[i].second;
132 }
133 } else {
134
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 hull_data.resize(static_cast<int64_t>(hull_size) * 2, 0);
135 }
136
137
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Bcast(hull_data.data(), hull_size * 2, MPI_INT, 0, MPI_COMM_WORLD);
138
139
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank_ != 0) {
140 hull_.clear();
141
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 hull_.reserve(hull_size);
142
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 11 times.
77 for (int64_t i = 0; i < hull_size; ++i) {
143
1/2
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
66 hull_.emplace_back(hull_data[i * 2], hull_data[(i * 2) + 1]);
144 }
145 }
146
147
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> output_vector(static_cast<int64_t>(width) * height, 0);
148
149
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 22 times.
154 for (const auto &point : hull_) {
150 132 const int x = point.first;
151 132 const int y = point.second;
152
2/4
✓ Branch 0 taken 132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 132 times.
✗ Branch 3 not taken.
132 if (x >= 0 && x < width && y >= 0 && y < height) {
153 132 output_vector[(y * width) + x] = 1;
154 }
155 }
156
157
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 GetOutput() = output_vector;
158
159 22 return true;
160 }
161
162 } // namespace guseva_a_jarvis
163