GCC Code Coverage Report


Directory: ./
File: tasks/goriacheva_k_violation_order_elem_vec/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 59 61 96.7%
Functions: 7 8 87.5%
Branches: 35 52 67.3%

Line Branch Exec Source
1 #include "goriacheva_k_violation_order_elem_vec/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "goriacheva_k_violation_order_elem_vec/common/include/common.hpp"
10
11 namespace goriacheva_k_violation_order_elem_vec {
12
13
1/2
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
76 GoriachevaKViolationOrderElemVecMPI::GoriachevaKViolationOrderElemVecMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15
1/2
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
76 GetInput() = in;
16 76 GetOutput() = 0;
17 76 }
18
19 76 bool GoriachevaKViolationOrderElemVecMPI::ValidationImpl() {
20 76 return true;
21 }
22
23 76 bool GoriachevaKViolationOrderElemVecMPI::PreProcessingImpl() {
24 76 input_vec_ = GetInput();
25 76 result_ = 0;
26 76 return true;
27 }
28
29 68 void GoriachevaKViolationOrderElemVecMPI::ScatterInput(int rank, int size, int n, std::vector<int> &local) const {
30 68 const int base = n / size;
31
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 34 times.
68 const int rem = n % size;
32 68 const int local_size = static_cast<int>(local.size());
33
34
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 34 times.
68 if (rank == 0) {
35
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 if (local_size > 0) {
36 34 std::copy(input_vec_.begin(), input_vec_.begin() + local_size, local.begin());
37 }
38
39
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 34 times.
68 for (int rank_iter = 1; rank_iter < size; ++rank_iter) {
40
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 const int sz = base + (rank_iter < rem ? 1 : 0);
41
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 if (sz > 0) {
42 34 const int offset = (rank_iter * base) + std::min(rank_iter, rem);
43 34 MPI_Send(input_vec_.data() + offset, sz, MPI_INT, rank_iter, 0, MPI_COMM_WORLD);
44 }
45 }
46
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 } else if (local_size > 0) {
47 34 MPI_Recv(local.data(), local_size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
48 }
49 68 }
50
51 int GoriachevaKViolationOrderElemVecMPI::CountLocalViolations(const std::vector<int> &local) {
52 int count = 0;
53
2/4
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
195 for (std::size_t i = 0; i + 1 < local.size(); ++i) {
54
2/4
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
127 if (local[i] > local[i + 1]) {
55 46 ++count;
56 }
57 }
58 return count;
59 }
60
61 68 int GoriachevaKViolationOrderElemVecMPI::CheckBoundaryViolation(int rank, int size, const std::vector<int> &local) {
62 68 int send_val = 0;
63
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 int left_last = 0;
64
65
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 if (!local.empty()) {
66 68 send_val = local.back();
67 }
68
69
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 34 times.
102 MPI_Sendrecv(&send_val, 1, MPI_INT, (rank + 1 < size) ? rank + 1 : MPI_PROC_NULL, 1, &left_last, 1, MPI_INT,
70 (rank > 0) ? rank - 1 : MPI_PROC_NULL, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
71
72
5/6
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 16 times.
68 if (rank > 0 && !local.empty() && left_last > local.front()) {
73 18 return 1;
74 }
75
76 return 0;
77 }
78
79 76 bool GoriachevaKViolationOrderElemVecMPI::RunImpl() {
80 76 int rank = 0;
81 76 int size = 0;
82 76 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
83 76 MPI_Comm_size(MPI_COMM_WORLD, &size);
84
85 76 int n = static_cast<int>(input_vec_.size());
86 76 MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
87
88
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 68 times.
76 if (n <= 1) {
89 8 result_ = 0;
90 8 MPI_Bcast(&result_, 1, MPI_INT, 0, MPI_COMM_WORLD);
91 8 return true;
92 }
93
94 68 const int base = n / size;
95 68 const int rem = n % size;
96
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 11 times.
68 const int local_size = base + (rank < rem ? 1 : 0);
97
98 68 std::vector<int> local(local_size);
99
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 ScatterInput(rank, size, n, local);
100
101 68 int local_count = CountLocalViolations(local);
102
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 local_count += CheckBoundaryViolation(rank, size, local);
103
104
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 MPI_Reduce(&local_count, &result_, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
105
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 MPI_Bcast(&result_, 1, MPI_INT, 0, MPI_COMM_WORLD);
106
107 return true;
108 }
109
110 76 bool GoriachevaKViolationOrderElemVecMPI::PostProcessingImpl() {
111 76 GetOutput() = result_;
112 76 return true;
113 }
114
115 } // namespace goriacheva_k_violation_order_elem_vec
116