GCC Code Coverage Report


Directory: ./
File: tasks/shkenev_i_linear_stretching_histogram_increase_contr/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 65 65 100.0%
Functions: 7 7 100.0%
Branches: 52 74 70.3%

Line Branch Exec Source
1 #include "shkenev_i_linear_stretching_histogram_increase_contr/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <climits>
7 #include <utility>
8 #include <vector>
9
10 #include "shkenev_i_linear_stretching_histogram_increase_contr/common/include/common.hpp"
11
12 namespace shkenev_i_linear_stretching_histogram_increase_contr {
13
14
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 ShkenevIlinerStretchingHistIncreaseContrMPI::ShkenevIlinerStretchingHistIncreaseContrMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 GetInput() = in;
17 22 }
18
19 22 bool ShkenevIlinerStretchingHistIncreaseContrMPI::ValidationImpl() {
20 22 int rank = 0;
21 22 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
22
23 22 int is_valid = 1;
24
25
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
26
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 if (!GetInput().empty()) {
27 10 is_valid =
28
8/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1502 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1502 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1502 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1502 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 7 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 10 times.
1527 std::all_of(GetInput().begin(), GetInput().end(), [](int val) { return val >= 0 && val <= 255; }) ? 1 : 0;
29 }
30 }
31
32 22 MPI_Bcast(&is_valid, 1, MPI_INT, 0, MPI_COMM_WORLD);
33 22 return is_valid == 1;
34 }
35
36 22 bool ShkenevIlinerStretchingHistIncreaseContrMPI::PreProcessingImpl() {
37 22 return true;
38 }
39
40 namespace {
41 20 std::pair<std::vector<int>, std::vector<int>> CalculateDistribution(int total_size, int num_processes) {
42 20 std::vector<int> send_counts(num_processes);
43
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> displs(num_processes);
44
45 20 const int base_chunk = total_size / num_processes;
46 20 const int remainder = total_size % num_processes;
47
48
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int i = 0; i < num_processes; ++i) {
49
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 30 times.
40 send_counts[i] = base_chunk;
50
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 30 times.
40 if (i < remainder) {
51 10 send_counts[i] += 1;
52 }
53
54
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
40 if (i == 0) {
55 20 displs[i] = 0;
56 } else {
57 20 displs[i] = displs[i - 1] + send_counts[i - 1];
58 }
59 }
60
61
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
40 return {send_counts, displs};
62 }
63
64
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1 times.
20 std::pair<int, int> FindLocalMinMax(const std::vector<int> &data) {
65
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1 times.
20 if (data.empty()) {
66 1 return {INT_MAX, INT_MIN};
67 }
68
69 auto min_it = std::ranges::min_element(data);
70 auto max_it = std::ranges::max_element(data);
71 19 return {*min_it, *max_it};
72 }
73
74 void ApplyLinearStretching(std::vector<int> &data, int global_min, int global_max) {
75
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (global_max <= global_min || data.empty()) {
76 return;
77 }
78
79 16 const int range = global_max - global_min;
80
2/2
✓ Branch 0 taken 6017 times.
✓ Branch 1 taken 16 times.
6033 for (auto &pixel : data) {
81 6017 pixel = (pixel - global_min) * 255 / range;
82 }
83 }
84
85 } // namespace
86
87 22 bool ShkenevIlinerStretchingHistIncreaseContrMPI::RunImpl() {
88 22 int rank = 0;
89 22 int size = 0;
90 22 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
91 22 MPI_Comm_size(MPI_COMM_WORLD, &size);
92
93 22 int total_size = 0;
94
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
95 11 total_size = static_cast<int>(GetInput().size());
96 }
97 22 MPI_Bcast(&total_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
98
99
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
22 if (total_size == 0) {
100
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (rank == 0) {
101 GetOutput().clear();
102 }
103 2 return true;
104 }
105
106 20 auto [send_counts, displs] = CalculateDistribution(total_size, size);
107
108
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<int> local_data(send_counts[rank]);
109
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
110
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(GetInput().data(), send_counts.data(), displs.data(), MPI_INT, local_data.data(), send_counts[rank],
111 MPI_INT, 0, MPI_COMM_WORLD);
112 } else {
113
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(nullptr, send_counts.data(), displs.data(), MPI_INT, local_data.data(), send_counts[rank], MPI_INT, 0,
114 MPI_COMM_WORLD);
115 }
116
117 20 auto [local_min, local_max] = FindLocalMinMax(local_data);
118
119 20 int global_min = INT_MAX;
120 20 int global_max = INT_MIN;
121
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Allreduce(&local_min, &global_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
122
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Allreduce(&local_max, &global_max, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
123
124
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 ApplyLinearStretching(local_data, global_min, global_max);
125
126
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
127
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 GetOutput().resize(total_size);
128 }
129
130
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
30 MPI_Gatherv(local_data.data(), send_counts[rank], MPI_INT, (rank == 0) ? GetOutput().data() : nullptr,
131 send_counts.data(), displs.data(), MPI_INT, 0, MPI_COMM_WORLD);
132
133 return true;
134 20 }
135
136 22 bool ShkenevIlinerStretchingHistIncreaseContrMPI::PostProcessingImpl() {
137 22 return true;
138 }
139
140 } // namespace shkenev_i_linear_stretching_histogram_increase_contr
141