GCC Code Coverage Report


Directory: ./
File: tasks/shkenev_i_diff_betw_neighb_elem_vec/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 0 72 0.0%
Functions: 0 8 0.0%
Branches: 0 60 0.0%

Line Branch Exec Source
1 #include "shkenev_i_diff_betw_neighb_elem_vec/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <vector>
9
10 #include "shkenev_i_diff_betw_neighb_elem_vec/common/include/common.hpp"
11
12 namespace shkenev_i_diff_betw_neighb_elem_vec {
13
14 namespace {
15
16 int HandleSmallVector(const std::vector<int> &vec, int n) {
17 int result = 0;
18 for (int i = 0; i < n - 1; ++i) {
19 int diff = std::abs(vec[i + 1] - vec[i]);
20 result = std::max(result, diff);
21 }
22 return result;
23 }
24
25 void ComputeCountsAndDispls(int n, int world_size, std::vector<int> &cnt, std::vector<int> &disp) {
26 int base_size = n / world_size;
27 int rem = n % world_size;
28
29 int shift = 0;
30 for (int i = 0; i < world_size; ++i) {
31 cnt[i] = base_size + (i < rem ? 1 : 0);
32 disp[i] = shift;
33 shift += cnt[i];
34 }
35 }
36
37 void ScatterData(const std::vector<int> &vec, const std::vector<int> &cnt, const std::vector<int> &disp,
38 std::vector<int> &l_vec, int world_rank) {
39 size_t l_n = cnt[world_rank];
40
41 if (world_rank == 0) {
42 if (l_n > 0) {
43 for (size_t i = 0; i < l_n; ++i) {
44 l_vec[i] = vec[i];
45 }
46 }
47
48 for (size_t proc = 1; proc < cnt.size(); ++proc) {
49 if (cnt[proc] > 0) {
50 MPI_Send(vec.data() + disp[proc], cnt[proc], MPI_INT, static_cast<int>(proc), 0, MPI_COMM_WORLD);
51 }
52 }
53 } else {
54 if (l_n > 0) {
55 MPI_Recv(l_vec.data(), static_cast<int>(l_n), MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
56 }
57 }
58 }
59
60 int LocalCompute(const std::vector<int> &l_vec) {
61 int l_max = 0;
62 int l_n = static_cast<int>(l_vec.size());
63
64 for (int i = 0; i < l_n - 1; ++i) {
65 int diff = std::abs(l_vec[i + 1] - l_vec[i]);
66 l_max = std::max(l_max, diff);
67 }
68
69 return l_max;
70 }
71
72 int BoundaryExchange(const std::vector<int> &l_vec, int world_rank, int world_size) {
73 int l_n = static_cast<int>(l_vec.size());
74 int boundary = 0;
75
76 if (world_rank > 0 && l_n > 0) {
77 int prev_last = 0;
78 MPI_Recv(&prev_last, 1, MPI_INT, world_rank - 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
79 boundary = std::abs(l_vec[0] - prev_last);
80 }
81
82 if (world_rank < world_size - 1 && l_n > 0) {
83 int my_last = l_vec[l_n - 1];
84 MPI_Send(&my_last, 1, MPI_INT, world_rank + 1, 1, MPI_COMM_WORLD);
85 }
86
87 return boundary;
88 }
89 } // namespace
90
91 ShkenevIDiffBetwNeighbElemVecMPI::ShkenevIDiffBetwNeighbElemVecMPI(const InType &in) {
92 SetTypeOfTask(GetStaticTypeOfTask());
93 GetInput() = in;
94 GetOutput() = 0;
95 }
96
97 bool ShkenevIDiffBetwNeighbElemVecMPI::ValidationImpl() {
98 return true;
99 }
100
101 bool ShkenevIDiffBetwNeighbElemVecMPI::PreProcessingImpl() {
102 return true;
103 }
104
105 bool ShkenevIDiffBetwNeighbElemVecMPI::RunImpl() {
106 int world_rank = 0;
107 int world_size = 0;
108
109 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
110 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
111
112 const std::vector<int> &vec = GetInput();
113 int n = static_cast<int>(vec.size());
114
115 if (n < 2) {
116 GetOutput() = 0;
117 return true;
118 }
119
120 if (world_size > n) {
121 int result = (world_rank == 0 ? HandleSmallVector(vec, n) : 0);
122 MPI_Bcast(&result, 1, MPI_INT, 0, MPI_COMM_WORLD);
123 GetOutput() = result;
124 return true;
125 }
126
127 std::vector<int> cnt(world_size);
128 std::vector<int> disp(world_size);
129 ComputeCountsAndDispls(n, world_size, cnt, disp);
130
131 std::vector<int> l_vec(cnt[world_rank]);
132 ScatterData(vec, cnt, disp, l_vec, world_rank);
133
134 int local_max = LocalCompute(l_vec);
135 int boundary = BoundaryExchange(l_vec, world_rank, world_size);
136 local_max = std::max(local_max, boundary);
137
138 int global_max = 0;
139 MPI_Reduce(&local_max, &global_max, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
140 MPI_Bcast(&global_max, 1, MPI_INT, 0, MPI_COMM_WORLD);
141
142 GetOutput() = global_max;
143 return true;
144 }
145
146 bool ShkenevIDiffBetwNeighbElemVecMPI::PostProcessingImpl() {
147 return true;
148 }
149
150 } // namespace shkenev_i_diff_betw_neighb_elem_vec
151