GCC Code Coverage Report


Directory: ./
File: tasks/melnik_i_gauss_block_part/mpi/include/ops_mpi.hpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 1 1 100.0%
Functions: 0 0 -%
Branches: 24 48 50.0%

Line Branch Exec Source
1 #pragma once
2
3 #include <cstdint>
4 #include <utility>
5 #include <vector>
6
7 #include "melnik_i_gauss_block_part/common/include/common.hpp"
8 #include "task/include/task.hpp"
9
10 namespace melnik_i_gauss_block_part {
11
12 class MelnikIGaussBlockPartMPI : public BaseTask {
13 public:
14 static constexpr ppc::task::TypeOfTask GetStaticTypeOfTask() {
15 return ppc::task::TypeOfTask::kMPI;
16 }
17
18 explicit MelnikIGaussBlockPartMPI(const InType &in);
19
20 private:
21 struct BlockInfo {
22 int start_x = 0;
23 int start_y = 0;
24 int width = 0;
25 int height = 0;
26 [[nodiscard]] bool Empty() const {
27
24/48
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 9 times.
✓ Branch 12 taken 18 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 18 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 18 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 18 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 9 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 9 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 9 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 9 times.
✓ Branch 28 taken 9 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 9 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 18 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 18 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 18 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 18 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 18 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 18 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 18 times.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✓ Branch 47 taken 18 times.
162 return width <= 0 || height <= 0;
28 }
29 };
30
31 struct Neighbours {
32 int up = 0;
33 int down = 0;
34 int left = 0;
35 int right = 0;
36 int up_left = 0;
37 int up_right = 0;
38 int down_left = 0;
39 int down_right = 0;
40 };
41
42 bool ValidationImpl() override;
43 bool PreProcessingImpl() override;
44 bool RunImpl() override;
45 bool PostProcessingImpl() override;
46
47 // Computes optimal 2D process grid (rows x cols) matching image aspect ratio
48 static std::pair<int, int> ComputeProcessGrid(int comm_size, int width, int height);
49 // Computes block info for a process given its rank
50 static BlockInfo ComputeBlockInfo(int rank, int grid_rows, int grid_cols, int width, int height);
51 // Computes block info for a process given its grid coordinates (process row, process column)
52 static BlockInfo ComputeBlockInfoByCoords(int pr, int pc, int grid_rows, int grid_cols, int width, int height);
53
54 // Clamps value v to range [low, high]
55 static int ClampInt(int v, int low, int high);
56 // Creates extended buffer (with halo borders) from local block using clamp
57 static void FillExtendedWithClamp(const std::vector<std::uint8_t> &local, const BlockInfo &blk, int ext_w,
58 std::vector<std::uint8_t> &ext);
59
60 // Exchanges halo regions (rows, columns, corners) with neighboring processes
61 static void ExchangeHalos(const BlockInfo &blk, int grid_rows, int grid_cols, int rank,
62 const std::vector<BlockInfo> &all_blocks, std::vector<std::uint8_t> &ext);
63
64 // Computes ranks of all 8 neighboring processes (up, down, left, right, and 4 diagonals)
65 static Neighbours ComputeNeighbours(const BlockInfo &blk, int grid_rows, int grid_cols, int rank,
66 const std::vector<BlockInfo> &all_blocks);
67 // Exchanges top and bottom row halos with vertical neighbors
68 static void ExchangeRowHalos(const BlockInfo &blk, const Neighbours &nbh, int ext_w, std::vector<std::uint8_t> &ext);
69 // Exchanges left and right column halos with horizontal neighbors
70 static void ExchangeColHalos(const BlockInfo &blk, const Neighbours &nbh, int ext_w, std::vector<std::uint8_t> &ext);
71 // Exchanges corner pixel values with diagonal neighbors
72 static void ExchangeCornerHalos(const BlockInfo &blk, const Neighbours &nbh, int ext_w,
73 std::vector<std::uint8_t> &ext);
74 // Fixes corner halo values when diagonal neighbor is absent, using adjacent edge halos
75 static void FixCornersWithoutDiagonal(const BlockInfo &blk, const Neighbours &nbh, int ext_w,
76 std::vector<std::uint8_t> &ext);
77
78 // Applies 3x3 Gaussian convolution to extended buffer, producing local output block
79 static void ApplyGaussianFromExtended(const BlockInfo &blk, const std::vector<std::uint8_t> &ext,
80 std::vector<std::uint8_t> &local_out);
81
82 // Broadcasts image dimensions (width, height) from rank 0 to all processes
83 static void BroadcastImageSize(int rank, int &width, int &height);
84 // Builds block information for all processes in the communicator
85 static std::vector<BlockInfo> BuildAllBlocks(int comm_size, int grid_rows, int grid_cols, int width, int height);
86 // Sends data blocks from root process to all other processes
87 static void SendBlocksToOthers(int comm_size, int width, int height, const std::vector<BlockInfo> &blocks,
88 const std::vector<std::uint8_t> &root_data);
89 // Scatters input image blocks
90 static std::vector<std::uint8_t> ScatterBlock(int rank, int comm_size, int width, int height,
91 const std::vector<BlockInfo> &blocks, const BlockInfo &my_blk,
92 const std::vector<std::uint8_t> &root_data);
93 // Computes local convolution result
94 static std::vector<std::uint8_t> ComputeLocal(const BlockInfo &my_blk, int grid_rows, int grid_cols, int rank,
95 const std::vector<BlockInfo> &blocks,
96 const std::vector<std::uint8_t> &local_data);
97 // Gathers local results from all processes into global output array on rank 0
98 static std::vector<std::uint8_t> GatherGlobal(int rank, int comm_size, int width, int height,
99 const std::vector<BlockInfo> &blocks, const BlockInfo &my_blk,
100 const std::vector<std::uint8_t> &local_out);
101 // Finalizes output: broadcast
102 void FinalizeOutput(int rank, int width, int height, std::vector<std::uint8_t> &global_out);
103 };
104
105 } // namespace melnik_i_gauss_block_part
106