11 #ifndef EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H 12 #define EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H 19 EIGEN_DEVICE_FUNC uint64_t get_random_seed() {
20 #if defined(EIGEN_GPU_COMPILE_PHASE) 23 gpu_assert(threadIdx.z == 0);
24 return blockIdx.x * blockDim.x + threadIdx.x
25 + gridDim.x * blockDim.x * (blockIdx.y * blockDim.y + threadIdx.y);
28 return random<uint64_t>();
32 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
unsigned PCG_XSH_RS_generator(uint64_t* state, uint64_t stream) {
34 uint64_t current = *state;
36 *state = current * 6364136223846793005ULL + (stream << 1 | 1);
38 return static_cast<unsigned>((current ^ (current >> 22)) >> (22 + (current >> 61)));
41 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint64_t PCG_XSH_RS_state(uint64_t seed) {
42 seed = seed ? seed : get_random_seed();
43 return seed * 6364136223846793005ULL + 0xda3e39cb94b95bdbULL;
49 template <
typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
50 T RandomToTypeUniform(uint64_t* state, uint64_t stream) {
51 unsigned rnd = PCG_XSH_RS_generator(state, stream);
52 return static_cast<T
>(rnd);
56 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
57 Eigen::half RandomToTypeUniform<Eigen::half>(uint64_t* state, uint64_t stream) {
59 unsigned rnd = PCG_XSH_RS_generator(state, stream);
60 const uint16_t half_bits =
static_cast<uint16_t
>(rnd & 0x3ffu) | (static_cast<uint16_t>(15) << 10);
61 Eigen::half result = Eigen::numext::bit_cast<Eigen::half>(half_bits);
63 return result - Eigen::half(1.0f);
66 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
67 Eigen::bfloat16 RandomToTypeUniform<Eigen::bfloat16>(uint64_t* state, uint64_t stream) {
70 unsigned rnd = PCG_XSH_RS_generator(state, stream);
71 const uint16_t half_bits =
static_cast<uint16_t
>(rnd & 0x7fu) | (static_cast<uint16_t>(127) << 7);
72 Eigen::bfloat16 result = Eigen::numext::bit_cast<Eigen::bfloat16>(half_bits);
74 return result - Eigen::bfloat16(1.0f);
77 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
78 float RandomToTypeUniform<float>(uint64_t* state, uint64_t stream) {
85 const unsigned rnd = PCG_XSH_RS_generator(state, stream);
86 result.raw = rnd & 0x7fffffu;
88 result.raw |= (
static_cast<uint32_t
>(127) << 23);
90 return result.fp - 1.0f;
93 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
94 double RandomToTypeUniform<double>(uint64_t* state, uint64_t stream) {
103 unsigned rnd1 = PCG_XSH_RS_generator(state, stream) & 0xfffffu;
105 unsigned rnd2 = PCG_XSH_RS_generator(state, stream);
106 result.raw = (
static_cast<uint64_t
>(rnd1) << 32) | rnd2;
108 result.raw |= (
static_cast<uint64_t
>(1023) << 52);
110 return result.dp - 1.0;
113 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
114 std::complex<float> RandomToTypeUniform<std::complex<float> >(uint64_t* state, uint64_t stream) {
115 return std::complex<float>(RandomToTypeUniform<float>(state, stream),
116 RandomToTypeUniform<float>(state, stream));
118 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
119 std::complex<double> RandomToTypeUniform<std::complex<double> >(uint64_t* state, uint64_t stream) {
120 return std::complex<double>(RandomToTypeUniform<double>(state, stream),
121 RandomToTypeUniform<double>(state, stream));
124 template <
typename T>
class UniformRandomGenerator {
126 static const bool PacketAccess =
true;
129 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE UniformRandomGenerator(
131 m_state = PCG_XSH_RS_state(seed);
132 #ifdef EIGEN_USE_SYCL 149 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE UniformRandomGenerator(
150 const UniformRandomGenerator& other) {
151 m_state = other.m_state;
152 #ifdef EIGEN_USE_SYCL 153 m_exec_once =other.m_exec_once;
157 template<
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
158 T operator()(
Index i)
const {
159 #ifdef EIGEN_USE_SYCL 163 m_state += (i * 6364136223846793005ULL);
167 T result = RandomToTypeUniform<T>(&m_state, i);
171 template<
typename Packet,
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
172 Packet packetOp(
Index i)
const {
173 const int packetSize = internal::unpacket_traits<Packet>::size;
174 EIGEN_ALIGN_MAX T values[packetSize];
175 #ifdef EIGEN_USE_SYCL 178 m_state += (i * 6364136223846793005ULL);
183 for (
int j = 0; j < packetSize; ++j) {
184 values[j] = RandomToTypeUniform<T>(&m_state, i);
186 return internal::pload<Packet>(values);
190 mutable uint64_t m_state;
191 #ifdef EIGEN_USE_SYCL 192 mutable bool m_exec_once;
196 template <
typename Scalar>
197 struct functor_traits<UniformRandomGenerator<Scalar> > {
200 Cost = 12 * NumTraits<Scalar>::AddCost *
201 ((
sizeof(Scalar) +
sizeof(
float) - 1) /
sizeof(
float)),
202 PacketAccess = UniformRandomGenerator<Scalar>::PacketAccess
208 template <
typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
209 T RandomToTypeNormal(uint64_t* state, uint64_t stream) {
215 u = RandomToTypeUniform<T>(state, stream);
216 v = T(1.7156) * (RandomToTypeUniform<T>(state, stream) - T(0.5));
217 const T x = u - T(0.449871);
218 const T y = numext::abs(v) + T(0.386595);
219 q = x*x + y * (T(0.196)*y - T(0.25472)*x);
220 }
while (q > T(0.27597) &&
221 (q > T(0.27846) || v*v > T(-4) * numext::log(u) * u*u));
226 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
227 std::complex<float> RandomToTypeNormal<std::complex<float> >(uint64_t* state, uint64_t stream) {
228 return std::complex<float>(RandomToTypeNormal<float>(state, stream),
229 RandomToTypeNormal<float>(state, stream));
231 template <> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
232 std::complex<double> RandomToTypeNormal<std::complex<double> >(uint64_t* state, uint64_t stream) {
233 return std::complex<double>(RandomToTypeNormal<double>(state, stream),
234 RandomToTypeNormal<double>(state, stream));
238 template <
typename T>
class NormalRandomGenerator {
240 static const bool PacketAccess =
true;
243 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE NormalRandomGenerator(uint64_t seed = 0) {
244 m_state = PCG_XSH_RS_state(seed);
245 #ifdef EIGEN_USE_SYCL 259 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE NormalRandomGenerator(
260 const NormalRandomGenerator& other) {
261 m_state = other.m_state;
262 #ifdef EIGEN_USE_SYCL 263 m_exec_once=other.m_exec_once;
267 template<
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
268 T operator()(
Index i)
const {
269 #ifdef EIGEN_USE_SYCL 272 m_state += (i * 6364136223846793005ULL);
276 T result = RandomToTypeNormal<T>(&m_state, i);
280 template<
typename Packet,
typename Index> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
281 Packet packetOp(
Index i)
const {
282 const int packetSize = internal::unpacket_traits<Packet>::size;
283 EIGEN_ALIGN_MAX T values[packetSize];
284 #ifdef EIGEN_USE_SYCL 287 m_state += (i * 6364136223846793005ULL);
292 for (
int j = 0; j < packetSize; ++j) {
293 values[j] = RandomToTypeNormal<T>(&m_state, i);
295 return internal::pload<Packet>(values);
299 mutable uint64_t m_state;
300 #ifdef EIGEN_USE_SYCL 301 mutable bool m_exec_once;
306 template <
typename Scalar>
307 struct functor_traits<NormalRandomGenerator<Scalar> > {
311 Cost = 3 * functor_traits<UniformRandomGenerator<Scalar> >::Cost +
312 15 * NumTraits<Scalar>::AddCost + 8 * NumTraits<Scalar>::AddCost +
313 3 * functor_traits<scalar_log_op<Scalar> >::Cost / 2,
314 PacketAccess = NormalRandomGenerator<Scalar>::PacketAccess
322 #endif // EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index