10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H 11 #define EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H 18 EIGEN_DEVICE_FUNC uint64_t get_random_seed() {
22 assert(threadIdx.z == 0);
24 blockIdx.x * blockDim.x + threadIdx.x +
25 gridDim.x * blockDim.x * (blockIdx.y * blockDim.y + threadIdx.y);
31 int time = st.wSecond + 1000 * st.wMilliseconds;
38 uint64_t rnd = (rnd1 | rnd2 << 16) ^ time;
41 #elif defined __APPLE__ 44 uint64_t rnd = ::random() ^ mach_absolute_time();
52 clock_gettime(CLOCK_REALTIME, &ts);
53 uint64_t rnd = ::random() ^ ts.tv_nsec;
58 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
unsigned PCG_XSH_RS_generator(uint64_t* state) {
60 uint64_t current = *state;
62 *state = current * 6364136223846793005ULL + 0xda3e39cb94b95bdbULL;
64 return static_cast<unsigned>((current ^ (current >> 22)) >> (22 + (current >> 61)));
67 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint64_t PCG_XSH_RS_state(uint64_t seed) {
68 seed = seed ? seed : get_random_seed();
69 return seed * 6364136223846793005ULL + 0xda3e39cb94b95bdbULL;
75 template <
typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
76 T RandomToTypeUniform(uint64_t* state) {
77 unsigned rnd = PCG_XSH_RS_generator(state);
78 return static_cast<T>(rnd);
82 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
83 Eigen::half RandomToTypeUniform<Eigen::half>(uint64_t* state) {
86 unsigned rnd = PCG_XSH_RS_generator(state);
87 result.x =
static_cast<uint16_t
>(rnd & 0x3ffu);
89 result.x |= (
static_cast<uint16_t
>(15) << 10);
95 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
96 float RandomToTypeUniform<float>(uint64_t* state) {
103 const unsigned rnd = PCG_XSH_RS_generator(state);
104 result.raw = rnd & 0x7fffffu;
106 result.raw |= (
static_cast<uint32_t
>(127) << 23);
108 return result.fp - 1.0f;
111 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
112 double RandomToTypeUniform<double>(uint64_t* state) {
121 unsigned rnd1 = PCG_XSH_RS_generator(state) & 0xfffffu;
123 unsigned rnd2 = PCG_XSH_RS_generator(state);
124 result.raw = (
static_cast<uint64_t
>(rnd1) << 32) | rnd2;
126 result.raw |= (
static_cast<uint64_t
>(1023) << 52);
128 return result.dp - 1.0;
131 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
132 std::complex<float> RandomToTypeUniform<std::complex<float> >(uint64_t* state) {
133 return std::complex<float>(RandomToTypeUniform<float>(state),
134 RandomToTypeUniform<float>(state));
136 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
137 std::complex<double> RandomToTypeUniform<std::complex<double> >(uint64_t* state) {
138 return std::complex<double>(RandomToTypeUniform<double>(state),
139 RandomToTypeUniform<double>(state));
144 static const bool PacketAccess =
true;
149 m_state = PCG_XSH_RS_state(seed);
153 m_state = other.m_state;
156 template<
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
157 T operator()(
Index i)
const {
158 uint64_t local_state = m_state + i;
159 T result = RandomToTypeUniform<T>(&local_state);
160 m_state = local_state;
164 template<
typename Packet,
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
167 EIGEN_ALIGN_MAX
T values[packetSize];
168 uint64_t local_state = m_state + i;
169 for (
int j = 0; j < packetSize; ++j) {
170 values[j] = RandomToTypeUniform<T>(&local_state);
172 m_state = local_state;
173 return internal::pload<Packet>(values);
177 mutable uint64_t m_state;
180 template <
typename Scalar>
185 ((
sizeof(Scalar) +
sizeof(
float) - 1) /
sizeof(
float)),
192 template <
typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
193 T RandomToTypeNormal(uint64_t* state) {
199 u = RandomToTypeUniform<T>(state);
200 v =
T(1.7156) * (RandomToTypeUniform<T>(state) -
T(0.5));
201 const T x = u -
T(0.449871);
202 const T y = numext::abs(v) + T(0.386595);
203 q = x*x + y * (T(0.196)*y - T(0.25472)*x);
204 }
while (q >
T(0.27597) &&
205 (q >
T(0.27846) || v*v >
T(-4) * numext::log(u) * u*u));
210 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
211 std::complex<float> RandomToTypeNormal<std::complex<float> >(uint64_t* state) {
212 return std::complex<float>(RandomToTypeNormal<float>(state),
213 RandomToTypeNormal<float>(state));
215 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
216 std::complex<double> RandomToTypeNormal<std::complex<double> >(uint64_t* state) {
217 return std::complex<double>(RandomToTypeNormal<double>(state),
218 RandomToTypeNormal<double>(state));
224 static const bool PacketAccess =
true;
228 m_state = PCG_XSH_RS_state(seed);
232 m_state = other.m_state;
235 template<
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
236 T operator()(
Index i)
const {
237 uint64_t local_state = m_state + i;
238 T result = RandomToTypeNormal<T>(&local_state);
239 m_state = local_state;
243 template<
typename Packet,
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
246 EIGEN_ALIGN_MAX
T values[packetSize];
247 uint64_t local_state = m_state + i;
248 for (
int j = 0; j < packetSize; ++j) {
249 values[j] = RandomToTypeNormal<T>(&local_state);
251 m_state = local_state;
252 return internal::pload<Packet>(values);
256 mutable uint64_t m_state;
260 template <
typename Scalar>
276 #endif // EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H
Definition: XprHelper.h:158
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:85
Holds information about the various numeric (i.e.
Definition: NumTraits.h:150
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
Definition: PacketMath.h:48
Definition: BandTriangularSolver.h:13
Definition: XprHelper.h:146
Definition: TensorRandom.h:222