32 #ifndef MCKL_RANDOM_INTERNAL_U01_AVX512_HPP 33 #define MCKL_RANDOM_INTERNAL_U01_AVX512_HPP 40 #define MCKL_RANDOM_INTERNAL_U01_AVX512_LOADU_SI512(u) \ 41 const __m512i *uptr = reinterpret_cast<const __m512i *>(u); \ 42 __m512i zmm0 = _mm512_loadu_si512(uptr++); \ 43 __m512i zmm1 = _mm512_loadu_si512(uptr++); \ 44 __m512i zmm2 = _mm512_loadu_si512(uptr++); \ 45 __m512i zmm3 = _mm512_loadu_si512(uptr++); 47 #define MCKL_RANDOM_INTERNAL_U01_AVX512_LOADU_SI512_CVTEPU32_EPI64(u) \ 48 const __m256i *uptr = reinterpret_cast<const __m256i *>(u); \ 49 __m512i zmm0 = _mm512_cvtepu32_epi64(_mm256_loadu_si256(uptr++)); \ 50 __m512i zmm1 = _mm512_cvtepu32_epi64(_mm256_loadu_si256(uptr++)); \ 51 __m512i zmm2 = _mm512_cvtepu32_epi64(_mm256_loadu_si256(uptr++)); \ 52 __m512i zmm3 = _mm512_cvtepu32_epi64(_mm256_loadu_si256(uptr++)); 54 #define MCKL_RANDOM_INTERNAL_U01_AVX512_STOREU_PS(r) \ 55 _mm512_storeu_ps(r + 0x00, _mm512_castsi512_ps(zmm0)); \ 56 _mm512_storeu_ps(r + 0x10, _mm512_castsi512_ps(zmm1)); \ 57 _mm512_storeu_ps(r + 0x20, _mm512_castsi512_ps(zmm2)); \ 58 _mm512_storeu_ps(r + 0x30, _mm512_castsi512_ps(zmm3)); 60 #define MCKL_RANDOM_INTERNAL_U01_AVX512_STOREU_PD(r) \ 61 _mm512_storeu_pd(r + 0x00, _mm512_castsi512_pd(zmm0)); \ 62 _mm512_storeu_pd(r + 0x08, _mm512_castsi512_pd(zmm1)); \ 63 _mm512_storeu_pd(r + 0x10, _mm512_castsi512_pd(zmm2)); \ 64 _mm512_storeu_pd(r + 0x18, _mm512_castsi512_pd(zmm3)); 66 #define MCKL_RANDOM_INTERNAL_U01_AVX512_AND1ADD_EPI32 \ 67 const __m512i mask = _mm512_set1_epi32(1); \ 68 zmm0 = _mm512_add_epi32(zmm0, _mm512_and_si512(zmm0, mask)); \ 69 zmm1 = _mm512_add_epi32(zmm1, _mm512_and_si512(zmm1, mask)); \ 70 zmm2 = _mm512_add_epi32(zmm2, _mm512_and_si512(zmm2, mask)); \ 71 zmm3 = _mm512_add_epi32(zmm3, _mm512_and_si512(zmm3, mask)); 73 #define MCKL_RANDOM_INTERNAL_U01_AVX512_AND1ADD_EPI64 \ 74 const __m512i mask = _mm512_set1_epi64(1); \ 75 zmm0 = _mm512_add_epi64(zmm0, _mm512_and_si512(zmm0, mask)); \ 76 zmm1 = _mm512_add_epi64(zmm1, _mm512_and_si512(zmm1, mask)); \ 77 zmm2 = _mm512_add_epi64(zmm2, _mm512_and_si512(zmm2, mask)); \ 78 zmm3 = _mm512_add_epi64(zmm3, _mm512_and_si512(zmm3, mask)); 80 #define MCKL_RANDOM_INTERNAL_U01_AVX512_SLLI_EPI32(imm8) \ 81 zmm0 = _mm512_slli_epi32(zmm0, imm8); \ 82 zmm1 = _mm512_slli_epi32(zmm1, imm8); \ 83 zmm2 = _mm512_slli_epi32(zmm2, imm8); \ 84 zmm3 = _mm512_slli_epi32(zmm3, imm8); 86 #define MCKL_RANDOM_INTERNAL_U01_AVX512_SRLI_EPI32(imm8) \ 87 zmm0 = _mm512_srli_epi32(zmm0, imm8); \ 88 zmm1 = _mm512_srli_epi32(zmm1, imm8); \ 89 zmm2 = _mm512_srli_epi32(zmm2, imm8); \ 90 zmm3 = _mm512_srli_epi32(zmm3, imm8); 92 #define MCKL_RANDOM_INTERNAL_U01_AVX512_SLLI_EPI64(imm8) \ 93 zmm0 = _mm512_slli_epi64(zmm0, imm8); \ 94 zmm1 = _mm512_slli_epi64(zmm1, imm8); \ 95 zmm2 = _mm512_slli_epi64(zmm2, imm8); \ 96 zmm3 = _mm512_slli_epi64(zmm3, imm8); 98 #define MCKL_RANDOM_INTERNAL_U01_AVX512_SRLI_EPI64(imm8) \ 99 zmm0 = _mm512_srli_epi64(zmm0, imm8); \ 100 zmm1 = _mm512_srli_epi64(zmm1, imm8); \ 101 zmm2 = _mm512_srli_epi64(zmm2, imm8); \ 102 zmm3 = _mm512_srli_epi64(zmm3, imm8); 104 #define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU32_PS_31 \ 105 zmm0 = _mm512_castps_si512(_mm512_cvtepi32_ps(zmm0)); \ 106 zmm1 = _mm512_castps_si512(_mm512_cvtepi32_ps(zmm1)); \ 107 zmm2 = _mm512_castps_si512(_mm512_cvtepi32_ps(zmm2)); \ 108 zmm3 = _mm512_castps_si512(_mm512_cvtepi32_ps(zmm3)); 110 #define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU32_PS \ 111 const __m512 c = _mm512_set1_ps(Pow2<float, 23>::value); \ 112 const __m512 d = _mm512_set1_ps(Pow2<float, 16>::value); \ 113 const __m512i l = _mm512_set1_epi32(static_cast<int>(0xFFFF)); \ 114 __m512i xmm0 = _mm512_and_si512(zmm0, l); \ 115 __m512i xmm1 = _mm512_and_si512(zmm1, l); \ 116 __m512i xmm2 = _mm512_and_si512(zmm2, l); \ 117 __m512i xmm3 = _mm512_and_si512(zmm3, l); \ 118 MCKL_RANDOM_INTERNAL_U01_AVX512_SRLI_EPI32(16); \ 119 zmm0 = _mm512_add_epi32(zmm0, _mm512_castps_si512(c)); \ 120 zmm1 = _mm512_add_epi32(zmm1, _mm512_castps_si512(c)); \ 121 zmm2 = _mm512_add_epi32(zmm2, _mm512_castps_si512(c)); \ 122 zmm3 = _mm512_add_epi32(zmm3, _mm512_castps_si512(c)); \ 123 xmm0 = _mm512_add_epi32(xmm0, _mm512_castps_si512(c)); \ 124 xmm1 = _mm512_add_epi32(xmm1, _mm512_castps_si512(c)); \ 125 xmm2 = _mm512_add_epi32(xmm2, _mm512_castps_si512(c)); \ 126 xmm3 = _mm512_add_epi32(xmm3, _mm512_castps_si512(c)); \ 127 zmm0 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(zmm0), c)); \ 128 zmm1 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(zmm1), c)); \ 129 zmm2 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(zmm2), c)); \ 130 zmm3 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(zmm3), c)); \ 131 xmm0 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(xmm0), c)); \ 132 xmm1 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(xmm1), c)); \ 133 xmm2 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(xmm2), c)); \ 134 xmm3 = _mm512_castps_si512(_mm512_sub_ps(_mm512_castsi512_ps(xmm3), c)); \ 135 zmm0 = _mm512_castps_si512(_mm512_fmadd_ps( \ 136 _mm512_castsi512_ps(zmm0), d, _mm512_castsi512_ps(xmm0))); \ 137 zmm1 = _mm512_castps_si512(_mm512_fmadd_ps( \ 138 _mm512_castsi512_ps(zmm1), d, _mm512_castsi512_ps(xmm1))); \ 139 zmm2 = _mm512_castps_si512(_mm512_fmadd_ps( \ 140 _mm512_castsi512_ps(zmm2), d, _mm512_castsi512_ps(xmm2))); \ 141 zmm3 = _mm512_castps_si512(_mm512_fmadd_ps( \ 142 _mm512_castsi512_ps(zmm3), d, _mm512_castsi512_ps(xmm3))); 144 #define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU64_PD_52 \ 145 const __m512d c = _mm512_set1_pd(Pow2<double, 52>::value); \ 146 zmm0 = _mm512_add_epi64(zmm0, _mm512_castpd_si512(c)); \ 147 zmm1 = _mm512_add_epi64(zmm1, _mm512_castpd_si512(c)); \ 148 zmm2 = _mm512_add_epi64(zmm2, _mm512_castpd_si512(c)); \ 149 zmm3 = _mm512_add_epi64(zmm3, _mm512_castpd_si512(c)); \ 150 zmm0 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm0), c)); \ 151 zmm1 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm1), c)); \ 152 zmm2 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm2), c)); \ 153 zmm3 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm3), c)); 155 #define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU64_PD \ 156 const __m512d c = _mm512_set1_pd(Pow2<double, 52>::value); \ 157 const __m512d d = _mm512_set1_pd(Pow2<double, 32>::value); \ 158 const __m512i l = _mm512_set1_epi64(static_cast<MCKL_INT64>(0xFFFFFFFF)); \ 159 __m512i xmm0 = _mm512_and_si512(zmm0, l); \ 160 __m512i xmm1 = _mm512_and_si512(zmm1, l); \ 161 __m512i xmm2 = _mm512_and_si512(zmm2, l); \ 162 __m512i xmm3 = _mm512_and_si512(zmm3, l); \ 163 MCKL_RANDOM_INTERNAL_U01_AVX512_SRLI_EPI64(32); \ 164 zmm0 = _mm512_add_epi64(zmm0, _mm512_castpd_si512(c)); \ 165 zmm1 = _mm512_add_epi64(zmm1, _mm512_castpd_si512(c)); \ 166 zmm2 = _mm512_add_epi64(zmm2, _mm512_castpd_si512(c)); \ 167 zmm3 = _mm512_add_epi64(zmm3, _mm512_castpd_si512(c)); \ 168 xmm0 = _mm512_add_epi64(xmm0, _mm512_castpd_si512(c)); \ 169 xmm1 = _mm512_add_epi64(xmm1, _mm512_castpd_si512(c)); \ 170 xmm2 = _mm512_add_epi64(xmm2, _mm512_castpd_si512(c)); \ 171 xmm3 = _mm512_add_epi64(xmm3, _mm512_castpd_si512(c)); \ 172 zmm0 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm0), c)); \ 173 zmm1 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm1), c)); \ 174 zmm2 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm2), c)); \ 175 zmm3 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm3), c)); \ 176 xmm0 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm0), c)); \ 177 xmm1 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm1), c)); \ 178 xmm2 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm2), c)); \ 179 xmm3 = _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm3), c)); \ 180 zmm0 = _mm512_castpd_si512(_mm512_fmadd_pd( \ 181 _mm512_castsi512_pd(zmm0), d, _mm512_castsi512_pd(xmm0))); \ 182 zmm1 = _mm512_castpd_si512(_mm512_fmadd_pd( \ 183 _mm512_castsi512_pd(zmm1), d, _mm512_castsi512_pd(xmm1))); \ 184 zmm2 = _mm512_castpd_si512(_mm512_fmadd_pd( \ 185 _mm512_castsi512_pd(zmm2), d, _mm512_castsi512_pd(xmm2))); \ 186 zmm3 = _mm512_castpd_si512(_mm512_fmadd_pd( \ 187 _mm512_castsi512_pd(zmm3), d, _mm512_castsi512_pd(xmm3))); 189 #define MCKL_RANDOM_INTERNAL_U01_AVX512_MUL_PS(a) \ 190 zmm0 = _mm512_castps_si512(_mm512_mul_ps(_mm512_castsi512_ps(zmm0), a)); \ 191 zmm1 = _mm512_castps_si512(_mm512_mul_ps(_mm512_castsi512_ps(zmm1), a)); \ 192 zmm2 = _mm512_castps_si512(_mm512_mul_ps(_mm512_castsi512_ps(zmm2), a)); \ 193 zmm3 = _mm512_castps_si512(_mm512_mul_ps(_mm512_castsi512_ps(zmm3), a)); 195 #define MCKL_RANDOM_INTERNAL_U01_AVX512_MUL_PD(a) \ 196 zmm0 = _mm512_castpd_si512(_mm512_mul_pd(_mm512_castsi512_pd(zmm0), a)); \ 197 zmm1 = _mm512_castpd_si512(_mm512_mul_pd(_mm512_castsi512_pd(zmm1), a)); \ 198 zmm2 = _mm512_castpd_si512(_mm512_mul_pd(_mm512_castsi512_pd(zmm2), a)); \ 199 zmm3 = _mm512_castpd_si512(_mm512_mul_pd(_mm512_castsi512_pd(zmm3), a)); 201 #define MCKL_RANDOM_INTERNAL_U01_AVX512_FMADD_PS(a, b) \ 202 zmm0 = _mm512_castps_si512( \ 203 _mm512_fmadd_ps(_mm512_castsi512_ps(zmm0), a, b)); \ 204 zmm1 = _mm512_castps_si512( \ 205 _mm512_fmadd_ps(_mm512_castsi512_ps(zmm1), a, b)); \ 206 zmm2 = _mm512_castps_si512( \ 207 _mm512_fmadd_ps(_mm512_castsi512_ps(zmm2), a, b)); \ 208 zmm3 = _mm512_castps_si512( \ 209 _mm512_fmadd_ps(_mm512_castsi512_ps(zmm3), a, b)); 211 #define MCKL_RANDOM_INTERNAL_U01_AVX512_FMADD_PD(a, b) \ 212 zmm0 = _mm512_castpd_si512( \ 213 _mm512_fmadd_pd(_mm512_castsi512_pd(zmm0), a, b)); \ 214 zmm1 = _mm512_castpd_si512( \ 215 _mm512_fmadd_pd(_mm512_castsi512_pd(zmm1), a, b)); \ 216 zmm2 = _mm512_castpd_si512( \ 217 _mm512_fmadd_pd(_mm512_castsi512_pd(zmm2), a, b)); \ 218 zmm3 = _mm512_castpd_si512( \ 219 _mm512_fmadd_pd(_mm512_castsi512_pd(zmm3), a, b)); 225 template <
typename UIntType,
typename RealType,
typename Lower,
typename Upper,
226 int = std::numeric_limits<UIntType>::digits>
231 template <
typename UIntType,
typename RealType,
typename Lower,
typename Upper>
240 MCKL_INLINE static void eval(std::size_t n,
const UIntType *u, RealType *r)
242 constexpr std::size_t
S = 4;
243 constexpr std::size_t N =
sizeof(__m512i) * S /
sizeof(RealType);
252 for (std::size_t i = 0; i != n; ++i) {
258 template <
typename UIntType,
typename RealType,
int Q,
259 int = std::numeric_limits<UIntType>::digits>
265 template <
typename UIntType,
typename RealType,
int Q>
274 MCKL_INLINE static void eval(std::size_t n,
const UIntType *u, RealType *r)
276 constexpr std::size_t
S = 4;
277 constexpr std::size_t N =
sizeof(__m512i) * S /
sizeof(RealType);
286 for (std::size_t i = 0; i != n; ++i, u += Q) {
292 template <
typename UIntType>
302 MCKL_INLINE static void eval(
const UIntType *u,
float *r)
316 template <
typename UIntType>
326 MCKL_INLINE static void eval(
const UIntType *u,
float *r)
338 template <
typename UIntType>
348 MCKL_INLINE static void eval(
const UIntType *u,
float *r)
360 template <
typename UIntType>
370 MCKL_INLINE static void eval(
const UIntType *u,
float *r)
383 template <
typename UIntType>
393 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
405 template <
typename UIntType>
415 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
426 template <
typename UIntType>
436 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
447 template <
typename UIntType>
457 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
469 template <
typename UIntType>
479 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
493 template <
typename UIntType>
503 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
515 template <
typename UIntType>
525 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
537 template <
typename UIntType>
547 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
560 template <
typename UIntType>
570 MCKL_INLINE static void eval(
const UIntType *u,
float *r)
581 template <
typename UIntType>
591 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
597 _mm512_set1_epi64(static_cast<MCKL_INT64>(0xFFFFFFFF));
601 __m512i xmm0 = _mm512_and_si512(zmm0, l);
602 __m512i xmm1 = _mm512_and_si512(zmm1, l);
603 __m512i xmm2 = _mm512_and_si512(zmm2, l);
604 __m512i xmm3 = _mm512_and_si512(zmm3, l);
608 zmm0 = _mm512_add_epi64(zmm0, _mm512_castpd_si512(c));
609 zmm1 = _mm512_add_epi64(zmm1, _mm512_castpd_si512(c));
610 zmm2 = _mm512_add_epi64(zmm2, _mm512_castpd_si512(c));
611 zmm3 = _mm512_add_epi64(zmm3, _mm512_castpd_si512(c));
613 xmm0 = _mm512_add_epi64(xmm0, _mm512_castpd_si512(c));
614 xmm1 = _mm512_add_epi64(xmm1, _mm512_castpd_si512(c));
615 xmm2 = _mm512_add_epi64(xmm2, _mm512_castpd_si512(c));
616 xmm3 = _mm512_add_epi64(xmm3, _mm512_castpd_si512(c));
619 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm0), c));
621 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm1), c));
623 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm2), c));
625 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(zmm3), c));
628 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm0), c));
630 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm1), c));
632 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm2), c));
634 _mm512_castpd_si512(_mm512_sub_pd(_mm512_castsi512_pd(xmm3), c));
638 zmm0 = _mm512_castpd_si512(_mm512_fmadd_pd(
639 _mm512_castsi512_pd(xmm0), d64, _mm512_castsi512_pd(zmm0)));
640 zmm1 = _mm512_castpd_si512(_mm512_fmadd_pd(
641 _mm512_castsi512_pd(xmm1), d64, _mm512_castsi512_pd(zmm1)));
642 zmm2 = _mm512_castpd_si512(_mm512_fmadd_pd(
643 _mm512_castsi512_pd(xmm2), d64, _mm512_castsi512_pd(zmm2)));
644 zmm3 = _mm512_castpd_si512(_mm512_fmadd_pd(
645 _mm512_castsi512_pd(xmm3), d64, _mm512_castsi512_pd(zmm3)));
651 template <
typename UIntType>
661 MCKL_INLINE static void eval(
const UIntType *u,
double *r)
678 #endif // MCKL_RANDOM_INTERNAL_U01_AVX512_HPP #define MCKL_RANDOM_INTERNAL_U01_AVX512_AND1ADD_EPI32
#define MCKL_RANDOM_INTERNAL_U01_AVX512_FMADD_PD(a, b)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_SRLI_EPI64(imm8)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_FMADD_PS(a, b)
#define MCKL_PUSH_GCC_WARNING(warning)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_SLLI_EPI32(imm8)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_SLLI_EPI64(imm8)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_LOADU_SI512_CVTEPU32_EPI64(u)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_AND1ADD_EPI64
static RealType eval(const UIntType *u)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_MUL_PS(a)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_MUL_PD(a)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU64_PD_52
#define MCKL_RANDOM_INTERNAL_U01_AVX512_STOREU_PS(r)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU64_PD
#define MCKL_RANDOM_INTERNAL_U01_AVX512_SRLI_EPI32(imm8)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU32_PS
#define MCKL_RANDOM_INTERNAL_U01_AVX512_STOREU_PD(r)
Pow2Impl< RealType, P > Pow2
#define MCKL_POP_GCC_WARNING
#define MCKL_RANDOM_INTERNAL_U01_AVX512_LOADU_SI512(u)
#define MCKL_RANDOM_INTERNAL_U01_AVX512_CVTEPU32_PS_31