GCC Code Coverage Report


Directory: ./
File: tasks/chernykh_s_yadro_gaussa_horizontal/mpi/src/ops_mpi.cpp
Date: 2026-02-02 01:14:38
Exec Total Coverage
Lines: 75 75 100.0%
Functions: 7 7 100.0%
Branches: 50 78 64.1%

Line Branch Exec Source
1 #include "chernykh_s_yadro_gaussa_horizontal/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "chernykh_s_yadro_gaussa_horizontal/common/include/common.hpp"
10 namespace chernykh_s_yadro_gaussa_horizontal {
11
12 1238600 int ChernykhSYadroGaussaHorizontalMPI::CalculateGauss(const std::vector<int> &data, int r, int c, int stolbci,
13 int extended_rows) {
14 int pixel_sum = 0;
15
2/2
✓ Branch 0 taken 3715800 times.
✓ Branch 1 taken 1238600 times.
4954400 for (int ki = -1; ki <= 1; ++ki) {
16
2/2
✓ Branch 0 taken 11147400 times.
✓ Branch 1 taken 3715800 times.
14863200 for (int kj = -1; kj <= 1; ++kj) {
17 int weight = 0;
18
2/2
✓ Branch 0 taken 9908800 times.
✓ Branch 1 taken 1238600 times.
11147400 if (ki == 0 && kj == 0) {
19 weight = 4;
20
2/2
✓ Branch 0 taken 4954400 times.
✓ Branch 1 taken 4954400 times.
9908800 } else if (ki == 0 || kj == 0) {
21 weight = 2;
22 } else {
23 weight = 1;
24 }
25
26 11147400 int cur_r = std::clamp(r + ki, 0, extended_rows - 1);
27 11147400 int cur_c = std::clamp(c + kj, 0, stolbci - 1);
28 11147400 size_t idx = (static_cast<size_t>(cur_r) * static_cast<size_t>(stolbci)) + static_cast<size_t>(cur_c);
29 11147400 pixel_sum += data[idx] * weight;
30 }
31 }
32 1238600 return pixel_sum / 16;
33 }
34
35 10 void ChernykhSYadroGaussaHorizontalMPI::GaussFilter(const std::vector<int> &local_data, std::vector<int> &local_res,
36 int stroki_local, int stolbci, int halo_top) {
37 10 int extended_rows = static_cast<int>(local_data.size() / static_cast<size_t>(stolbci));
38
2/2
✓ Branch 0 taken 1914 times.
✓ Branch 1 taken 10 times.
1924 for (int i = 0; i < stroki_local; ++i) {
39
2/2
✓ Branch 0 taken 1238600 times.
✓ Branch 1 taken 1914 times.
1240514 for (int j = 0; j < stolbci; ++j) {
40 1238600 size_t res_idx = (static_cast<size_t>(i) * static_cast<size_t>(stolbci)) + static_cast<size_t>(j);
41 1238600 local_res[res_idx] = CalculateGauss(local_data, i + halo_top, j, stolbci, extended_rows);
42 }
43 }
44 10 }
45
46
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 ChernykhSYadroGaussaHorizontalMPI::ChernykhSYadroGaussaHorizontalMPI(const InType &in) {
47 SetTypeOfTask(GetStaticTypeOfTask());
48 10 GetInput() = InType(in);
49 10 GetOutput() = std::vector<int>();
50 10 }
51
52 10 bool ChernykhSYadroGaussaHorizontalMPI::ValidationImpl() {
53 10 int stolbci = std::get<0>(GetInput());
54 10 int stroki = std::get<1>(GetInput());
55 auto &input = std::get<2>(GetInput());
56
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 return stolbci > 0 && stroki > 0 && input.size() == static_cast<size_t>(stroki) * static_cast<size_t>(stolbci);
57 }
58
59 10 bool ChernykhSYadroGaussaHorizontalMPI::PreProcessingImpl() {
60 10 return true;
61 }
62
63 10 bool ChernykhSYadroGaussaHorizontalMPI::RunImpl() {
64 10 int rank = 0;
65 10 int size = 0;
66 10 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
67 10 MPI_Comm_size(MPI_COMM_WORLD, &size);
68
69 10 int stolbci = 0;
70 10 int stroki = 0;
71
72
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
73 5 stolbci = std::get<0>(GetInput());
74 5 stroki = std::get<1>(GetInput());
75 }
76
77 10 MPI_Bcast(&stolbci, 1, MPI_INT, 0, MPI_COMM_WORLD);
78 10 MPI_Bcast(&stroki, 1, MPI_INT, 0, MPI_COMM_WORLD);
79
80 10 std::vector<int> strok_na_process(size, 0);
81
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> offset(size, 0);
82 int current_offset = 0;
83
84
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int i = 0; i < size; ++i) {
85
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 int count = (stroki / size) + (i < (stroki % size) ? 1 : 0);
86 20 strok_na_process[i] = count;
87 20 offset[i] = current_offset;
88 20 current_offset += count;
89 }
90
91
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> sendcounts(size, 0);
92
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> new_start(size, 0);
93
94
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int i = 0; i < size; ++i) {
95
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 int start_row = offset[i];
96 20 int count_rows = strok_na_process[i];
97
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 int h_top = (start_row > 0) ? 1 : 0;
98
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 int h_bot = ((start_row + count_rows) < stroki) ? 1 : 0;
99 20 sendcounts[i] = (count_rows + h_top + h_bot) * stolbci;
100 20 new_start[i] = (start_row - h_top) * stolbci;
101 }
102
103
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 int local_rows = strok_na_process[rank];
104
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 int halo_top = (offset[rank] > 0) ? 1 : 0;
105
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 int halo_bot = ((offset[rank] + local_rows) < stroki) ? 1 : 0;
106 10 int extended_rows = local_rows + halo_top + halo_bot;
107
108
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> local_data(static_cast<size_t>(extended_rows) * static_cast<size_t>(stolbci));
109
110 const int *data_to_send = nullptr;
111 int *send_counts_ptr = nullptr;
112 int *new_start_ptr = nullptr;
113
114
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
115 data_to_send = std::get<2>(GetInput()).data();
116 send_counts_ptr = sendcounts.data();
117 new_start_ptr = new_start.data();
118 }
119
120
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(data_to_send, send_counts_ptr, new_start_ptr, MPI_INT, local_data.data(), extended_rows * stolbci,
121 MPI_INT, 0, MPI_COMM_WORLD);
122
123
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> local_res(static_cast<size_t>(local_rows) * static_cast<size_t>(stolbci));
124 10 GaussFilter(local_data, local_res, local_rows, stolbci, halo_top);
125
126 int *final_output_ptr = nullptr;
127
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> recvcounts(size, 0);
128
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> recvdispls(size, 0);
129 int *recvcounts_ptr = nullptr;
130 int *recvdispls_ptr = nullptr;
131
132
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
133
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 GetOutput().resize(static_cast<size_t>(stolbci) * static_cast<size_t>(stroki));
134 final_output_ptr = GetOutput().data();
135
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5 times.
15 for (int i = 0; i < size; ++i) {
136 10 recvcounts[i] = strok_na_process[i] * stolbci;
137 10 recvdispls[i] = offset[i] * stolbci;
138 }
139 recvcounts_ptr = recvcounts.data();
140 recvdispls_ptr = recvdispls.data();
141 }
142
143
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Gatherv(local_res.data(), local_rows * stolbci, MPI_INT, final_output_ptr, recvcounts_ptr, recvdispls_ptr,
144 MPI_INT, 0, MPI_COMM_WORLD);
145
146 10 return true;
147 }
148
149 10 bool ChernykhSYadroGaussaHorizontalMPI::PostProcessingImpl() {
150 10 return true;
151 }
152 } // namespace chernykh_s_yadro_gaussa_horizontal
153