MCPcopy Create free account
hub / github.com/apache/arrow / bits_to_bytes

Function bits_to_bytes

cpp/src/arrow/compute/util.cc:211–262  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

209}
210
211void bits_to_bytes(int64_t hardware_flags, const int num_bits, const uint8_t* bits,
212 uint8_t* bytes, int bit_offset) {
213 bits += bit_offset / 8;
214 bit_offset %= 8;
215 if (bit_offset != 0) {
216 uint64_t bits_head = bits[0] >> bit_offset;
217 int bits_in_first_byte = std::min(num_bits, 8 - bit_offset);
218 bits_to_bytes(hardware_flags, bits_in_first_byte,
219 reinterpret_cast<const uint8_t*>(&bits_head), bytes);
220 if (num_bits > bits_in_first_byte) {
221 bits_to_bytes(hardware_flags, num_bits - bits_in_first_byte, bits + 1,
222 bytes + bits_in_first_byte);
223 }
224 return;
225 }
226
227 int num_processed = 0;
228#if defined(ARROW_HAVE_RUNTIME_AVX2) && defined(ARROW_HAVE_RUNTIME_BMI2)
229 if ((hardware_flags & CpuInfo::AVX2) && CpuInfo::GetInstance()->HasEfficientBmi2()) {
230 // The function call below processes whole 32 bit chunks together.
231 num_processed = num_bits - (num_bits % 32);
232 avx2::bits_to_bytes_avx2(num_processed, bits, bytes);
233 }
234#endif
235 // Processing 8 bits at a time
236 constexpr int unroll = 8;
237 for (int i = num_processed / unroll; i < num_bits / unroll; ++i) {
238 uint8_t bits_next = bits[i];
239 // Clear the lowest bit and then make 8 copies of remaining 7 bits, each 7 bits apart
240 // from the previous.
241 uint64_t unpacked = static_cast<uint64_t>(bits_next & 0xfe) *
242 ((1ULL << 7) | (1ULL << 14) | (1ULL << 21) | (1ULL << 28) |
243 (1ULL << 35) | (1ULL << 42) | (1ULL << 49));
244 unpacked |= (bits_next & 1);
245 unpacked &= 0x0101010101010101ULL;
246 unpacked *= 255;
247 util::SafeStore(&reinterpret_cast<uint64_t*>(bytes)[i], unpacked);
248 }
249 int tail = num_bits % unroll;
250 if (tail) {
251 uint8_t bits_next = bits[(num_bits - tail) / unroll];
252 // Clear the lowest bit and then make 8 copies of remaining 7 bits, each 7 bits apart
253 // from the previous.
254 uint64_t unpacked = static_cast<uint64_t>(bits_next & 0xfe) *
255 ((1ULL << 7) | (1ULL << 14) | (1ULL << 21) | (1ULL << 28) |
256 (1ULL << 35) | (1ULL << 42) | (1ULL << 49));
257 unpacked |= (bits_next & 1);
258 unpacked &= 0x0101010101010101ULL;
259 unpacked *= 255;
260 SafeStoreUpTo8Bytes(bytes + num_bits - tail, tail, unpacked);
261 }
262}
263
264void bytes_to_bits(int64_t hardware_flags, const int num_bits, const uint8_t* bytes,
265 uint8_t* bits, int bit_offset) {

Callers

nothing calls this directly

Calls 3

bits_to_bytes_avx2Function · 0.85
SafeStoreFunction · 0.85
SafeStoreUpTo8BytesFunction · 0.85

Tested by

no test coverage detected