Skip to content

Commit 4ec8068

Browse files
Merge pull request #447 from apache/fix_bit_packing
Fix bit packing
2 parents fbb78f4 + 6e944cf commit 4ec8068

File tree

2 files changed

+44
-42
lines changed

2 files changed

+44
-42
lines changed

theta/include/bit_packing.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ static inline void pack_bits_13(const uint64_t* values, uint8_t* ptr) {
329329

330330
*ptr++ = static_cast<uint8_t>(values[3] >> 4);
331331

332-
*ptr = static_cast<uint8_t>(values[3] >> 4);
332+
*ptr = static_cast<uint8_t>(values[3] << 4);
333333
*ptr++ |= static_cast<uint8_t>(values[4] >> 9);
334334

335335
*ptr++ = static_cast<uint8_t>(values[4] >> 1);
@@ -4227,7 +4227,7 @@ static inline void unpack_bits_33(uint64_t* values, const uint8_t* ptr) {
42274227
values[6] |= *ptr >> 1;
42284228

42294229
values[7] = static_cast<uint64_t>(*ptr++ & 1) << 32;
4230-
values[7] |= *ptr++ << 24;
4230+
values[7] |= static_cast<uint64_t>(*ptr++) << 24;
42314231
values[7] |= *ptr++ << 16;
42324232
values[7] |= *ptr++ << 8;
42334233
values[7] |= *ptr;
@@ -4296,7 +4296,7 @@ static inline void unpack_bits_35(uint64_t* values, const uint8_t* ptr) {
42964296
values[1] |= *ptr++ << 6;
42974297
values[1] |= *ptr >> 2;
42984298

4299-
values[2] = static_cast<uint64_t>(*ptr++ & 2) << 33;
4299+
values[2] = static_cast<uint64_t>(*ptr++ & 3) << 33;
43004300
values[2] |= static_cast<uint64_t>(*ptr++) << 25;
43014301
values[2] |= *ptr++ << 17;
43024302
values[2] |= *ptr++ << 9;

theta/test/bit_packing_test.cpp

+41-39
Original file line numberDiff line numberDiff line change
@@ -29,51 +29,53 @@ namespace datasketches {
2929
static const uint64_t IGOLDEN64 = 0x9e3779b97f4a7c13ULL;
3030

3131
TEST_CASE("pack unpack bits") {
32-
for (uint8_t bits = 1; bits <= 63; ++bits) {
33-
int n = 8;
34-
const uint64_t mask = (1ULL << bits) - 1;
35-
std::vector<uint64_t> input(n, 0);
36-
const uint64_t igolden64 = IGOLDEN64;
37-
uint64_t value = 0xaa55aa55aa55aa55ULL; // arbitrary starting value
38-
for (int i = 0; i < n; ++i) {
39-
input[i] = value & mask;
40-
value += igolden64;
41-
}
42-
std::vector<uint8_t> bytes(n * sizeof(uint64_t), 0);
43-
uint8_t offset = 0;
44-
uint8_t* ptr = bytes.data();
45-
for (int i = 0; i < n; ++i) {
46-
offset = pack_bits(input[i], bits, ptr, offset);
47-
}
32+
uint64_t value = 0xaa55aa55aa55aa55ULL; // arbitrary starting value
33+
for (int m = 0; m < 100; ++m) {
34+
for (uint8_t bits = 1; bits <= 63; ++bits) {
35+
int n = 8;
36+
const uint64_t mask = (1ULL << bits) - 1;
37+
std::vector<uint64_t> input(n, 0);
38+
for (int i = 0; i < n; ++i) {
39+
input[i] = value & mask;
40+
value += IGOLDEN64;
41+
}
42+
std::vector<uint8_t> bytes(n * sizeof(uint64_t), 0);
43+
uint8_t offset = 0;
44+
uint8_t* ptr = bytes.data();
45+
for (int i = 0; i < n; ++i) {
46+
offset = pack_bits(input[i], bits, ptr, offset);
47+
}
4848

49-
std::vector<uint64_t> output(n, 0);
50-
offset = 0;
51-
const uint8_t* cptr = bytes.data();
52-
for (int i = 0; i < n; ++i) {
53-
offset = unpack_bits(output[i], bits, cptr, offset);
54-
}
55-
for (int i = 0; i < n; ++i) {
56-
REQUIRE(input[i] == output[i]);
49+
std::vector<uint64_t> output(n, 0);
50+
offset = 0;
51+
const uint8_t* cptr = bytes.data();
52+
for (int i = 0; i < n; ++i) {
53+
offset = unpack_bits(output[i], bits, cptr, offset);
54+
}
55+
for (int i = 0; i < n; ++i) {
56+
REQUIRE(input[i] == output[i]);
57+
}
5758
}
5859
}
5960
}
6061

6162
TEST_CASE("pack unpack blocks") {
62-
for (uint8_t bits = 1; bits <= 63; ++bits) {
63-
const uint64_t mask = (1ULL << bits) - 1;
64-
std::vector<uint64_t> input(8, 0);
65-
const uint64_t igolden64 = IGOLDEN64;
66-
uint64_t value = 0xaa55aa55aa55aa55ULL; // arbitrary starting value
67-
for (int i = 0; i < 8; ++i) {
68-
input[i] = value & mask;
69-
value += igolden64;
70-
}
71-
std::vector<uint8_t> bytes(8 * sizeof(uint64_t), 0);
72-
pack_bits_block8(input.data(), bytes.data(), bits);
73-
std::vector<uint64_t> output(8, 0);
74-
unpack_bits_block8(output.data(), bytes.data(), bits);
75-
for (int i = 0; i < 8; ++i) {
76-
REQUIRE((input[i] & mask) == output[i]);
63+
uint64_t value = 0xaa55aa55aa55aa55ULL; // arbitrary starting value
64+
for (int n = 0; n < 100; ++n) {
65+
for (uint8_t bits = 1; bits <= 63; ++bits) {
66+
const uint64_t mask = (1ULL << bits) - 1;
67+
std::vector<uint64_t> input(8, 0);
68+
for (int i = 0; i < 8; ++i) {
69+
input[i] = value & mask;
70+
value += IGOLDEN64;
71+
}
72+
std::vector<uint8_t> bytes(bits, 0);
73+
pack_bits_block8(input.data(), bytes.data(), bits);
74+
std::vector<uint64_t> output(8, 0);
75+
unpack_bits_block8(output.data(), bytes.data(), bits);
76+
for (int i = 0; i < 8; ++i) {
77+
REQUIRE(input[i] == output[i]);
78+
}
7779
}
7880
}
7981
}

0 commit comments

Comments
 (0)