GCC Code Coverage Report


Directory: ./
File: tasks/rozenberg_a_radix_simple_merge/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 72 72 100.0%
Functions: 7 7 100.0%
Branches: 51 70 72.9%

Line Branch Exec Source
1 #include "rozenberg_a_radix_simple_merge/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <array>
7 #include <cstddef>
8 #include <cstdint>
9 #include <cstring>
10 #include <utility>
11 #include <vector>
12
13 #include "rozenberg_a_radix_simple_merge/common/include/common.hpp"
14
15 namespace rozenberg_a_radix_simple_merge {
16
17
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23 times.
24 void RozenbergARadixSimpleMergeMPI::LocalRadixSort(InType &data) {
18
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23 times.
24 if (data.empty()) {
19 1 return;
20 }
21 size_t n = data.size();
22 23 InType buffer(n);
23
24
2/2
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 23 times.
207 for (int shift = 0; shift < 64; shift += 8) {
25 184 std::array<size_t, 256> count = {0};
26
27
4/4
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 2200 times.
✓ Branch 2 taken 2776 times.
✓ Branch 3 taken 184 times.
2960 for (double val : data) {
28 uint64_t u = 0;
29 std::memcpy(&u, &val, sizeof(double));
30
31
2/2
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 2200 times.
2776 u = (u >> 63 != 0U) ? ~u : (u ^ 0x8000000000000000);
32
33 2776 auto byte = static_cast<uint8_t>((u >> shift) & 0xFF);
34 2776 count.at(byte)++;
35 }
36
37
2/2
✓ Branch 0 taken 46920 times.
✓ Branch 1 taken 184 times.
47104 for (int i = 1; i < 256; ++i) {
38 46920 count.at(i) += count.at(i - 1);
39 }
40
41
2/2
✓ Branch 0 taken 2776 times.
✓ Branch 1 taken 184 times.
2960 for (int i = static_cast<int>(n) - 1; i >= 0; --i) {
42 uint64_t u = 0;
43
2/2
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 2200 times.
2776 std::memcpy(&u, &data[i], 8);
44
45
2/2
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 2200 times.
2776 u = (u >> 63 != 0U) ? ~u : (u ^ 0x8000000000000000);
46
47 2776 auto byte = static_cast<uint8_t>((u >> shift) & 0xFF);
48 2776 buffer[--count.at(byte)] = data[i];
49 }
50
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 data = buffer;
51 }
52 }
53
54 24 void RozenbergARadixSimpleMergeMPI::ExchangeAndMerge(InType &local_buf, int rank, int size) {
55
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 for (int step = 1; step < size; step *= 2) {
56
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (rank % (2 * step) == 0) {
57 12 int neighbor = rank + step;
58
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (neighbor < size) {
59 12 int neighbor_size = 0;
60 12 MPI_Recv(&neighbor_size, 1, MPI_INT, neighbor, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
61
62 12 std::vector<double> neighbor_data(neighbor_size);
63
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Recv(neighbor_data.data(), neighbor_size, MPI_DOUBLE, neighbor, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
64
65
1/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
12 InType merged(local_buf.size() + neighbor_size);
66 12 std::ranges::merge(local_buf, neighbor_data, merged.begin());
67 local_buf = std::move(merged);
68 }
69 } else {
70 12 int target = rank - step;
71 12 int my_size = static_cast<int>(local_buf.size());
72 12 MPI_Send(&my_size, 1, MPI_INT, target, 0, MPI_COMM_WORLD);
73 12 MPI_Send(local_buf.data(), my_size, MPI_DOUBLE, target, 0, MPI_COMM_WORLD);
74 local_buf.clear();
75 break;
76 }
77 }
78 24 }
79
80 24 RozenbergARadixSimpleMergeMPI::RozenbergARadixSimpleMergeMPI(const InType &in) {
81 SetTypeOfTask(GetStaticTypeOfTask());
82
83 InType empty;
84 GetInput().swap(empty);
85
86
2/2
✓ Branch 0 taken 347 times.
✓ Branch 1 taken 24 times.
371 for (const auto &elem : in) {
87 GetInput().push_back(elem);
88 }
89
90 GetOutput().clear();
91 24 }
92
93 24 bool RozenbergARadixSimpleMergeMPI::ValidationImpl() {
94 24 int rank = 0;
95 24 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
96
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (rank == 0) {
97
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 return (!(GetInput().empty())) && (GetOutput().empty());
98 }
99 return true;
100 }
101
102 24 bool RozenbergARadixSimpleMergeMPI::PreProcessingImpl() {
103 24 int rank = 0;
104 24 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
105
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (rank == 0) {
106 12 GetOutput().resize(GetInput().size());
107 }
108 24 return true;
109 }
110
111 24 bool RozenbergARadixSimpleMergeMPI::RunImpl() {
112 24 int rank = 0;
113 24 int size = 0;
114 24 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
115 24 MPI_Comm_size(MPI_COMM_WORLD, &size);
116
117 24 int n = 0;
118
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (rank == 0) {
119 12 n = static_cast<int>(GetInput().size());
120 }
121 24 MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
122
123 24 std::vector<int> sendcounts(size);
124
1/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
24 std::vector<int> displs(size);
125
126 int sum = 0;
127
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
72 for (int i = 0; i < size; i++) {
128
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 14 times.
82 sendcounts[i] = (n / size) + (i < (n % size) ? 1 : 0);
129 48 displs[i] = sum;
130 48 sum += sendcounts[i];
131 }
132
133
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 int chunk = sendcounts[rank];
134
2/6
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 InType local_buf(static_cast<size_t>(chunk));
135
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 MPI_Scatterv(GetInput().data(), sendcounts.data(), displs.data(), MPI_DOUBLE, local_buf.data(), chunk, MPI_DOUBLE, 0,
136 MPI_COMM_WORLD);
137
138
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 LocalRadixSort(local_buf);
139
140
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 ExchangeAndMerge(local_buf, rank, size);
141
142
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (rank == 0) {
143 GetOutput() = std::move(local_buf);
144 }
145 24 return true;
146 }
147
148 24 bool RozenbergARadixSimpleMergeMPI::PostProcessingImpl() {
149 24 return true;
150 }
151
152 } // namespace rozenberg_a_radix_simple_merge
153