EigenRand  0.4.0-alpha
arch/NEON/RandUtils.h
Go to the documentation of this file.
1 
12 #ifndef EIGENRAND_RAND_UTILS_NEON_H
13 #define EIGENRAND_RAND_UTILS_NEON_H
14 
15 #include <arm_neon.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  uint64_t v[2];
29  v[0] = rng();
30  v[1] = rng();
31  return vld1q_s32((int32_t*)v);
32  }
33  else
34  {
35  uint32_t v[4];
36  v[0] = rng();
37  v[1] = rng();
38  v[2] = rng();
39  v[3] = rng();
40  return vld1q_s32((int32_t*)v);
41  }
42  }
43 
44  EIGEN_STRONG_INLINE Packet4i rawbits_34(Rng& rng)
45  {
46  if (sizeof(RngResult) == 8)
47  {
48  uint64_t v[2];
49  v[0] = rng();
50  v[1] = rng();
51  return vld1q_s32((int32_t*)v);
52  }
53  else
54  {
55  uint32_t v[4];
56  v[0] = rng();
57  v[1] = rng();
58  v[2] = rng();
59  v[3] = rng();
60  return vld1q_s32((int32_t*)v);
61  }
62  }
63 
64  EIGEN_STRONG_INLINE Packet4i rawbits_half(Rng& rng)
65  {
66  if (sizeof(decltype(rng())) == 8)
67  {
68  uint64_t v[2];
69  v[0] = rng();
70  v[1] = 0;
71  return vld1q_s32((int32_t*)v);
72  }
73  else
74  {
75  uint32_t v[4];
76  v[0] = rng();
77  v[1] = rng();
78  v[2] = 0;
79  v[3] = 0;
80  return vld1q_s32((int32_t*)v);
81  }
82  }
83  };
84 
85  template<typename Rng>
86  struct RawbitsMaker<Packet4i, Rng, Packet4i, Rand::RandomEngineType::packet>
87  {
88  EIGEN_STRONG_INLINE Packet4i rawbits(Rng& rng)
89  {
90  return rng();
91  }
92 
93  EIGEN_STRONG_INLINE Packet4i rawbits_34(Rng& rng)
94  {
95  return rng();
96  }
97 
98  EIGEN_STRONG_INLINE Packet4i rawbits_half(Rng& rng)
99  {
100  return rng();
101  }
102  };
103 
104  template<typename Rng>
105  struct UniformRealUtils<Packet4f, Rng> : public RawbitsMaker<Packet4i, Rng>
106  {
107  EIGEN_STRONG_INLINE Packet4f zero_to_one(Rng& rng)
108  {
109  return pdiv((Packet4f)vcvtq_f32_s32(pand(this->rawbits(rng), pset1<Packet4i>(0x7FFFFFFF))),
110  pset1<Packet4f>(0x7FFFFFFF));
111  }
112 
113  EIGEN_STRONG_INLINE Packet4f uniform_real(Rng& rng)
114  {
115  return bit_to_ur_float(this->rawbits_34(rng));
116  }
117  };
118 
119  template<typename Gen, typename Urng, bool _mutable>
120  struct functor_traits<scalar_rng_adaptor<Gen, double, Urng, _mutable> >
121  {
122  enum { Cost = HugeCost, PacketAccess = 0, IsRepeatable = false };
123  };
124  }
125 }
126 #endif