32 #ifndef MCKL_RANDOM_INTERNAL_PHILOX_AVX512_2X32_HPP 33 #define MCKL_RANDOM_INTERNAL_PHILOX_AVX512_2X32_HPP 47 template <
typename T,
typename Constants>
50 static_assert(std::numeric_limits<T>::digits == 32,
51 "**Philox2x32GeneratorAVX512Impl** used with T other than a 32-bit " 54 static constexpr std::size_t K = 2;
55 static constexpr std::size_t Rounds = 10;
59 const void *plain,
void *cipher,
const std::array<T, K / 2> &key)
64 template <
typename ResultType>
65 static void eval(std::array<std::uint64_t, 1> &ctr, ResultType *r,
66 const std::array<T, K / 2> &key)
71 template <
typename ResultType>
72 static void eval(std::array<std::uint64_t, 1> &ctr, std::size_t n,
73 ResultType *r,
const std::array<T, K / 2> &key)
75 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
77 const std::size_t n0 =
78 static_cast<std::size_t
>(std::min(static_cast<std::uint64_t>(n),
79 std::numeric_limits<std::uint64_t>::max() - ctr.front()));
81 eval_kernel(ctr, n0, r, key);
91 eval_kernel(ctr, n, r, key);
95 template <
typename ResultType>
96 static void eval_kernel(std::array<std::uint64_t, 1> &ctr, std::size_t n,
97 ResultType *r,
const std::array<T, K / 2> &key)
99 #if MCKL_USE_ASM_LIBRARY 100 constexpr T m0 = Constants::multiplier::value[0];
101 constexpr T w0 = Constants::weyl::value[0];
103 const T mwk[6] = {m0, 0, 0, w0, 0, std::get<0>(key)};
105 #else // MCKL_USE_ASM_LIBRARY 106 constexpr std::size_t
S = 8;
107 constexpr std::size_t N =
sizeof(__m512i) * S / (
sizeof(T) * K);
109 const int k0 =
static_cast<int>(std::get<0>(key));
110 const __m512i ymmk0 = _mm512_set_epi32(
111 k0, 0, k0, 0, k0, 0, k0, 0, k0, 0, k0, 0, k0, 0, k0, 0);
114 _mm512_set1_epi64(static_cast<MCKL_INT64>(std::get<0>(ctr)));
117 __m512i *rptr =
reinterpret_cast<__m512i *
>(r);
119 __m512i ymm0 = _mm512_add_epi64(ymmc,
121 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01));
122 __m512i ymm1 = _mm512_add_epi64(ymmc,
124 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09));
125 __m512i ymm2 = _mm512_add_epi64(ymmc,
127 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11));
128 __m512i ymm3 = _mm512_add_epi64(ymmc,
130 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19));
131 __m512i ymm4 = _mm512_add_epi64(ymmc,
133 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21));
134 __m512i ymm5 = _mm512_add_epi64(ymmc,
136 0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29));
137 __m512i ymm6 = _mm512_add_epi64(ymmc,
139 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31));
140 __m512i ymm7 = _mm512_add_epi64(ymmc,
142 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39));
143 ymmc = _mm512_add_epi64(ymmc, _mm512_set1_epi64(0x40));
158 _mm512_storeu_si512(rptr++, ymm0);
159 _mm512_storeu_si512(rptr++, ymm1);
160 _mm512_storeu_si512(rptr++, ymm2);
161 _mm512_storeu_si512(rptr++, ymm3);
162 _mm512_storeu_si512(rptr++, ymm4);
163 _mm512_storeu_si512(rptr++, ymm5);
164 _mm512_storeu_si512(rptr++, ymm6);
165 _mm512_storeu_si512(rptr++, ymm7);
167 std::array<__m512i, S> s;
168 std::get<0>(s) = ymm0;
169 std::get<1>(s) = ymm1;
170 std::get<2>(s) = ymm2;
171 std::get<3>(s) = ymm3;
172 std::get<4>(s) = ymm4;
173 std::get<5>(s) = ymm5;
174 std::get<6>(s) = ymm6;
175 std::get<7>(s) = ymm7;
176 std::memcpy(rptr, s.data(), n *
sizeof(T) * K);
180 #endif // MCKL_USE_ASM_LIBRARY 190 #endif // MCKL_RANDOM_INTERNAL_PHILOX_AVX512_2X32_HPP #define MCKL_PUSH_GCC_WARNING(warning)
void mckl_philox2x32_avx512_kernel(uint64_t *, size_t, void *, const void *)
#define MCKL_RANDOM_INTERNAL_PHILOX_AVX512_32_RBOX(K, N, imm8)
static void eval(std::array< std::uint64_t, 1 > &ctr, ResultType *r, const std::array< T, K/2 > &key)
static void eval(const void *plain, void *cipher, const std::array< T, K/2 > &key)
#define MCKL_POP_GCC_WARNING
static void eval(std::array< std::uint64_t, 1 > &ctr, std::size_t n, ResultType *r, const std::array< T, K/2 > &key)