AVX512 - Left packing elements by index using mask

Viewed 233

In short, I am trying to compress(left pack) 64-bit integers by index. Neither scatter nor compress intrinsics solves this problem directly.

Suppose you have eight 64-bit integers in a and want to left pack those elements at addresses starting at base_addr by the index subject to mask k.

int64_t* dst; // memory to store the result
__m512i a = _mm512_loadu_si512 ( arr ); // load data from memory into a
__mmask8 k = _mm512_cmpgt_epi64_mask ( a, _mm512_set1_epi64(6) ); // compare for greater-than
__m512i index = _mm512_set_epi64 ( 14, 12, 10, 8, 6, 4, 2, 0 ); // index vector
_mm512_mask_compressstoreu_epi64_by_index ( dst, k, index, a ); // How can I implement this function efficiently?

So, _mm512_mask_compressstoreu_epi64_by_index function should compress 64-bit integers from a into memory dst using index. The writemask k stores the element, which is active in a, to memory.

The result of this function will looks like:

dst = [10, 0, 7, 0, 9, 0, 0, 0 ...].

The elements 10, 7 and 9 are stored after an index 0, 2 and 4 accordingly.

I've tried _mm512_mask_compressstoreu_epi64 and _mm512_mask_i64scatter_epi64 intrinsics, but these instructions save the elements differently. They will give you following results:

_mm512_mask_compressstoreu_epi64( dst, k, a ) produces: dst = [ 10, 7, 9 , ... ]

_mm512_mask_i64scatter_epi64 ( dst, k, index, a, 8 ) produces: dst = [ 0, 10, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 9, ...]

What I want is _mm512_mask_compressstoreu_epi64_by_index( dst, k, index, a ) which results dst = [10, 0, 7, 0, 9, 0, 0, 0 ...]

How can I solve this problem?

0 Answers
Related