GCC Code Coverage Report


Directory: ./
File: tasks/papulina_y_radix_sort/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 68 72 94.4%
Functions: 9 11 81.8%
Branches: 46 92 50.0%

Line Branch Exec Source
1 #include "papulina_y_radix_sort/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/tbb.h>
4
5 #include <algorithm>
6 #include <array>
7 #include <cmath>
8 #include <cstddef>
9 #include <cstdint>
10 #include <cstring>
11 #include <vector>
12
13 #include "oneapi/tbb/parallel_for.h"
14 #include "papulina_y_radix_sort/common/include/common.hpp"
15
16 namespace papulina_y_radix_sort {
17
18
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 PapulinaYRadixSortTBB::PapulinaYRadixSortTBB(const InType &in) {
19 SetTypeOfTask(GetStaticTypeOfTask());
20
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 GetInput() = in;
21 28 GetOutput() = std::vector<double>();
22 28 }
23
24 28 bool PapulinaYRadixSortTBB::ValidationImpl() {
25 28 return true;
26 }
27
28 28 bool PapulinaYRadixSortTBB::PreProcessingImpl() {
29 28 return true;
30 }
31
32 28 bool PapulinaYRadixSortTBB::RunImpl() {
33 double *result = GetInput().data();
34 size_t size = GetInput().size();
35
36 28 ParallelRadixSort(result, static_cast<int>(size));
37
38 28 GetOutput() = std::vector<double>(size);
39
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 28 times.
228 for (size_t i = 0; i < size; i++) {
40 200 GetOutput()[i] = result[i];
41 }
42 28 return true;
43 }
44
45 28 bool PapulinaYRadixSortTBB::PostProcessingImpl() {
46 28 return true;
47 }
48 uint64_t PapulinaYRadixSortTBB::InBytes(double d) {
49 uint64_t bits = 0;
50 memcpy(&bits, &d, sizeof(double));
51
2/6
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
200 if ((bits & kMask) != 0) {
52 40 bits = ~bits;
53 } else {
54 160 bits = bits ^ kMask;
55 }
56 return bits;
57 }
58 double PapulinaYRadixSortTBB::FromBytes(uint64_t bits) {
59 double d = NAN;
60
2/6
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
200 if ((bits & kMask) != 0) {
61 160 bits = bits ^ kMask;
62 } else {
63 40 bits = ~bits;
64 }
65 memcpy(&d, &bits, sizeof(double));
66 return d;
67 }
68 224 void PapulinaYRadixSortTBB::ParallelSortByByte(uint64_t *bytes, uint64_t *out, int byte, int size) {
69 224 auto *byte_view = reinterpret_cast<unsigned char *>(bytes);
70 224 int block_size = 2048;
71
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (size <= 100) {
72 224 block_size = 4;
73 }
74 224 const int num_blocks = (size + block_size - 1) / block_size;
75
76 224 std::vector<std::array<int, 256>> local_counts(num_blocks, std::array<int, 256>{0});
77
1/4
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
224 std::vector<std::array<int, 256>> local_offsets(num_blocks, std::array<int, 256>{0});
78
79
1/2
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
224 tbb::parallel_for(0, num_blocks, [&](int b) {
80 512 int start = b * block_size;
81
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 288 times.
512 int end = std::min(start + block_size, size);
82
2/2
✓ Branch 0 taken 1600 times.
✓ Branch 1 taken 512 times.
2112 for (int i = start; i < end; ++i) {
83 1600 int index = byte_view[(8 * i) + byte];
84 1600 local_counts[b].at(index)++;
85 }
86 512 });
87
88 int total = 0;
89
2/2
✓ Branch 0 taken 57344 times.
✓ Branch 1 taken 224 times.
57568 for (int j = 0; j < 256; ++j) {
90
2/2
✓ Branch 0 taken 131072 times.
✓ Branch 1 taken 57344 times.
188416 for (int block = 0; block < num_blocks; ++block) {
91 131072 local_offsets[block].at(j) = total;
92 131072 total += local_counts[block].at(j);
93 }
94 }
95
96
2/6
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 224 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
224 tbb::parallel_for(0, num_blocks, [&](int b) {
97 512 int start = b * block_size;
98
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 288 times.
512 int end = std::min(start + block_size, size);
99
2/2
✓ Branch 0 taken 1600 times.
✓ Branch 1 taken 512 times.
2112 for (int i = start; i < end; ++i) {
100 1600 int index = byte_view[(8 * i) + byte];
101 1600 int pos = local_offsets[b].at(index)++;
102 1600 out[pos] = bytes[i];
103 }
104 512 });
105 224 }
106 28 void PapulinaYRadixSortTBB::ParallelRadixSort(double *arr, int size) {
107 28 std::vector<uint64_t> bytes(size);
108
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
28 std::vector<uint64_t> out(size);
109
110
2/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
28 tbb::parallel_for(tbb::blocked_range<int>(0, size), [&](const tbb::blocked_range<int> &range) {
111
2/4
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
400 for (int i = range.begin(); i != range.end(); ++i) {
112
2/4
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
400 bytes[i] = InBytes(arr[i]);
113 }
114 });
115
116
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(bytes.data(), out.data(), 0, size);
117
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(out.data(), bytes.data(), 1, size);
118
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(bytes.data(), out.data(), 2, size);
119
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(out.data(), bytes.data(), 3, size);
120
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(bytes.data(), out.data(), 4, size);
121
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(out.data(), bytes.data(), 5, size);
122
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(bytes.data(), out.data(), 6, size);
123
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParallelSortByByte(out.data(), bytes.data(), 7, size);
124
125
2/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
28 tbb::parallel_for(tbb::blocked_range<int>(0, size), [&](const tbb::blocked_range<int> &range) {
126
2/4
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
400 for (int i = range.begin(); i != range.end(); ++i) {
127
2/4
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
400 arr[i] = FromBytes(bytes[i]);
128 }
129 });
130 28 }
131 } // namespace papulina_y_radix_sort
132