GCC Code Coverage Report


Directory: ./
File: tasks/spichek_d_radix_sort_for_integers_with_simple_merging/all/src/ops_all.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 68 70 97.1%
Functions: 8 8 100.0%
Branches: 43 60 71.7%

Line Branch Exec Source
1 #include "spichek_d_radix_sort_for_integers_with_simple_merging/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <tbb/tbb.h>
5
6 #include <algorithm>
7 #include <iterator>
8 #include <utility>
9 #include <vector>
10
11 #include "spichek_d_radix_sort_for_integers_with_simple_merging/common/include/common.hpp"
12 #include "util/include/util.hpp"
13
14 namespace spichek_d_radix_sort_for_integers_with_simple_merging {
15
16
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 SpichekDRadixSortALL::SpichekDRadixSortALL(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 GetInput() = in;
19 30 }
20
21 30 bool SpichekDRadixSortALL::ValidationImpl() {
22 30 int rank = 0;
23 30 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
24
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
25 15 return !GetInput().empty();
26 }
27 return true;
28 }
29
30 30 bool SpichekDRadixSortALL::PreProcessingImpl() {
31 30 int rank = 0;
32 30 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
33
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
34 15 GetOutput() = GetInput();
35 }
36 30 return true;
37 }
38
39 30 bool SpichekDRadixSortALL::RunImpl() {
40 30 int rank = 0;
41 30 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
42
43
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
30 if (rank == 0 && !GetOutput().empty()) {
44 15 int num_threads = ppc::util::GetNumThreads();
45 15 int n = static_cast<int>(GetOutput().size());
46
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (num_threads <= 1 || n < num_threads) {
48 RadixSort(GetOutput());
49 } else {
50 15 std::vector<std::vector<int>> local_data = SplitData(GetOutput(), num_threads);
51
52
1/2
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
45 tbb::parallel_for(0, num_threads, [&](int i) { RadixSort(local_data[i]); });
53
54
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 GetOutput() = MergeData(local_data);
55 15 }
56 }
57
58 30 MPI_Barrier(MPI_COMM_WORLD);
59 30 return true;
60 }
61
62 30 bool SpichekDRadixSortALL::PostProcessingImpl() {
63 30 int rank = 0;
64 30 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
65
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
66 return std::ranges::is_sorted(GetOutput());
67 }
68 return true;
69 }
70
71 15 std::vector<std::vector<int>> SpichekDRadixSortALL::SplitData(const std::vector<int> &data, int num_parts) {
72 15 int n = static_cast<int>(data.size());
73 15 std::vector<std::vector<int>> parts(num_parts);
74 15 int base_size = n / num_parts;
75 15 int remainder = n % num_parts;
76 int offset = 0;
77
78
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15 times.
45 for (int i = 0; i < num_parts; ++i) {
79
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
60 int current_size = base_size + (i < remainder ? 1 : 0);
80
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 parts[i] = std::vector<int>(data.begin() + offset, data.begin() + offset + current_size);
81 30 offset += current_size;
82 }
83 15 return parts;
84 }
85
86 15 std::vector<int> SpichekDRadixSortALL::MergeData(std::vector<std::vector<int>> &parts) {
87 std::vector<int> result = std::move(parts[0]);
88 15 int num_parts = static_cast<int>(parts.size());
89
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 for (int i = 1; i < num_parts; ++i) {
90
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 std::vector<int> temp;
91
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 temp.reserve(result.size() + parts[i].size());
92
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 std::ranges::merge(result, parts[i], std::back_inserter(temp));
93 result = std::move(temp);
94 }
95 15 return result;
96 }
97
98
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 void SpichekDRadixSortALL::RadixSort(std::vector<int> &data) {
99
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (data.empty()) {
100 return;
101 }
102
103 30 int min_val = *std::ranges::min_element(data);
104
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 if (min_val < 0) {
105
2/2
✓ Branch 0 taken 21300 times.
✓ Branch 1 taken 20 times.
21320 for (auto &x : data) {
106 21300 x -= min_val;
107 }
108 }
109
110 30 int max_val = *std::ranges::max_element(data);
111
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 30 times.
84 for (int shift = 0; (max_val >> shift) > 0; shift += 8) {
112 54 std::vector<int> output(data.size());
113
1/4
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
54 std::vector<int> count(256, 0);
114
115
2/2
✓ Branch 0 taken 54900 times.
✓ Branch 1 taken 54 times.
54954 for (int x : data) {
116 54900 count[(x >> shift) & 255]++;
117 }
118
2/2
✓ Branch 0 taken 13770 times.
✓ Branch 1 taken 54 times.
13824 for (int i = 1; i < 256; i++) {
119 13770 count[i] += count[i - 1];
120 }
121
2/2
✓ Branch 0 taken 54900 times.
✓ Branch 1 taken 54 times.
54954 for (int i = static_cast<int>(data.size()) - 1; i >= 0; i--) {
122 54900 output[count[(data[i] >> shift) & 255] - 1] = data[i];
123 54900 count[(data[i] >> shift) & 255]--;
124 }
125 data = std::move(output);
126 }
127
128
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 if (min_val < 0) {
129
2/2
✓ Branch 0 taken 21300 times.
✓ Branch 1 taken 20 times.
21320 for (auto &x : data) {
130 21300 x += min_val;
131 }
132 }
133 }
134
135 } // namespace spichek_d_radix_sort_for_integers_with_simple_merging
136