Skip to content

Commit

Permalink
Extract storeBitsToByte to be reused (facebookincubator#8416)
Browse files Browse the repository at this point in the history
Summary:

We will need this to fix `simd::gatherBits` for non-AVX cases.

See facebookincubator#8415

Differential Revision: D52837098
  • Loading branch information
Yuhta authored and facebook-github-bot committed Jan 17, 2024
1 parent eb09be0 commit 3379917
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 20 deletions.
22 changes: 22 additions & 0 deletions velox/common/base/BitUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#pragma once

#include "velox/common/base/Exceptions.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -977,6 +979,26 @@ inline __int128_t builtin_bswap128(__int128_t value) {
#endif
}

/// Store `bits' into the memory region pointed by `byte', at `index' (bit
/// index). If `kSize' is 8, we store the whole byte directly; otherwise it
/// must be 4 and we store either the whole byte or the upper 4 bits only,
/// depending on the `index'.
template <int kSize>
void storeBitsToByte(uint8_t bits, uint8_t* bytes, unsigned index) {
VELOX_DCHECK_EQ(index % kSize, 0);
VELOX_DCHECK_EQ(bits >> kSize, 0);
if constexpr (kSize == 8) {
bytes[index / 8] = bits;
} else {
VELOX_DCHECK_EQ(kSize, 4);
if (index % 8 == 0) {
bytes[index / 8] = bits;
} else {
bytes[index / 8] |= bits << 4;
}
}
}

} // namespace bits
} // namespace velox
} // namespace facebook
17 changes: 17 additions & 0 deletions velox/common/base/tests/BitUtilTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,23 @@ TEST_F(BitUtilTest, countLeadingZeros) {
EXPECT_EQ(
countLeadingZeros<__uint128_t>(HugeInt::build(0x08FFFFFFFFFFFFFF, 0)), 4);
}

TEST_F(BitUtilTest, storeBitsToByte) {
uint8_t bytes[3]{};
storeBitsToByte<8>(0xAA, bytes, 0);
ASSERT_EQ(bytes[0], 0xAA);
ASSERT_EQ(bytes[1], 0);
ASSERT_EQ(bytes[2], 0);
storeBitsToByte<4>(0x5, bytes, 8);
ASSERT_EQ(bytes[0], 0xAA);
ASSERT_EQ(bytes[1], 0x5);
ASSERT_EQ(bytes[2], 0);
storeBitsToByte<4>(0xA, bytes, 12);
ASSERT_EQ(bytes[0], 0xAA);
ASSERT_EQ(bytes[1], 0xA5);
ASSERT_EQ(bytes[2], 0);
}

} // namespace bits
} // namespace velox
} // namespace facebook
22 changes: 2 additions & 20 deletions velox/dwio/common/DecoderUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,7 @@ bool nonNullRowsFromSparse(
if (isDense(rows.data() + i, width)) {
uint16_t flags = load8Bits(nulls, rows[i]) & widthMask;
if (outputNulls) {
if constexpr (kStep == 8) {
resultNullBytes[i / 8] = flags;
} else {
VELOX_DCHECK_EQ(kStep, 4);
if (i % 8 == 0) {
resultNullBytes[i / 8] = flags;
} else {
resultNullBytes[i / 8] |= flags << 4;
}
}
bits::storeBitsToByte<kStep>(flags, resultNullBytes, i);
anyNull |= flags != widthMask;
}
if (!flags) {
Expand Down Expand Up @@ -131,16 +122,7 @@ bool nonNullRowsFromSparse(
auto next8Rows = xsimd::load_unaligned(rows.data() + i);
uint16_t flags = simd::gather8Bits(nulls, next8Rows, width);
if (outputNulls) {
if constexpr (kStep == 8) {
resultNullBytes[i / 8] = flags;
} else {
VELOX_DCHECK_EQ(kStep, 4);
if (i % 8 == 0) {
resultNullBytes[i / 8] = flags;
} else {
resultNullBytes[i / 8] |= flags << 4;
}
}
bits::storeBitsToByte<kStep>(flags, resultNullBytes, i);
anyNull |= flags != widthMask;
}
if (!flags) {
Expand Down

0 comments on commit 3379917

Please sign in to comment.