MCPcopy Create free account
hub / github.com/cwida/ALP / encode_simdized

Method encode_simdized

include/alp/encoder.hpp:307–400  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

305 }
306
307 static inline void encode_simdized(const PT* input_vector,
308 PT* exceptions,
309 exp_p_t* exceptions_positions,
310 exp_c_t* exceptions_count,
311 ST* encoded_integers,
312 const factor_idx_t factor_idx,
313 const exponent_idx_t exponent_idx) {
314 // These arrays are thread_local static to ensure thread safety during multithreaded compression.
315 // See: https://github.com/cwida/ALP/issues/41 for discussion.
316 // Without thread_local, static arrays would be shared between threads, causing data races.
317 alignas(64) thread_local static PT ENCODED_VALUE_ARR[1024];
318 alignas(64) thread_local static PT VALUE_ARR_WITHOUT_SPECIALS[1024];
319 alignas(64) thread_local static UT TMP_INDEX_ARR[1024];
320
321 exp_p_t current_exceptions_count {0};
322 uint64_t exceptions_idx {0};
323
324 // make copy of input with all special values replaced by ENCODING_UPPER_LIMIT
325 const auto* tmp_input = reinterpret_cast<const UT*>(input_vector);
326 for (size_t i {0}; i < config::VECTOR_SIZE; i++) {
327 const auto is_special =
328 ((tmp_input[i] & Constants<PT>::SIGN_BIT_MASK) >=
329 Constants<PT>::EXPONENTIAL_BITS_MASK) // any NaN, +inf and -inf
330 // (https://stackoverflow.com/questions/29730530/)
331 || tmp_input[i] == Constants<PT>::NEGATIVE_ZERO;
332
333 if (is_special) {
334 VALUE_ARR_WITHOUT_SPECIALS[i] = ENCODING_UPPER_LIMIT;
335 } else {
336 VALUE_ARR_WITHOUT_SPECIALS[i] = input_vector[i];
337 }
338 }
339
340#pragma clang loop vectorize_width(64)
341 for (size_t i {0}; i < config::VECTOR_SIZE; i++) {
342 auto const actual_value = VALUE_ARR_WITHOUT_SPECIALS[i];
343
344 // Attempt conversion
345 const ST encoded_value = encode_value<false>(actual_value, factor_idx, exponent_idx);
346 encoded_integers[i] = encoded_value;
347 const PT decoded_value = decoder<PT>::decode_value(encoded_value, factor_idx, exponent_idx);
348 ENCODED_VALUE_ARR[i] = decoded_value;
349 }
350
351#ifdef __AVX512F__
352 if constexpr (std::is_same_v<PT, double>) {
353 for (size_t i {0}; i < config::VECTOR_SIZE; i = i + 8) {
354 __m512d l = _mm512_loadu_pd(ENCODED_VALUE_ARR + i);
355 __m512d r = _mm512_loadu_pd(VALUE_ARR_WITHOUT_SPECIALS + i);
356 __m512i index = _mm512_loadu_pd(DOUBLE_INDEX_ARR + i);
357 auto is_exception = _mm512_cmpneq_pd_mask(l, r);
358 _mm512_mask_compressstoreu_pd(TMP_INDEX_ARR + exceptions_idx, is_exception, index);
359 exceptions_idx += LOOKUP_TABLE[is_exception];
360 }
361 } else {
362 for (size_t i {0}; i < config::VECTOR_SIZE; i = i + 16) {
363 __m512 l = _mm512_loadu_ps(ENCODED_VALUE_ARR + i);
364 __m512 r = _mm512_loadu_ps(VALUE_ARR_WITHOUT_SPECIALS + i);

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected