EigenRand  0.5.0
 
Loading...
Searching...
No Matches
arch/AVX512/RandUtils.h
Go to the documentation of this file.
1
12#ifndef EIGENRAND_RAND_UTILS_AVX512_H
13#define EIGENRAND_RAND_UTILS_AVX512_H
14
15#include <immintrin.h>
16
17namespace Eigen
18{
19 namespace internal
20 {
21 template<typename Rng>
22 struct RawbitsMaker<Packet8i, Rng, Packet16i, Rand::RandomEngineType::packet>
23 {
24 EIGEN_STRONG_INLINE Packet8i rawbits(Rng& rng)
25 {
26 return rng.half();
27 }
28
29 EIGEN_STRONG_INLINE Packet8i rawbits_34(Rng& rng)
30 {
31 return rng.half();
32 }
33
34 EIGEN_STRONG_INLINE Packet8i rawbits_half(Rng& rng)
35 {
36 return rng.half();
37 }
38 };
39
40 template<typename Rng>
41 struct RawbitsMaker<Packet16i, Rng, Packet8i, Rand::RandomEngineType::packet>
42 {
43 EIGEN_STRONG_INLINE Packet16i rawbits(Rng& rng)
44 {
45 return _mm512_inserti64x4(_mm512_castsi256_si512(rng()), rng(), 1);
46 }
47
48 EIGEN_STRONG_INLINE Packet16i rawbits_34(Rng& rng)
49 {
50 return _mm512_inserti64x4(_mm512_castsi256_si512(rng()), rng(), 1);
51 }
52
53 EIGEN_STRONG_INLINE Packet8i rawbits_half(Rng& rng)
54 {
55 return rng();
56 }
57 };
58
59 template<typename Rng, typename RngResult>
60 struct RawbitsMaker<Packet16i, Rng, RngResult, Rand::RandomEngineType::scalar_fullbit>
61 {
62 EIGEN_STRONG_INLINE Packet16i rawbits(Rng& rng)
63 {
64 if (sizeof(decltype(rng())) == 8)
65 {
66 return _mm512_set_epi64(rng(), rng(), rng(), rng(),
67 rng(), rng(), rng(), rng());
68 }
69 else
70 {
71 return _mm512_set_epi32(rng(), rng(), rng(), rng(),
72 rng(), rng(), rng(), rng(),
73 rng(), rng(), rng(), rng(),
74 rng(), rng(), rng(), rng());
75 }
76 }
77
78 EIGEN_STRONG_INLINE Packet16i rawbits_34(Rng& rng)
79 {
80 return rawbits(rng);
81 }
82
83 EIGEN_STRONG_INLINE Packet8i rawbits_half(Rng& rng)
84 {
85 if (sizeof(decltype(rng())) == 8)
86 {
87 return _mm256_set_epi64x(rng(), rng(), rng(), rng());
88 }
89 else
90 {
91 return _mm256_set_epi32(rng(), rng(), rng(), rng(),
92 rng(), rng(), rng(), rng());
93 }
94 }
95 };
96
97 template<typename Rng>
98 struct RawbitsMaker<Packet16i, Rng, Packet16i, Rand::RandomEngineType::packet>
99 {
100 EIGEN_STRONG_INLINE Packet16i rawbits(Rng& rng)
101 {
102 return rng();
103 }
104
105 EIGEN_STRONG_INLINE Packet16i rawbits_34(Rng& rng)
106 {
107 return rng();
108 }
109
110 EIGEN_STRONG_INLINE Packet8i rawbits_half(Rng& rng)
111 {
112 return rng.half();
113 }
114 };
115
116 template<typename Rng>
117 struct UniformRealUtils<Packet16f, Rng> : public RawbitsMaker<Packet16i, Rng>
118 {
119 EIGEN_STRONG_INLINE Packet16f zero_to_one(Rng& rng)
120 {
121 return pdiv(_mm512_cvtepi32_ps(pand(this->rawbits(rng), pset1<Packet16i>(0x7FFFFFFF))),
122 pset1<Packet16f>(0x7FFFFFFF));
123 }
124
125 EIGEN_STRONG_INLINE Packet16f uniform_real(Rng& rng)
126 {
127 return bit_to_ur_float(this->rawbits_34(rng));
128 }
129 };
130
131 template<typename Rng>
132 struct UniformRealUtils<Packet8d, Rng> : public RawbitsMaker<Packet16i, Rng>
133 {
134 EIGEN_STRONG_INLINE Packet8d zero_to_one(Rng& rng)
135 {
136 return pdiv(_mm512_cvtepi32_pd(pand(this->rawbits_half(rng), pset1<Packet8i>(0x7FFFFFFF))),
137 pset1<Packet8d>(0x7FFFFFFF));
138 }
139
140 EIGEN_STRONG_INLINE Packet8d uniform_real(Rng& rng)
141 {
142 return bit_to_ur_double(this->rawbits(rng));
143 }
144 };
145 }
146}
147#endif