GCC Code Coverage Report


Directory: ./
File: tasks/posternak_a_increase_contrast/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 71 71 100.0%
Functions: 8 8 100.0%
Branches: 33 54 61.1%

Line Branch Exec Source
1 #include "posternak_a_increase_contrast/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <vector>
8
9 #include "posternak_a_increase_contrast/common/include/common.hpp"
10
11 namespace posternak_a_increase_contrast {
12
13
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 PosternakAIncreaseContrastMPI::PosternakAIncreaseContrastMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 GetInput() = in;
16
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 GetOutput().resize(in.size());
17 20 }
18
19 20 bool PosternakAIncreaseContrastMPI::ValidationImpl() {
20 20 return !GetInput().empty();
21 }
22
23 20 bool PosternakAIncreaseContrastMPI::PreProcessingImpl() {
24 20 return true;
25 }
26
27 20 bool PosternakAIncreaseContrastMPI::RunImpl() {
28 20 int rank = 0;
29 20 int size = 0;
30 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
31 20 MPI_Comm_size(MPI_COMM_WORLD, &size);
32
33 20 int data_len = 0;
34
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
35 10 data_len = static_cast<int>(GetInput().size());
36 }
37
38 // Рассылаем процессам размер данных
39 20 MPI_Bcast(&data_len, 1, MPI_INT, 0, MPI_COMM_WORLD);
40
41 // Раздаем локальные данные всем процессам
42 20 std::vector<unsigned char> proc_part = ScatterInputData(rank, size, data_len);
43
44 // Узнаем максимальное и минимальное значение пикселей и сообщаем об этом всем процессам
45 20 unsigned char data_min = 0;
46 20 unsigned char data_max = 0;
47
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 FindGlobalMinMax(proc_part, &data_min, &data_max);
48
49 // Преобразование пикселей процессами
50
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<unsigned char> local_output = ApplyContrast(proc_part, data_min, data_max);
51
52 // Получаем данные о частях
53 20 int local_size = data_len / size;
54 20 int remainder = data_len % size;
55
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> counts(size);
56
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> step(size);
57 int start = 0;
58
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int i = 0; i < size; ++i) {
59
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
68 counts[i] = local_size + (i < remainder ? 1 : 0);
60 40 step[i] = start;
61 40 start += counts[i];
62 }
63
64 // Рассылаем результат всем процессам
65
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 GetOutput().resize(data_len);
66
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Allgatherv(local_output.data(), static_cast<int>(local_output.size()), MPI_UNSIGNED_CHAR, GetOutput().data(),
67 counts.data(), step.data(), MPI_UNSIGNED_CHAR, MPI_COMM_WORLD);
68
69 20 return true;
70 }
71
72 20 std::vector<unsigned char> PosternakAIncreaseContrastMPI::ScatterInputData(int rank, int size, int data_len) {
73 20 int local_size = data_len / size;
74 20 int remainder = data_len % size;
75
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 6 times.
20 int my_size = local_size + (rank < remainder ? 1 : 0);
76
77 20 std::vector<int> counts(size);
78
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> step(size);
79 int start = 0;
80
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int i = 0; i < size; ++i) {
81
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
68 counts[i] = local_size + (i < remainder ? 1 : 0);
82 40 step[i] = start;
83 40 start += counts[i];
84 }
85
86
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<unsigned char> proc_part(my_size);
87
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
88
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(GetInput().data(), counts.data(), step.data(), MPI_UNSIGNED_CHAR, proc_part.data(), my_size,
89 MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
90 } else {
91
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(nullptr, nullptr, nullptr, MPI_UNSIGNED_CHAR, proc_part.data(), my_size, MPI_UNSIGNED_CHAR, 0,
92 MPI_COMM_WORLD);
93 }
94 20 return proc_part;
95 }
96
97 20 void PosternakAIncreaseContrastMPI::FindGlobalMinMax(const std::vector<unsigned char> &proc_part,
98 unsigned char *data_min, unsigned char *data_max) {
99 20 unsigned char local_min = 255;
100 20 unsigned char local_max = 0;
101
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 20 times.
56 for (unsigned char pixel : proc_part) {
102 36 local_min = std::min(local_min, pixel);
103 36 local_max = std::max(local_max, pixel);
104 }
105
106 20 MPI_Allreduce(&local_min, data_min, 1, MPI_UNSIGNED_CHAR, MPI_MIN, MPI_COMM_WORLD);
107 20 MPI_Allreduce(&local_max, data_max, 1, MPI_UNSIGNED_CHAR, MPI_MAX, MPI_COMM_WORLD);
108 20 }
109
110 20 std::vector<unsigned char> PosternakAIncreaseContrastMPI::ApplyContrast(const std::vector<unsigned char> &proc_part,
111 unsigned char data_min,
112 unsigned char data_max) {
113 20 int my_size = static_cast<int>(proc_part.size());
114 20 std::vector<unsigned char> local_output(my_size);
115
116
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 12 times.
20 if (data_min == data_max) {
117 std::ranges::fill(local_output, 128);
118 } else {
119 12 const double scale = 255.0 / (data_max - data_min);
120
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 12 times.
39 for (int i = 0; i < my_size; ++i) {
121 27 double scaled_value = (proc_part[i] - data_min) * scale;
122 27 int new_pixel = static_cast<int>(std::lround(scaled_value));
123 27 if (new_pixel < 0) {
124 new_pixel = 0;
125 27 } else if (new_pixel > 255) {
126 new_pixel = 255;
127 }
128 27 local_output[i] = static_cast<unsigned char>(new_pixel);
129 }
130 }
131 20 return local_output;
132 }
133
134 20 bool PosternakAIncreaseContrastMPI::PostProcessingImpl() {
135 20 return true;
136 }
137
138 } // namespace posternak_a_increase_contrast
139