32 #ifndef MCKL_RANDOM_INTERNAL_PHILOX_AVX2_2X32_HPP 33 #define MCKL_RANDOM_INTERNAL_PHILOX_AVX2_2X32_HPP 47 template <
typename T,
typename Constants>
50 static_assert(std::numeric_limits<T>::digits == 32,
51 "**Philox2x32GeneratorAVX2Impl** 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(__m256i) * S / (
sizeof(T) * K);
109 const int k0 =
static_cast<int>(std::get<0>(key));
110 const __m256i ymmk0 = _mm256_set_epi32(k0, 0, k0, 0, k0, 0, k0, 0);
113 _mm256_set1_epi64x(static_cast<MCKL_INT64>(std::get<0>(ctr)));
116 __m256i *rptr =
reinterpret_cast<__m256i *
>(r);
118 __m256i ymm0 = _mm256_add_epi64(
119 ymmc, _mm256_set_epi64x(0x04, 0x03, 0x02, 0x01));
120 __m256i ymm1 = _mm256_add_epi64(
121 ymmc, _mm256_set_epi64x(0x08, 0x07, 0x06, 0x05));
122 __m256i ymm2 = _mm256_add_epi64(
123 ymmc, _mm256_set_epi64x(0x0C, 0x0B, 0x0A, 0x09));
124 __m256i ymm3 = _mm256_add_epi64(
125 ymmc, _mm256_set_epi64x(0x10, 0x0F, 0x0E, 0x0D));
126 __m256i ymm4 = _mm256_add_epi64(
127 ymmc, _mm256_set_epi64x(0x14, 0x13, 0x12, 0x11));
128 __m256i ymm5 = _mm256_add_epi64(
129 ymmc, _mm256_set_epi64x(0x18, 0x17, 0x16, 0x15));
130 __m256i ymm6 = _mm256_add_epi64(
131 ymmc, _mm256_set_epi64x(0x1C, 0x1B, 0x1A, 0x19));
132 __m256i ymm7 = _mm256_add_epi64(
133 ymmc, _mm256_set_epi64x(0x20, 0x1F, 0x1E, 0x1D));
134 ymmc = _mm256_add_epi64(ymmc, _mm256_set1_epi64x(0x20));
149 _mm256_storeu_si256(rptr++, ymm0);
150 _mm256_storeu_si256(rptr++, ymm1);
151 _mm256_storeu_si256(rptr++, ymm2);
152 _mm256_storeu_si256(rptr++, ymm3);
153 _mm256_storeu_si256(rptr++, ymm4);
154 _mm256_storeu_si256(rptr++, ymm5);
155 _mm256_storeu_si256(rptr++, ymm6);
156 _mm256_storeu_si256(rptr++, ymm7);
158 std::array<__m256i, S> s;
159 std::get<0>(s) = ymm0;
160 std::get<1>(s) = ymm1;
161 std::get<2>(s) = ymm2;
162 std::get<3>(s) = ymm3;
163 std::get<4>(s) = ymm4;
164 std::get<5>(s) = ymm5;
165 std::get<6>(s) = ymm6;
166 std::get<7>(s) = ymm7;
167 std::memcpy(rptr, s.data(), n *
sizeof(T) * K);
171 #endif // MCKL_USE_ASM_LIBRARY 181 #endif // MCKL_RANDOM_INTERNAL_PHILOX_AVX2_2X32_HPP static void eval(const void *plain, void *cipher, const std::array< T, K/2 > &key)
#define MCKL_PUSH_GCC_WARNING(warning)
#define MCKL_RANDOM_INTERNAL_PHILOX_AVX2_32_RBOX(K, N, imm8)
void mckl_philox2x32_avx2_kernel(uint64_t *, size_t, void *, const void *)
static void eval(std::array< std::uint64_t, 1 > &ctr, std::size_t n, ResultType *r, const std::array< T, K/2 > &key)
static void eval(std::array< std::uint64_t, 1 > &ctr, ResultType *r, const std::array< T, K/2 > &key)
#define MCKL_POP_GCC_WARNING