GCC Code Coverage Report


Directory: ./
File: tasks/belov_e_sobel/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 45 45 100.0%
Functions: 5 5 100.0%
Branches: 29 56 51.8%

Line Branch Exec Source
1 #include "belov_e_sobel/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <cmath>
8 #include <cstddef>
9 #include <cstdint>
10 #include <utility>
11 #include <vector>
12
13 #include "belov_e_sobel/common/include/common.hpp"
14
15 namespace belov_e_sobel {
16
17
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 BelovESobelALL::BelovESobelALL(const InType &in) {
18 SetTypeOfTask(GetStaticTypeOfTask());
19 GetInput() = in;
20 GetOutput() = in;
21 4 }
22
23
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 bool BelovESobelALL::ValidationImpl() {
24
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 return !std::get<0>(GetInput()).empty() && (std::get<1>(GetInput()) > 0) && (std::get<2>(GetInput()) > 0);
25 }
26
27 4 bool BelovESobelALL::PreProcessingImpl() {
28 4 return true;
29 }
30
31 4 bool BelovESobelALL::RunImpl() {
32 4 int rank = 0;
33 4 int size = 0;
34 4 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
35 4 MPI_Comm_size(MPI_COMM_WORLD, &size);
36
37 4 int width = 0;
38 4 int height = 0;
39 4 std::vector<uint8_t> global_input;
40 4 std::vector<uint8_t> global_output;
41
42
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank == 0) {
43
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 global_input = std::get<0>(GetInput());
44 2 width = std::get<1>(GetInput());
45 2 height = std::get<2>(GetInput());
46
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 global_output.resize(static_cast<std::size_t>(width) * height);
47 }
48
49
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(&width, 1, MPI_INT, 0, MPI_COMM_WORLD);
50
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(&height, 1, MPI_INT, 0, MPI_COMM_WORLD);
51
52 4 int base_rows = height / size;
53 4 int remainder = height % size;
54
55
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<int> send_counts(size);
56
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<int> displacements(size);
57 int current_disp = 0;
58
59
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (int i = 0; i < size; ++i) {
60
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 int rows_for_proc = base_rows + (i < remainder ? 1 : 0);
61 8 send_counts[i] = rows_for_proc * width;
62 8 displacements[i] = current_disp;
63 8 current_disp += send_counts[i];
64 }
65
66
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 int local_rows = send_counts[rank] / width;
67
68 4 int start_y_global = displacements[rank] / width;
69 4 int end_y_global = start_y_global + local_rows;
70
71
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<uint8_t> local_output(static_cast<std::size_t>(local_rows) * width);
72
73
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank != 0) {
74
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 global_input.resize(static_cast<std::size_t>(width) * height);
75 }
76
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Bcast(global_input.data(), static_cast<int>(static_cast<std::size_t>(width) * height), MPI_BYTE, 0,
77 MPI_COMM_WORLD);
78
79 auto get_px = [&](int col, int row) -> float {
80 int clamped_x = std::clamp(col, 0, width - 1);
81 int clamped_y = std::clamp(row, 0, height - 1);
82 return static_cast<float>(global_input[(static_cast<std::size_t>(clamped_y) * width) + clamped_x]);
83 4 };
84
85 4 #pragma omp parallel for default(none) \
86 shared(global_input, local_output, width, height, start_y_global, end_y_global, get_px) schedule(dynamic)
87 for (int row = start_y_global; row < end_y_global; ++row) {
88 int local_y = row - start_y_global;
89
90 for (int col = 0; col < width; ++col) {
91 float gx = (-1 * get_px(col - 1, row - 1)) + (1 * get_px(col + 1, row - 1)) + (-2 * get_px(col - 1, row)) +
92 (2 * get_px(col + 1, row)) + (-1 * get_px(col - 1, row + 1)) + (1 * get_px(col + 1, row + 1));
93
94 float gy = (-1 * get_px(col - 1, row - 1)) - (2 * get_px(col, row - 1)) - (1 * get_px(col + 1, row - 1)) +
95 (1 * get_px(col - 1, row + 1)) + (2 * get_px(col, row + 1)) + (1 * get_px(col + 1, row + 1));
96
97 float magnitude = std::sqrt((gx * gx) + (gy * gy));
98 local_output[(static_cast<std::size_t>(local_y) * width) + col] =
99 static_cast<uint8_t>(std::min(255.0F, magnitude));
100 }
101 }
102
103
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 global_output.resize(static_cast<std::size_t>(width) * height);
104
105
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MPI_Allgatherv(local_output.data(), static_cast<int>(local_output.size()), MPI_BYTE, global_output.data(),
106 send_counts.data(), displacements.data(), MPI_BYTE, MPI_COMM_WORLD);
107
108 std::get<0>(GetOutput()) = std::move(global_output);
109
110 4 return true;
111 }
112
113
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 bool BelovESobelALL::PostProcessingImpl() {
114
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 return !std::get<0>(GetOutput()).empty() && (std::get<1>(GetOutput()) > 0) && (std::get<2>(GetOutput()) > 0);
115 }
116
117 } // namespace belov_e_sobel
118