32 #ifndef MCKL_RANDOM_INTERNAL_PHILOX_AVX512_32_HPP 33 #define MCKL_RANDOM_INTERNAL_PHILOX_AVX512_32_HPP 49 template <std::
size_t>
56 template <std::
size_t S>
61 template <std::
size_t S>
64 shuffle_epi32<0xB1>(s);
67 template <std::
size_t S>
70 shuffle_epi32<0xB1>(s);
78 template <std::
size_t S>
81 shuffle_epi32<0xC6>(s);
84 template <std::
size_t S>
87 shuffle_epi32<0x93>(s);
90 template <std::
size_t S>
93 shuffle_epi32<0xB1>(s);
97 template <
typename T, std::
size_t K, std::
size_t Rounds,
typename Constants>
102 const void *plain,
void *cipher,
const std::array<T, K / 2> &key)
108 template <
typename ResultType>
110 Counter<T, K> &ctr, ResultType *r,
const std::array<T, K / 2> &key)
115 template <
typename ResultType>
117 const std::array<T, K / 2> &key)
119 constexpr std::size_t
S = 8;
120 constexpr std::size_t N =
sizeof(__m512i) * S / (
sizeof(T) * K);
121 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
123 const std::array<__m512i, Rounds> rk(round_key(key));
125 std::array<__m512i, S> s;
130 std::memcpy(r, s.data(),
sizeof(T) * K * N);
137 ctr, n, t.data(), key);
138 std::memcpy(r, t.data(),
sizeof(T) * K * n);
142 template <std::
size_t, std::
size_t S>
143 static void round(std::array<__m512i, S> &,
144 const std::array<__m512i, Rounds> &, std::false_type)
148 template <std::
size_t N, std::
size_t S>
149 static void round(std::array<__m512i, S> &s,
150 const std::array<__m512i, Rounds> &rk, std::true_type)
155 template <std::
size_t N, std::
size_t S>
157 std::array<__m512i, S> &s,
const std::array<__m512i, Rounds> &rk)
159 rbox<N>(s, rk, std::integral_constant<bool, (N > 0 && N <= Rounds)>());
162 template <std::
size_t, std::
size_t S>
163 static void rbox(std::array<__m512i, S> &,
164 const std::array<__m512i, Rounds> &, std::false_type)
168 template <std::
size_t N, std::
size_t S>
169 static void rbox(std::array<__m512i, S> &s,
170 const std::array<__m512i, Rounds> &rk, std::true_type)
173 static_cast<int>(Constants::multiplier::value[0 % (K / 2)]);
175 static_cast<int>(Constants::multiplier::value[1 % (K / 2)]);
177 static_cast<int>(Constants::multiplier::value[2 % (K / 2)]);
179 static_cast<int>(Constants::multiplier::value[3 % (K / 2)]);
181 static_cast<int>(Constants::multiplier::value[4 % (K / 2)]);
183 static_cast<int>(Constants::multiplier::value[5 % (K / 2)]);
185 static_cast<int>(Constants::multiplier::value[6 % (K / 2)]);
187 static_cast<int>(Constants::multiplier::value[7 % (K / 2)]);
188 constexpr
int mask =
static_cast<int>(0xFFFFFFFF);
190 const __m512i m = _mm512_set_epi32(0, mul7, 0, mul6, 0, mul5, 0, mul4,
191 0, mul3, 0, mul2, 0, mul1, 0, mul0);
192 const __m512i a = _mm512_set_epi32(mask, 0, mask, 0, mask, 0, mask, 0,
193 mask, 0, mask, 0, mask, 0, mask, 0);
194 const __m512i k = std::get<N - 1>(rk);
196 std::array<__m512i, S> t;
204 MCKL_INLINE static std::array<__m512i, Rounds> round_key(
205 const std::array<T, K / 2> &k)
207 const int k0 =
static_cast<int>(std::get<0 % (K / 2)>(k));
208 const int k1 =
static_cast<int>(std::get<1 % (K / 2)>(k));
209 const int k2 =
static_cast<int>(std::get<2 % (K / 2)>(k));
210 const int k3 =
static_cast<int>(std::get<3 % (K / 2)>(k));
211 const int k4 =
static_cast<int>(std::get<4 % (K / 2)>(k));
212 const int k5 =
static_cast<int>(std::get<5 % (K / 2)>(k));
213 const int k6 =
static_cast<int>(std::get<6 % (K / 2)>(k));
214 const int k7 =
static_cast<int>(std::get<7 % (K / 2)>(k));
216 std::array<__m512i, Rounds> rk;
219 k7, 0, k6, 0, k5, 0, k4, 0, k3, 0, k2, 0, k1, 0, k0, 0),
225 template <std::
size_t>
227 std::array<__m512i, Rounds> &,
const __m512i &, std::false_type)
231 template <std::
size_t N>
233 std::array<__m512i, Rounds> &rk,
const __m512i &k, std::true_type)
236 static_cast<int>(Constants::weyl::value[0 % (K / 2)] * N);
238 static_cast<int>(Constants::weyl::value[1 % (K / 2)] * N);
240 static_cast<int>(Constants::weyl::value[2 % (K / 2)] * N);
242 static_cast<int>(Constants::weyl::value[3 % (K / 2)] * N);
244 static_cast<int>(Constants::weyl::value[4 % (K / 2)] * N);
246 static_cast<int>(Constants::weyl::value[5 % (K / 2)] * N);
248 static_cast<int>(Constants::weyl::value[6 % (K / 2)] * N);
250 static_cast<int>(Constants::weyl::value[7 % (K / 2)] * N);
252 std::get<N>(rk) = _mm512_add_epi32(k,
254 w7, 0, w6, 0, w5, 0, w4, 0, w3, 0, w2, 0, w1, 0, w0, 0));
255 set_key<N + 1>(rk, k, std::integral_constant<bool, N + 1 < Rounds>());
258 template <std::
size_t N, std::
size_t S>
259 static void permute(std::array<__m512i, S> &s)
261 permute(s, std::integral_constant<
bool, (N > 0 && N < Rounds)>());
264 template <std::
size_t S>
265 static void permute(std::array<__m512i, S> &, std::false_type)
269 template <std::
size_t S>
270 static void permute(std::array<__m512i, S> &s, std::true_type)
276 template <
typename T,
typename Constants>
282 template <
typename T,
typename Constants>
294 #endif // MCKL_RANDOM_INTERNAL_PHILOX_AVX512_32_HPP #define MCKL_PUSH_GCC_WARNING(warning)
void increment_si512(std::array< T, K > &ctr, std::array< __m512i, S > &s, std::false_type)
void round(std::size_t n, const float *a, float *y)
typename internal::CounterImpl< T, K >::type Counter
A counter type with the same width as std::array<T, K> but with possibly fewer elements.
#define MCKL_RANDOM_INTERNAL_PHILOX_UNROLL_ROUND(N, s, rk)
static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K/2 > &key)
static void eval(Counter< T, K > &ctr, std::size_t n, 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_ALIGNMENT
The default alignment for scalar type.
#define MCKL_POP_GCC_WARNING