GCC Code Coverage Report


Directory: ./
File: tasks/dergynov_s_radix_sort_double_simple_merge/mpi/src/ops_mpi.cpp
Date: 2026-02-23 23:20:07
Exec Total Coverage
Lines: 79 79 100.0%
Functions: 7 7 100.0%
Branches: 71 104 68.3%

Line Branch Exec Source
1 #include "dergynov_s_radix_sort_double_simple_merge/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <cstdint>
7 #include <cstring>
8 #include <utility>
9 #include <vector>
10
11 #include "dergynov_s_radix_sort_double_simple_merge/common/include/common.hpp"
12
13 namespace dergynov_s_radix_sort_double_simple_merge {
14 namespace {
15
16
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 10 times.
14 void RadixSortDoubles(std::vector<double> &data) {
17
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 10 times.
14 if (data.size() <= 1) {
18 4 return;
19 }
20
21 10 std::vector<uint64_t> keys(data.size());
22
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 10 times.
42 for (size_t i = 0; i < data.size(); ++i) {
23
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 23 times.
64 keys[i] = DoubleToSortableUint64(data[i]);
24 }
25
26 const int k_radix = 256;
27
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<uint64_t> temp(data.size());
28
29
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 10 times.
90 for (int shift = 0; shift < 64; shift += 8) {
30
1/4
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
80 std::vector<size_t> count(k_radix + 1, 0);
31
32
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 80 times.
336 for (uint64_t key : keys) {
33 256 uint8_t digit = (key >> shift) & 0xFF;
34 256 ++count[digit + 1];
35 }
36
37
2/2
✓ Branch 0 taken 20480 times.
✓ Branch 1 taken 80 times.
20560 for (int i = 0; i < k_radix; ++i) {
38 20480 count[i + 1] += count[i];
39 }
40
41
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 80 times.
336 for (uint64_t key : keys) {
42 256 uint8_t digit = (key >> shift) & 0xFF;
43 256 size_t pos = count[digit];
44 256 temp[pos] = key;
45 256 ++count[digit];
46 }
47
48 keys.swap(temp);
49 }
50
51
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 10 times.
42 for (size_t i = 0; i < data.size(); ++i) {
52
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 9 times.
64 data[i] = SortableUint64ToDouble(keys[i]);
53 }
54 }
55
56 7 std::vector<double> MergeSorted(const std::vector<double> &a, const std::vector<double> &b) {
57
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 std::vector<double> result;
58
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 result.reserve(a.size() + b.size());
59 size_t i = 0;
60 size_t j = 0;
61
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 18 times.
25 while (i < a.size() && j < b.size()) {
62
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 10 times.
18 if (a[i] < b[j]) {
63
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 result.push_back(a[i++]);
64 } else {
65
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 result.push_back(b[j++]);
66 }
67 }
68
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 7 times.
18 while (i < a.size()) {
69
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 result.push_back(a[i++]);
70 }
71
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
11 while (j < b.size()) {
72
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 result.push_back(b[j++]);
73 }
74 7 return result;
75 }
76
77 } // namespace
78
79
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 DergynovSRadixSortDoubleSimpleMergeMPI::DergynovSRadixSortDoubleSimpleMergeMPI(const InType &in) {
80 SetTypeOfTask(GetStaticTypeOfTask());
81
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 GetInput() = in;
82 result_.clear();
83 14 std::get<1>(GetOutput()) = -1;
84 14 }
85
86 14 bool DergynovSRadixSortDoubleSimpleMergeMPI::ValidationImpl() {
87 14 int initialized = 0;
88 14 MPI_Initialized(&initialized);
89 14 return initialized != 0;
90 }
91
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 bool DergynovSRadixSortDoubleSimpleMergeMPI::PreProcessingImpl() {
93 result_.clear();
94 14 return true;
95 }
96
97 14 bool DergynovSRadixSortDoubleSimpleMergeMPI::RunImpl() {
98 14 int rank = 0;
99 14 int size = 0;
100 14 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
101 14 MPI_Comm_size(MPI_COMM_WORLD, &size);
102
103 const auto &input = GetInput();
104 14 int n = static_cast<int>(input.size());
105
106 14 MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
107
108 14 std::vector<int> counts(size);
109
1/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
14 std::vector<int> displs(size);
110
111 14 int base = n / size;
112 14 int rem = n % size;
113 int offset = 0;
114
115
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
42 for (int i = 0; i < size; ++i) {
116
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
46 counts[i] = base + (i < rem ? 1 : 0);
117 28 displs[i] = offset;
118 28 offset += counts[i];
119 }
120
121
1/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
14 std::vector<double> local_data(counts[rank]);
122
123
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
21 MPI_Scatterv(rank == 0 ? input.data() : nullptr, counts.data(), displs.data(), MPI_DOUBLE, local_data.data(),
124
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 counts[rank], MPI_DOUBLE, 0, MPI_COMM_WORLD);
125
126
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 RadixSortDoubles(local_data);
127
128
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (rank == 0) {
129 7 result_ = std::move(local_data);
130
131
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for (int proc = 1; proc < size; ++proc) {
132 7 int recv_count = 0;
133
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 MPI_Recv(&recv_count, 1, MPI_INT, proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
134
1/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
7 std::vector<double> part(recv_count);
135
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 MPI_Recv(part.data(), recv_count, MPI_DOUBLE, proc, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
136
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
14 result_ = MergeSorted(result_, part);
137 }
138 } else {
139 7 int send_count = static_cast<int>(local_data.size());
140
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 MPI_Send(&send_count, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
141
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 MPI_Send(local_data.data(), send_count, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
142 }
143
144
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 9 times.
14 std::get<1>(GetOutput()) = rank;
145 14 return true;
146 }
147
148
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 bool DergynovSRadixSortDoubleSimpleMergeMPI::PostProcessingImpl() {
149
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 if (!result_.empty()) {
150 6 std::get<0>(GetOutput()) = result_;
151 }
152 14 return true;
153 }
154
155 } // namespace dergynov_s_radix_sort_double_simple_merge
156