GCC Code Coverage Report


Directory: ./
File: tasks/ermakov_a_numb_viol_elem_vec/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 64 64 100.0%
Functions: 8 8 100.0%
Branches: 42 52 80.8%

Line Branch Exec Source
1 #include "ermakov_a_numb_viol_elem_vec/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <vector>
7
8 #include "ermakov_a_numb_viol_elem_vec/common/include/common.hpp"
9
10 namespace ermakov_a_numb_viol_elem_vec {
11
12 namespace {
13
14 16 void ComputeBlocks(int total_size, int world_size, std::vector<int> &counts, std::vector<int> &displs) {
15 16 counts.resize(world_size);
16 16 displs.resize(world_size);
17
18 16 const int base = total_size / world_size;
19 16 const int rem = total_size % world_size;
20
21 int shift = 0;
22
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (int rank = 0; rank < world_size; ++rank) {
23
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 14 times.
50 counts[rank] = base + (rank < rem ? 1 : 0); // ? : чтобы прошел clang-tidy
24 32 displs[rank] = shift;
25 32 shift += counts[rank];
26 }
27 16 }
28
29 16 void ScatterData(const std::vector<int> &input, std::vector<int> &local, const std::vector<int> &counts,
30 const std::vector<int> &displs, int rank) {
31 16 int world_size = 0;
32 16 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
33
34
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if (counts[rank] == 0) {
35 1 return;
36 }
37
38
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 7 times.
15 if (rank == 0) {
39
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for (int dest = 1; dest < world_size; ++dest) {
40
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (counts[dest] > 0) {
41 7 MPI_Send(input.data() + displs[dest], counts[dest], MPI_INT, dest, 0, MPI_COMM_WORLD);
42 }
43 }
44 8 local.assign(input.begin(), input.begin() + counts[0]);
45 } else {
46 7 MPI_Recv(local.data(), counts[rank], MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
47 }
48 }
49
50 int CountLocalViolations(const std::vector<int> &local) {
51 int count = 0;
52
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 for (std::size_t i = 0; i + 1 < local.size(); ++i) {
53
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (local[i] > local[i + 1]) {
54 16 ++count;
55 }
56 }
57 return count;
58 }
59
60
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 int CheckBoundaryViolation(const std::vector<int> &local, const std::vector<int> &counts, int rank, int world_size) {
61
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if (local.empty()) {
62 return 0;
63 }
64
65 15 int left_last_value = 0;
66 15 const int my_last_value = local.back();
67
68
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 8 times.
15 if (rank > 0) {
69 7 MPI_Recv(&left_last_value, 1, MPI_INT, rank - 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
70 }
71
72
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1 times.
15 if (rank + 1 < world_size && counts[rank + 1] > 0) {
73 7 MPI_Send(&my_last_value, 1, MPI_INT, rank + 1, 1, MPI_COMM_WORLD);
74 }
75
76
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 2 times.
15 if (rank > 0 && left_last_value > local.front()) {
77 return 1;
78 }
79
80 return 0;
81 }
82
83 } // namespace
84
85
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 ErmakovANumbViolElemVecMPI::ErmakovANumbViolElemVecMPI(const InType &in) {
86 SetTypeOfTask(GetStaticTypeOfTask());
87
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 GetInput() = in;
88 18 GetOutput() = 0;
89 18 }
90
91 18 bool ErmakovANumbViolElemVecMPI::ValidationImpl() {
92 18 return true;
93 }
94 18 bool ErmakovANumbViolElemVecMPI::PreProcessingImpl() {
95 18 return true;
96 }
97
98 18 bool ErmakovANumbViolElemVecMPI::RunImpl() {
99 18 int rank = 0;
100 18 int world_size = 0;
101
102 18 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
103 18 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
104
105 const auto &input = GetInput();
106 18 int n = static_cast<int>(input.size());
107
108 18 MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
109
110
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 if (n == 0) {
111 2 GetOutput() = 0;
112 2 return true;
113 }
114
115 16 std::vector<int> counts;
116 16 std::vector<int> displs;
117
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 ComputeBlocks(n, world_size, counts, displs);
118
119
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 std::vector<int> local(counts[rank]);
120
121
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 ScatterData(input, local, counts, displs, rank);
122
123 const int local_viol = CountLocalViolations(local);
124
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 const int border_viol = CheckBoundaryViolation(local, counts, rank, world_size);
125
126 16 const int local_sum = local_viol + border_viol;
127
128 16 int res = 0;
129
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Reduce(&local_sum, &res, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
130
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Bcast(&res, 1, MPI_INT, 0, MPI_COMM_WORLD);
131
132
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1 times.
16 GetOutput() = res;
133 return true;
134 }
135
136 18 bool ErmakovANumbViolElemVecMPI::PostProcessingImpl() {
137 18 return true;
138 }
139
140 } // namespace ermakov_a_numb_viol_elem_vec
141