GCC Code Coverage Report


Directory: ./
File: tasks/buzulukski_d_gaus_gorizontal/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 0 52 0.0%
Functions: 0 6 0.0%
Branches: 0 24 0.0%

Line Branch Exec Source
1 #include "buzulukski_d_gaus_gorizontal/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <array>
8 #include <cstddef>
9 #include <cstdint>
10 #include <vector>
11
12 #include "buzulukski_d_gaus_gorizontal/common/include/common.hpp"
13
14 namespace buzulukski_d_gaus_gorizontal {
15
16 namespace {
17 constexpr int kChannels = 3;
18 constexpr int kKernelSum = 16;
19 constexpr std::array<std::array<int, 3>, 3> kKernel = {{{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}};
20
21 uint8_t CalculatePixelALL(const uint8_t *in, int py, int px, int w, int h, int ch) {
22 int sum = 0;
23 for (int ky = -1; ky <= 1; ++ky) {
24 for (int kx = -1; kx <= 1; ++kx) {
25 int ny = std::clamp(py + ky, 0, h - 1);
26 int nx = std::clamp(px + kx, 0, w - 1);
27 size_t idx = ((static_cast<size_t>(ny) * w + nx) * kChannels) + ch;
28 sum += static_cast<int>(in[idx]) * kKernel.at(static_cast<size_t>(ky) + 1).at(static_cast<size_t>(kx) + 1);
29 }
30 }
31 return static_cast<uint8_t>(sum / kKernelSum);
32 }
33 } // namespace
34
35 BuzulukskiDGausGorizontalALL::BuzulukskiDGausGorizontalALL(const InType &in) : BaseTask() {
36 SetTypeOfTask(GetStaticTypeOfTask());
37 GetInput() = in;
38 GetOutput() = 0;
39 }
40
41 bool BuzulukskiDGausGorizontalALL::ValidationImpl() {
42 return GetInput() >= 3;
43 }
44
45 bool BuzulukskiDGausGorizontalALL::PreProcessingImpl() {
46 width_ = GetInput();
47 height_ = GetInput();
48 size_t total_size = static_cast<size_t>(width_) * height_ * kChannels;
49 input_image_.assign(total_size, 100);
50 output_image_.assign(total_size, 0);
51 return true;
52 }
53
54 bool BuzulukskiDGausGorizontalALL::RunImpl() {
55 int rank = 0;
56 int size = 0;
57 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
58 MPI_Comm_size(MPI_COMM_WORLD, &size);
59
60 int h = height_;
61 int w = width_;
62
63 int rows_per_proc = h / size;
64 int start_row = rank * rows_per_proc;
65 int end_row = (rank == size - 1) ? h : (rank + 1) * rows_per_proc;
66
67 const uint8_t *input_ptr = input_image_.data();
68 std::vector<uint8_t> local_output((static_cast<size_t>(end_row) - start_row) * w * kChannels);
69 uint8_t *local_ptr = local_output.data();
70
71 #pragma omp parallel for collapse(2) default(none) shared(start_row, end_row, w, h, input_ptr, local_ptr)
72 for (int py = start_row; py < end_row; ++py) {
73 for (int px = 0; px < w; ++px) {
74 for (int ch = 0; ch < kChannels; ++ch) {
75 int local_py = py - start_row;
76 size_t local_idx = ((static_cast<size_t>(local_py) * w + px) * kChannels) + ch;
77 local_ptr[local_idx] = CalculatePixelALL(input_ptr, py, px, w, h, ch);
78 }
79 }
80 }
81
82 std::vector<int> recv_counts;
83 std::vector<int> displs;
84
85 if (rank == 0) {
86 recv_counts.resize(size);
87 displs.resize(size);
88 for (int i = 0; i < size; ++i) {
89 int s = i * rows_per_proc;
90 int e = (i == size - 1) ? h : (i + 1) * rows_per_proc;
91 recv_counts[i] = (e - s) * w * kChannels;
92 displs[i] = s * w * kChannels;
93 }
94 }
95
96 MPI_Gatherv(local_ptr, static_cast<int>(local_output.size()), MPI_UNSIGNED_CHAR, output_image_.data(),
97 recv_counts.data(), displs.data(), MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
98
99 return true;
100 }
101
102 bool BuzulukskiDGausGorizontalALL::PostProcessingImpl() {
103 int rank = 0;
104 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
105 if (rank == 0) {
106 int64_t total_sum = 0;
107 for (const auto &val : output_image_) {
108 total_sum += static_cast<int64_t>(val);
109 }
110 GetOutput() = static_cast<int>(total_sum / static_cast<int64_t>(output_image_.size()));
111 }
112 return true;
113 }
114
115 } // namespace buzulukski_d_gaus_gorizontal
116