aboutsummaryrefslogtreecommitdiffhomepage
path: root/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
diff options
context:
space:
mode:
authorGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2015-04-22 09:14:38 -0700
committerGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2015-04-22 09:14:38 -0700
commit8838ed39f49bc1eb44efbcf13946132611a3132f (patch)
treeeefae31832e79c3fb2cdee1020f1a501e4e61b4b /unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
parente7457e419d9347aae20df342358d6f2a6581d4f3 (diff)
Added support for non-deterministic random number generation on GPU
Diffstat (limited to 'unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h')
-rw-r--r--unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h98
1 files changed, 75 insertions, 23 deletions
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h b/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
index bfd01ad6e..b5adb4041 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
@@ -185,21 +185,25 @@ template <typename T> struct ProdReducer
// Random number generation
namespace {
+#ifdef __CUDA_ARCH__
+__device__ int get_random_seed() {
+ return clock();
+}
+#else
int get_random_seed() {
-#if defined _WIN32
+#ifdef _WIN32
SYSTEMTIME st;
GetSystemTime(&st);
return st.wSecond + 1000 * st.wMilliseconds;
#elif defined __APPLE__
return mach_absolute_time();
-#elif defined __CUDA_ARCH__
- return clock();
#else
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
- return static_cast<int>(ts.tv_nsec);
+ return ts.tv_nsec;
#endif
}
+#endif
}
#if !defined (EIGEN_USE_GPU) || !defined(__CUDACC__) || !defined(__CUDA_ARCH__)
@@ -209,11 +213,14 @@ template <typename T> class UniformRandomGenerator {
public:
static const bool PacketAccess = true;
- UniformRandomGenerator(bool deterministic = true) {
+ UniformRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {
if (!deterministic) {
srand(get_random_seed());
}
}
+ UniformRandomGenerator(const UniformRandomGenerator& other) {
+ m_deterministic = other.m_deterministic;
+ }
template<typename Index>
T operator()(Index, Index = 0) const {
@@ -228,6 +235,9 @@ template <typename T> class UniformRandomGenerator {
}
return internal::pload<typename internal::packet_traits<T>::type>(values);
}
+
+ private:
+ bool m_deterministic;
};
#if __cplusplus > 199711
@@ -235,13 +245,14 @@ template <> class UniformRandomGenerator<float> {
public:
static const bool PacketAccess = true;
- UniformRandomGenerator(bool deterministic = true) {
+ UniformRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {
if (!deterministic) {
m_generator.seed(get_random_seed());
}
}
UniformRandomGenerator(const UniformRandomGenerator<float>& other) {
m_generator.seed(other(0, 0) * UINT_MAX);
+ m_deterministic = other.m_deterministic;
}
template<typename Index>
@@ -260,6 +271,9 @@ template <> class UniformRandomGenerator<float> {
private:
UniformRandomGenerator& operator = (const UniformRandomGenerator&);
+ // Make sure m_deterministic comes first to match the layout of the cpu
+ // version of the code.
+ bool m_deterministic;
mutable std::mt19937 m_generator;
mutable std::uniform_real_distribution<float> m_distribution;
};
@@ -268,13 +282,14 @@ template <> class UniformRandomGenerator<double> {
public:
static const bool PacketAccess = true;
- UniformRandomGenerator(bool deterministic = true) {
+ UniformRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {
if (!deterministic) {
m_generator.seed(get_random_seed());
}
}
UniformRandomGenerator(const UniformRandomGenerator<double>& other) {
m_generator.seed(other(0, 0) * UINT_MAX);
+ m_deterministic = other.m_deterministic;
}
template<typename Index>
@@ -293,6 +308,9 @@ template <> class UniformRandomGenerator<double> {
private:
UniformRandomGenerator& operator = (const UniformRandomGenerator&);
+ // Make sure m_deterministic comes first to match the layout of the cpu
+ // version of the code.
+ bool m_deterministic;
mutable std::mt19937 m_generator;
mutable std::uniform_real_distribution<double> m_distribution;
};
@@ -307,22 +325,30 @@ template <> class UniformRandomGenerator<float> {
public:
static const bool PacketAccess = true;
- EIGEN_DEVICE_FUNC UniformRandomGenerator(bool deterministic = true) {
+ __device__ UniformRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {
const int tid = blockIdx.x * blockDim.x + threadIdx.x;
const int seed = deterministic ? 0 : get_random_seed();
curand_init(seed, tid, 0, &m_state);
}
+ __device__ UniformRandomGenerator(const UniformRandomGenerator& other) {
+ m_deterministic = other.m_deterministic;
+ const int tid = blockIdx.x * blockDim.x + threadIdx.x;
+ const int seed = m_deterministic ? 0 : get_random_seed();
+ curand_init(seed, tid, 0, &m_state);
+ }
+
template<typename Index>
- EIGEN_DEVICE_FUNC float operator()(Index, Index = 0) const {
+ __device__ float operator()(Index, Index = 0) const {
return curand_uniform(&m_state);
}
template<typename Index>
- EIGEN_DEVICE_FUNC float4 packetOp(Index, Index = 0) const {
+ __device__ float4 packetOp(Index, Index = 0) const {
return curand_uniform4(&m_state);
}
private:
+ bool m_deterministic;
mutable curandStatePhilox4_32_10_t m_state;
};
@@ -330,21 +356,28 @@ template <> class UniformRandomGenerator<double> {
public:
static const bool PacketAccess = true;
- EIGEN_DEVICE_FUNC UniformRandomGenerator(bool deterministic = true) {
+ __device__ UniformRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {
const int tid = blockIdx.x * blockDim.x + threadIdx.x;
const int seed = deterministic ? 0 : get_random_seed();
curand_init(seed, tid, 0, &m_state);
}
+ __device__ UniformRandomGenerator(const UniformRandomGenerator& other) {
+ m_deterministic = other.m_deterministic;
+ const int tid = blockIdx.x * blockDim.x + threadIdx.x;
+ const int seed = m_deterministic ? 0 : get_random_seed();
+ curand_init(seed, tid, 0, &m_state);
+ }
template<typename Index>
- EIGEN_DEVICE_FUNC double operator()(Index, Index = 0) const {
+ __device__ double operator()(Index, Index = 0) const {
return curand_uniform_double(&m_state);
}
template<typename Index>
- EIGEN_DEVICE_FUNC double2 packetOp(Index, Index = 0) const {
+ __device__ double2 packetOp(Index, Index = 0) const {
return curand_uniform2_double(&m_state);
}
private:
+ bool m_deterministic;
mutable curandStatePhilox4_32_10_t m_state;
};
@@ -357,12 +390,13 @@ template <typename T> class NormalRandomGenerator {
public:
static const bool PacketAccess = true;
- NormalRandomGenerator(bool deterministic = true) : m_distribution(0, 1) {
+ NormalRandomGenerator(bool deterministic = true) : m_deterministic(deterministic), m_distribution(0, 1) {
if (!deterministic) {
m_generator.seed(get_random_seed());
}
}
- NormalRandomGenerator(const NormalRandomGenerator& other) : m_distribution(other.m_distribution) {
+ NormalRandomGenerator(const NormalRandomGenerator& other)
+ : m_deterministic(other.m_deterministic), m_distribution(other.m_distribution) {
m_generator.seed(other(0, 0) * UINT_MAX);
}
@@ -380,6 +414,8 @@ template <typename T> class NormalRandomGenerator {
return internal::pload<typename internal::packet_traits<T>::type>(values);
}
+ private:
+ bool m_deterministic;
mutable std::normal_distribution<T> m_distribution;
mutable std::mt19937 m_generator;
};
@@ -393,22 +429,28 @@ template <> class NormalRandomGenerator<float> {
public:
static const bool PacketAccess = true;
- EIGEN_DEVICE_FUNC NormalRandomGenerator(bool deterministic = true) {
+ __device__ NormalRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {
const int tid = blockIdx.x * blockDim.x + threadIdx.x;
const int seed = deterministic ? 0 : get_random_seed();
curand_init(seed, tid, 0, &m_state);
}
-
+ __device__ NormalRandomGenerator(const NormalRandomGenerator<float>& other) {
+ m_deterministic = other.m_deterministic;
+ const int tid = blockIdx.x * blockDim.x + threadIdx.x;
+ const int seed = m_deterministic ? 0 : get_random_seed();
+ curand_init(seed, tid, 0, &m_state);
+ }
template<typename Index>
- EIGEN_DEVICE_FUNC float operator()(Index, Index = 0) const {
+ __device__ float operator()(Index, Index = 0) const {
return curand_normal(&m_state);
}
template<typename Index>
- EIGEN_DEVICE_FUNC float4 packetOp(Index, Index = 0) const {
+ __device__ float4 packetOp(Index, Index = 0) const {
return curand_normal4(&m_state);
}
private:
+ bool m_deterministic;
mutable curandStatePhilox4_32_10_t m_state;
};
@@ -416,21 +458,28 @@ template <> class NormalRandomGenerator<double> {
public:
static const bool PacketAccess = true;
- EIGEN_DEVICE_FUNC NormalRandomGenerator(bool deterministic = true) {
+ __device__ NormalRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {
const int tid = blockIdx.x * blockDim.x + threadIdx.x;
const int seed = deterministic ? 0 : get_random_seed();
curand_init(seed, tid, 0, &m_state);
}
+ __device__ NormalRandomGenerator(const NormalRandomGenerator<double>& other) {
+ m_deterministic = other.m_deterministic;
+ const int tid = blockIdx.x * blockDim.x + threadIdx.x;
+ const int seed = m_deterministic ? 0 : get_random_seed();
+ curand_init(seed, tid, 0, &m_state);
+ }
template<typename Index>
- EIGEN_DEVICE_FUNC double operator()(Index, Index = 0) const {
+ __device__ double operator()(Index, Index = 0) const {
return curand_normal_double(&m_state);
}
template<typename Index>
- EIGEN_DEVICE_FUNC double2 packetOp(Index, Index = 0) const {
+ __device__ double2 packetOp(Index, Index = 0) const {
return curand_normal2_double(&m_state);
}
private:
+ bool m_deterministic;
mutable curandStatePhilox4_32_10_t m_state;
};
@@ -438,7 +487,10 @@ template <> class NormalRandomGenerator<double> {
template <typename T> class NormalRandomGenerator {
public:
- NormalRandomGenerator(bool = true) {}
+ NormalRandomGenerator(bool deterministic = true) : m_deterministic(deterministic) {}
+
+ private:
+ bool m_deterministic;
};
#endif