32 #ifndef MCKL_RANDOM_INTERNAL_PHILOX_AVX2_4X32_HPP 33 #define MCKL_RANDOM_INTERNAL_PHILOX_AVX2_4X32_HPP 47 template <
typename T,
typename Constants>
50 static_assert(std::numeric_limits<T>::digits == 32,
51 "**Philox4x32GeneratorAVX2Impl** used with T other than a 32-bit " 54 static constexpr std::size_t K = 4;
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, 2> &ctr, ResultType *r,
66 const std::array<T, K / 2> &key)
71 template <
typename ResultType>
72 static void eval(std::array<std::uint64_t, 2> &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, 2> &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 m1 = Constants::multiplier::value[1];
102 constexpr T w0 = Constants::weyl::value[0];
103 constexpr T w1 = Constants::weyl::value[1];
105 const T mwk[12] = {m0, 0, m1, 0, 0, w0, 0, w1, 0, std::get<0>(key), 0,
108 #else // MCKL_USE_ASM_LIBRARY 109 constexpr std::size_t
S = 8;
110 constexpr std::size_t N =
sizeof(__m256i) * S / (
sizeof(T) * K);
112 const int k0 =
static_cast<int>(std::get<0>(key));
113 const int k1 =
static_cast<int>(std::get<1>(key));
114 const __m256i ymmk0 = _mm256_set_epi32(k1, 0, k0, 0, k1, 0, k0, 0);
117 _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
118 static_cast<MCKL_INT64>(std::get<0>(ctr)),
119 static_cast<MCKL_INT64>(std::get<1>(ctr)),
120 static_cast<MCKL_INT64>(std::get<0>(ctr)));
123 __m256i *rptr =
reinterpret_cast<__m256i *
>(r);
126 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x02, 0, 0x01));
128 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x04, 0, 0x03));
130 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x06, 0, 0x05));
132 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x08, 0, 0x07));
134 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x0A, 0, 0x09));
136 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x0C, 0, 0x0B));
138 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x0E, 0, 0x0D));
140 _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x10, 0, 0x0F));
141 ymmc = _mm256_add_epi64(ymmc, _mm256_set_epi64x(0, 0x10, 0, 0x10));
143 ymm0 = _mm256_shuffle_epi32(ymm0, 0xC6);
144 ymm1 = _mm256_shuffle_epi32(ymm1, 0xC6);
145 ymm2 = _mm256_shuffle_epi32(ymm2, 0xC6);
146 ymm3 = _mm256_shuffle_epi32(ymm3, 0xC6);
147 ymm4 = _mm256_shuffle_epi32(ymm4, 0xC6);
148 ymm5 = _mm256_shuffle_epi32(ymm5, 0xC6);
149 ymm6 = _mm256_shuffle_epi32(ymm6, 0xC6);
150 ymm7 = _mm256_shuffle_epi32(ymm7, 0xC6);
165 _mm256_storeu_si256(rptr++, ymm0);
166 _mm256_storeu_si256(rptr++, ymm1);
167 _mm256_storeu_si256(rptr++, ymm2);
168 _mm256_storeu_si256(rptr++, ymm3);
169 _mm256_storeu_si256(rptr++, ymm4);
170 _mm256_storeu_si256(rptr++, ymm5);
171 _mm256_storeu_si256(rptr++, ymm6);
172 _mm256_storeu_si256(rptr++, ymm7);
174 std::array<__m256i, S> s;
175 std::get<0>(s) = ymm0;
176 std::get<1>(s) = ymm1;
177 std::get<2>(s) = ymm2;
178 std::get<3>(s) = ymm3;
179 std::get<4>(s) = ymm4;
180 std::get<5>(s) = ymm5;
181 std::get<6>(s) = ymm6;
182 std::get<7>(s) = ymm7;
183 std::memcpy(rptr, s.data(), n *
sizeof(T) * K);
187 #endif // MCKL_USE_ASM_LIBRARY 197 #endif // MCKL_RANDOM_INTERNAL_PHILOX_AVX2_4X32_HPP #define MCKL_PUSH_GCC_WARNING(warning)
static void eval(std::array< std::uint64_t, 2 > &ctr, std::size_t n, ResultType *r, const std::array< T, K/2 > &key)
static void eval(std::array< std::uint64_t, 2 > &ctr, ResultType *r, const std::array< T, K/2 > &key)
#define MCKL_RANDOM_INTERNAL_PHILOX_AVX2_32_RBOX(K, N, imm8)
void mckl_philox4x32_avx2_kernel(uint64_t *, size_t, void *, const void *)
static void eval(const void *plain, void *cipher, const std::array< T, K/2 > &key)
#define MCKL_POP_GCC_WARNING