GCC Code Coverage Report


Directory: ./
File: tasks/belov_e_bubble_sort/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 78 81 96.3%
Functions: 12 12 100.0%
Branches: 55 104 52.9%

Line Branch Exec Source
1 #include "belov_e_bubble_sort/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <iterator>
8 #include <utility>
9 #include <vector>
10
11 #include "belov_e_bubble_sort/common/include/common.hpp"
12
13 namespace belov_e_bubble_sort {
14
15
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 BelovEBubbleSortMPI::BelovEBubbleSortMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 GetInput() = in;
18 6 }
19
20 6 bool BelovEBubbleSortMPI::ValidationImpl() {
21 6 return !GetInput().empty();
22 }
23
24 6 bool BelovEBubbleSortMPI::PreProcessingImpl() {
25 6 return true;
26 }
27
28 6 void BubbleSort(std::vector<int> &arr) {
29 const std::size_t n = arr.size();
30
2/2
✓ Branch 0 taken 5019 times.
✓ Branch 1 taken 6 times.
5025 for (std::size_t i = 0; i < n; ++i) {
31
2/2
✓ Branch 0 taken 6247551 times.
✓ Branch 1 taken 5019 times.
6252570 for (std::size_t j = 0; j + 1 < n - i; ++j) {
32
1/2
✓ Branch 0 taken 6247551 times.
✗ Branch 1 not taken.
6247551 if (arr[j] > arr[j + 1]) {
33 std::swap(arr[j], arr[j + 1]);
34 }
35 }
36 }
37 6 }
38
39 6 std::vector<int> LeftMerge(const std::vector<int> &left, const std::vector<int> &right) {
40
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::vector<int> result;
41
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 result.reserve(left.size() + right.size());
42
43
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::ranges::merge(left, right, std::back_inserter(result));
44
45
2/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
12 return {result.begin(), std::next(result.begin(), static_cast<std::vector<int>::difference_type>(left.size()))};
46 }
47 6 std::vector<int> RightMerge(const std::vector<int> &left, const std::vector<int> &right) {
48
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::vector<int> result;
49
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 result.reserve(left.size() + right.size());
50
51
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::ranges::merge(left, right, std::back_inserter(result));
52
53
2/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
12 return {std::prev(result.end(), static_cast<std::vector<int>::difference_type>(right.size())), result.end()};
54 }
55
56 6 void LeftProcAct(int rank, std::vector<int> &local_arr, int local_arr_size, std::vector<int> &arrays_sizes,
57 MPI_Comm comm) {
58 6 std::vector<int> right_arr;
59
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 right_arr.resize(arrays_sizes[rank + 1]);
60
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Sendrecv(local_arr.data(), local_arr_size, MPI_INT, rank + 1, 0, right_arr.data(), arrays_sizes[rank + 1],
61 MPI_INT, rank + 1, 0, comm, MPI_STATUS_IGNORE);
62
2/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
12 local_arr = LeftMerge(local_arr, right_arr);
63 6 }
64
65 6 void RightProcAct(int rank, std::vector<int> &local_arr, int local_arr_size, std::vector<int> &arrays_sizes,
66 MPI_Comm comm) {
67 6 std::vector<int> left_arr;
68
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 left_arr.resize(arrays_sizes[rank - 1]);
69
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Sendrecv(local_arr.data(), local_arr_size, MPI_INT, rank - 1, 0, left_arr.data(), arrays_sizes[rank - 1], MPI_INT,
70 rank - 1, 0, comm, MPI_STATUS_IGNORE);
71
2/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
12 local_arr = RightMerge(left_arr, local_arr);
72 6 }
73
74 12 void EvenPhase(int rank, int mpi_size, std::vector<int> &local_arr, int local_arr_size, std::vector<int> &arrays_sizes,
75 MPI_Comm comm) {
76
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (mpi_size % 2 != 0 && rank == mpi_size - 1) {
77 return;
78 }
79
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank % 2 == 0) {
80 6 LeftProcAct(rank, local_arr, local_arr_size, arrays_sizes, comm);
81 } else {
82 6 RightProcAct(rank, local_arr, local_arr_size, arrays_sizes, comm);
83 }
84 }
85
86 6 void OddPhase(int rank, int mpi_size, std::vector<int> &local_arr, int local_arr_size, std::vector<int> &arrays_sizes,
87 MPI_Comm comm) {
88
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
89 return;
90 }
91
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if (mpi_size % 2 == 0 && rank == mpi_size - 1) {
92 return;
93 }
94 if (rank % 2 == 0) {
95 RightProcAct(rank, local_arr, local_arr_size, arrays_sizes, comm);
96 } else {
97 LeftProcAct(rank, local_arr, local_arr_size, arrays_sizes, comm);
98 }
99 }
100
101 6 bool BelovEBubbleSortMPI::RunImpl() {
102 6 int mpi_size = 0;
103 6 int rank = 0;
104
105 6 MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
106 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
107
108 6 std::vector<int> arr;
109 6 int n = 0;
110
111
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
112
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 arr = GetInput();
113 3 n = static_cast<int>(arr.size());
114 }
115
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
116
117 int local_arr_size = 0;
118 6 std::vector<int> local_arr;
119 6 int base = n / mpi_size;
120 6 int rem = n % mpi_size;
121
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 local_arr_size = base + (rank < rem ? 1 : 0);
122
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 local_arr.resize(local_arr_size);
123
124 6 std::vector<int> arrays_sizes;
125
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 arrays_sizes.resize(mpi_size);
126
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Allgather(&local_arr_size, 1, MPI_INT, arrays_sizes.data(), 1, MPI_INT, MPI_COMM_WORLD);
127
128 6 std::vector<int> displs;
129
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 displs.resize(mpi_size);
130
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (mpi_size == 0) {
131 return false;
132 }
133 6 displs[0] = 0;
134
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int i = 1; i < mpi_size; i++) {
135 6 displs[i] = displs[i - 1] + arrays_sizes[i - 1];
136 }
137
138
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Scatterv(arr.data(), arrays_sizes.data(), displs.data(), MPI_INT, local_arr.data(), local_arr_size, MPI_INT, 0,
139 MPI_COMM_WORLD);
140
141 6 BubbleSort(local_arr);
142
143
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 for (int i = 0; i < mpi_size + 1; i++) {
144
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 if (i % 2 == 0) {
145
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 EvenPhase(rank, mpi_size, local_arr, local_arr_size, arrays_sizes, MPI_COMM_WORLD);
146 } else {
147
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 OddPhase(rank, mpi_size, local_arr, local_arr_size, arrays_sizes, MPI_COMM_WORLD);
148 }
149 }
150
151
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 arr.resize(n);
152
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Allgatherv(local_arr.data(), local_arr_size, MPI_INT, arr.data(), arrays_sizes.data(), displs.data(), MPI_INT,
153 MPI_COMM_WORLD);
154
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 GetOutput() = arr;
155 return true;
156 }
157
158 6 bool BelovEBubbleSortMPI::PostProcessingImpl() {
159 6 return true;
160 }
161
162 } // namespace belov_e_bubble_sort
163