EigenRand  0.5.0
 
Loading...
Searching...
No Matches
arch/SSE/RandUtils.h
Go to the documentation of this file.
1
12#ifndef EIGENRAND_RAND_UTILS_SSE_H
13#define EIGENRAND_RAND_UTILS_SSE_H
14
15#include <xmmintrin.h>
16
17namespace Eigen
18{
19 namespace internal
20 {
21 template<typename Rng, typename RngResult>
22 struct RawbitsMaker<Packet4i, Rng, RngResult, Rand::RandomEngineType::scalar_fullbit>
23 {
24 EIGEN_STRONG_INLINE Packet4i rawbits(Rng& rng)
25 {
26 if (sizeof(RngResult) == 8)
27 {
28 return _mm_set_epi64x(rng(), rng());
29 }
30 else
31 {
32 return _mm_set_epi32(rng(), rng(), rng(), rng());
33 }
34 }
35
36 EIGEN_STRONG_INLINE Packet4i rawbits_34(Rng& rng)
37 {
38 if (sizeof(RngResult) == 8)
39 {
40 return _mm_set_epi64x(rng(), rng());
41 }
42 else
43 {
44#ifdef EIGEN_VECTORIZE_SSSE3
45 Packet4i p = _mm_setr_epi32(rng(), rng(), rng(), 0);
46 return _mm_shuffle_epi8(p, _mm_setr_epi8(
47 0, 1, 2, 3,
48 4, 5, 6, 7,
49 8, 9, 10, 11,
50 3, 7, 11, 11));
51#else
52 return _mm_set_epi32(rng(), rng(), rng(), rng());
53#endif
54 }
55 }
56
57 EIGEN_STRONG_INLINE Packet4i rawbits_half(Rng& rng)
58 {
59 if (sizeof(decltype(rng())) == 8)
60 {
61 return _mm_set_epi64x(0, rng());
62 }
63 else
64 {
65 return _mm_setr_epi32(rng(), rng(), 0, 0);
66 }
67 }
68 };
69
70 template<typename Rng>
71 struct RawbitsMaker<Packet4i, Rng, Packet4i, Rand::RandomEngineType::packet>
72 {
73 EIGEN_STRONG_INLINE Packet4i rawbits(Rng& rng)
74 {
75 return rng();
76 }
77
78 EIGEN_STRONG_INLINE Packet4i rawbits_34(Rng& rng)
79 {
80 return rng();
81 }
82
83 EIGEN_STRONG_INLINE Packet4i rawbits_half(Rng& rng)
84 {
85 return rng();
86 }
87 };
88
89 template<typename Rng>
90 struct UniformRealUtils<Packet4f, Rng> : public RawbitsMaker<Packet4i, Rng>
91 {
92 EIGEN_STRONG_INLINE Packet4f zero_to_one(Rng& rng)
93 {
94 return pdiv((Packet4f)_mm_cvtepi32_ps(pand(this->rawbits(rng), pset1<Packet4i>(0x7FFFFFFF))),
95 pset1<Packet4f>(0x7FFFFFFF));
96 }
97
98 EIGEN_STRONG_INLINE Packet4f uniform_real(Rng& rng)
99 {
100 return bit_to_ur_float(this->rawbits_34(rng));
101 }
102 };
103
104 template<typename Rng>
105 struct UniformRealUtils<Packet2d, Rng> : public RawbitsMaker<Packet4i, Rng>
106 {
107 EIGEN_STRONG_INLINE Packet2d zero_to_one(Rng& rng)
108 {
109 return pdiv((Packet2d)_mm_cvtepi32_pd(pand(this->rawbits_half(rng), pset1<Packet4i>(0x7FFFFFFF))),
110 pset1<Packet2d>(0x7FFFFFFF));
111 }
112
113 EIGEN_STRONG_INLINE Packet2d uniform_real(Rng& rng)
114 {
115 return bit_to_ur_double(this->rawbits(rng));
116 }
117 };
118 }
119}
120#endif