@@ -372,36 +372,68 @@ namespace xsimd
372372 detail::store_masked (mem, src, mask.mask (), Mode {});
373373 }
374374
375- // namespace detail
376- // {
377- // template <class A, class T>
378- // std::array<batch_bool<T, A>, 2> zip_complex_mask(batch_bool<T, A> mask)
379- // {
380- // using mask_register_type = typename batch_bool<T, A>::register_type;
381- // mask_register_type nmask = mask.to_native();
382-
383- // constexpr mask_register_type lo_bitmask = xsimd::utils::make_low_mask<mask_register_type>(mask.size / 2);
384- // mask_register_type lo_mask = nmask & lo_bitmask;
385- // lo_mask |= lo_mask << (mask.size / 2);
386-
387- // constexpr mask_register_type hi_bitmask = lo_bitmask << (mask.size / 2);
388- // mask_register_type hi_mask = nmask & hi_bitmask;
389- // hi_mask |= hi_mask >> (mask.size / 2);
390-
391- // return { batch_bool<T, A>{ lo_mask }, batch_bool<T, A>{ hi_mask } };
392- // }
393- // }
375+ namespace detail
376+ {
377+ // complex_low
378+ template <class A >
379+ XSIMD_INLINE batch<float , A> complex_low (batch<std::complex <float >, A> const & self, requires_arch<avx512f>) noexcept
380+ {
381+ __m512i idx = _mm512_setr_epi32 (0 , 16 , 1 , 17 , 2 , 18 , 3 , 19 , 4 , 20 , 5 , 21 , 6 , 22 , 7 , 23 );
382+ return _mm512_permutex2var_ps (self.real (), idx, self.imag ());
383+ }
384+ template <class A >
385+ XSIMD_INLINE batch<double , A> complex_low (batch<std::complex <double >, A> const & self, requires_arch<avx512f>) noexcept
386+ {
387+ __m512i idx = _mm512_setr_epi64 (0 , 8 , 1 , 9 , 2 , 10 , 3 , 11 );
388+ return _mm512_permutex2var_pd (self.real (), idx, self.imag ());
389+ }
390+
391+ // complex_high
392+ template <class A >
393+ XSIMD_INLINE batch<float , A> complex_high (batch<std::complex <float >, A> const & self, requires_arch<avx512f>) noexcept
394+ {
395+ __m512i idx = _mm512_setr_epi32 (8 , 24 , 9 , 25 , 10 , 26 , 11 , 27 , 12 , 28 , 13 , 29 , 14 , 30 , 15 , 31 );
396+ return _mm512_permutex2var_ps (self.real (), idx, self.imag ());
397+ }
398+ template <class A >
399+ XSIMD_INLINE batch<double , A> complex_high (batch<std::complex <double >, A> const & self, requires_arch<avx512f>) noexcept
400+ {
401+ __m512i idx = _mm512_setr_epi64 (4 , 12 , 5 , 13 , 6 , 14 , 7 , 15 );
402+ return _mm512_permutex2var_pd (self.real (), idx, self.imag ());
403+ }
404+ }
405+
406+ namespace detail
407+ {
408+ template <class A , class T >
409+ std::array<batch_bool<T, A>, 2 > zip_complex_mask (batch_bool<T, A> mask)
410+ {
411+ using mask_register_type = typename batch_bool<T, A>::register_type;
412+ mask_register_type nmask = mask.to_native ();
413+
414+ constexpr mask_register_type lo_bitmask = xsimd::utils::make_low_mask<mask_register_type>(mask.size / 2 );
415+ mask_register_type lo_mask = nmask & lo_bitmask;
416+ lo_mask |= lo_mask << (mask.size / 2 );
394417
395- // template <class A, class T, class Mode>
396- // XSIMD_INLINE void
397- // store_complex_masked(std::complex<T>* mem, batch<std::complex<T>, A> const& src, batch_bool<T, A> mask, Mode mode, requires_arch<avx512f>) noexcept
398- // {
399- // auto [lo_mask, hi_mask] = detail::zip_complex_mask(mask);
400- // batch<T, A> src_lo = zip_lo(src.real(), src.imag());
401- // batch<T, A> src_hi = zip_hi(src.real(), src.imag());
402- // detail::store_masked(reinterpret_cast<T*>(mem), src_lo, lo_mask, mode);
403- // detail::store_masked(reinterpret_cast<T*>(mem) + src.size, src_hi, hi_mask, mode);
404- // }
418+ constexpr mask_register_type hi_bitmask = lo_bitmask << (mask.size / 2 );
419+ mask_register_type hi_mask = nmask & hi_bitmask;
420+ hi_mask |= hi_mask >> (mask.size / 2 );
421+
422+ return { batch_bool<T, A> { lo_mask }, batch_bool<T, A> { hi_mask } };
423+ }
424+ }
425+
426+ template <class A , class T , class Mode >
427+ XSIMD_INLINE void
428+ store_complex_masked (std::complex <T>* mem, batch<std::complex <T>, A> const & src, batch_bool<T, A> mask, Mode mode, requires_arch<avx512f>) noexcept
429+ {
430+ auto [lo_mask, hi_mask] = detail::zip_complex_mask (mask);
431+
432+ auto src_lo = detail::complex_low (src, A { });
433+ auto src_hi = detail::complex_high (src, A { });
434+ store_masked (reinterpret_cast <T*>(mem), src_lo, lo_mask, mode, A { });
435+ store_masked (reinterpret_cast <T*>(mem) + src.size , src_hi, hi_mask, mode, A { });
436+ }
405437
406438 // abs
407439 template <class A >
@@ -1003,36 +1035,6 @@ namespace xsimd
10031035 }
10041036 }
10051037
1006- namespace detail
1007- {
1008- // complex_low
1009- template <class A >
1010- XSIMD_INLINE batch<float , A> complex_low (batch<std::complex <float >, A> const & self, requires_arch<avx512f>) noexcept
1011- {
1012- __m512i idx = _mm512_setr_epi32 (0 , 16 , 1 , 17 , 2 , 18 , 3 , 19 , 4 , 20 , 5 , 21 , 6 , 22 , 7 , 23 );
1013- return _mm512_permutex2var_ps (self.real (), idx, self.imag ());
1014- }
1015- template <class A >
1016- XSIMD_INLINE batch<double , A> complex_low (batch<std::complex <double >, A> const & self, requires_arch<avx512f>) noexcept
1017- {
1018- __m512i idx = _mm512_setr_epi64 (0 , 8 , 1 , 9 , 2 , 10 , 3 , 11 );
1019- return _mm512_permutex2var_pd (self.real (), idx, self.imag ());
1020- }
1021-
1022- // complex_high
1023- template <class A >
1024- XSIMD_INLINE batch<float , A> complex_high (batch<std::complex <float >, A> const & self, requires_arch<avx512f>) noexcept
1025- {
1026- __m512i idx = _mm512_setr_epi32 (8 , 24 , 9 , 25 , 10 , 26 , 11 , 27 , 12 , 28 , 13 , 29 , 14 , 30 , 15 , 31 );
1027- return _mm512_permutex2var_ps (self.real (), idx, self.imag ());
1028- }
1029- template <class A >
1030- XSIMD_INLINE batch<double , A> complex_high (batch<std::complex <double >, A> const & self, requires_arch<avx512f>) noexcept
1031- {
1032- __m512i idx = _mm512_setr_epi64 (4 , 12 , 5 , 13 , 6 , 14 , 7 , 15 );
1033- return _mm512_permutex2var_pd (self.real (), idx, self.imag ());
1034- }
1035- }
10361038 // incr_if
10371039 template <class A , class T , class = std::enable_if_t <std::is_integral_v<T>>>
10381040 XSIMD_INLINE batch<T, A> decr_if (batch<T, A> const & self, batch_bool<T, A> const & mask, requires_arch<avx512f>) noexcept
0 commit comments