EigenRand  0.5.0
 
Loading...
Searching...
No Matches
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
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 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#if EIGEN_ARCH_ARM64 && !EIGEN_APPLE_DOUBLE_NEON_BUG
120 template<typename Rng>
121 struct UniformRealUtils<Packet2d, Rng> : public RawbitsMaker<Packet4i, Rng>
122 {
123 EIGEN_STRONG_INLINE Packet2d zero_to_one(Rng& rng)
124 {
125 return pdiv((Packet2d)vcvtq_f64_s64(vreinterpretq_s64_s32(pand(this->rawbits(rng), vreinterpretq_s32_s64(vdupq_n_s64(0x7FFFFFFF))))),
126 pset1<Packet2d>(0x7FFFFFFF));
127 }
128
129 EIGEN_STRONG_INLINE Packet2d uniform_real(Rng& rng)
130 {
131 return bit_to_ur_double(this->rawbits(rng));
132 }
133 };
134
135#else
136 template<typename Gen, typename Urng, bool _mutable>
137 struct functor_traits<scalar_rng_adaptor<Gen, double, Urng, _mutable> >
138 {
139 enum { Cost = HugeCost, PacketAccess = 0, IsRepeatable = false };
140 };
141#endif
142 }
143}
144#endif