GCC Code Coverage Report


Directory: ./
File: tasks/krasavin_a_max_neighbor_diff/mpi/src/ops_mpi.cpp
Date: 2026-02-26 23:37:49
Exec Total Coverage
Lines: 67 72 93.1%
Functions: 8 8 100.0%
Branches: 37 60 61.7%

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