EigenRand  0.4.0-alpha
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 
17 namespace Eigen
18 {
19  namespace internal
20  {
21  template<typename Rng, typename RngResult>
22  struct RawbitsMaker<Packet4i, Rng, RngResult, Rand::RandomEngineType::scalar>
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