mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-01-18 14:34:17 +08:00
Added support for generation of random complex numbers on CUDA devices
This commit is contained in:
parent
6de6fa9483
commit
e6297741c9
@ -387,6 +387,58 @@ template <> class UniformRandomGenerator<double> {
|
||||
mutable curandStatePhilox4_32_10_t m_state;
|
||||
};
|
||||
|
||||
template <> class UniformRandomGenerator<std::complex<float> > {
|
||||
public:
|
||||
static const bool PacketAccess = false;
|
||||
|
||||
__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>
|
||||
__device__ std::complex<float> operator()(Index, Index = 0) const {
|
||||
float4 vals = curand_uniform4(&m_state);
|
||||
return std::complex<float>(vals.x, vals.y);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_deterministic;
|
||||
mutable curandStatePhilox4_32_10_t m_state;
|
||||
};
|
||||
|
||||
template <> class UniformRandomGenerator<std::complex<double> > {
|
||||
public:
|
||||
static const bool PacketAccess = false;
|
||||
|
||||
__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>
|
||||
__device__ std::complex<double> operator()(Index, Index = 0) const {
|
||||
double2 vals = curand_uniform2_double(&m_state);
|
||||
return std::complex<double>(vals.x, vals.y);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_deterministic;
|
||||
mutable curandStatePhilox4_32_10_t m_state;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -489,6 +541,58 @@ template <> class NormalRandomGenerator<double> {
|
||||
mutable curandStatePhilox4_32_10_t m_state;
|
||||
};
|
||||
|
||||
template <> class NormalRandomGenerator<std::complex<float> > {
|
||||
public:
|
||||
static const bool PacketAccess = false;
|
||||
|
||||
__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& 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>
|
||||
__device__ std::complex<float> operator()(Index, Index = 0) const {
|
||||
float4 vals = curand_normal4(&m_state);
|
||||
return std::complex<float>(vals.x, vals.y);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_deterministic;
|
||||
mutable curandStatePhilox4_32_10_t m_state;
|
||||
};
|
||||
|
||||
template <> class NormalRandomGenerator<std::complex<double> > {
|
||||
public:
|
||||
static const bool PacketAccess = false;
|
||||
|
||||
__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& 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>
|
||||
__device__ std::complex<double> operator()(Index, Index = 0) const {
|
||||
double2 vals = curand_normal2_double(&m_state);
|
||||
return std::complex<double>(vals.x, vals.y);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_deterministic;
|
||||
mutable curandStatePhilox4_32_10_t m_state;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <typename T> class NormalRandomGenerator {
|
||||
|
@ -144,5 +144,6 @@ if(EIGEN_TEST_CXX11)
|
||||
# ei_add_test(cxx11_tensor_cuda "-std=c++0x")
|
||||
# ei_add_test(cxx11_tensor_contract_cuda "-std=c++0x")
|
||||
# ei_add_test(cxx11_tensor_reduction_cuda "-std=c++0x")
|
||||
# ei_add_test(cxx11_tensor_random_cuda "-std=c++0x")
|
||||
|
||||
endif()
|
||||
|
35
unsupported/test/cxx11_tensor_random_cuda.cpp
Normal file
35
unsupported/test/cxx11_tensor_random_cuda.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#define EIGEN_TEST_NO_LONGDOUBLE
|
||||
#define EIGEN_TEST_NO_COMPLEX
|
||||
#define EIGEN_TEST_FUNC cxx11_tensor_random_cuda
|
||||
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
|
||||
#define EIGEN_USE_GPU
|
||||
|
||||
#include "main.h"
|
||||
#include <Eigen/CXX11/Tensor>
|
||||
|
||||
static void test_default()
|
||||
{
|
||||
Tensor<std::complex<float>, 1> vec(6);
|
||||
vec.setRandom();
|
||||
|
||||
// Fixme: we should check that the generated numbers follow a uniform
|
||||
// distribution instead.
|
||||
for (int i = 1; i < 6; ++i) {
|
||||
VERIFY_IS_NOT_EQUAL(vec(i), vec(i-1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test_cxx11_tensor_random_cuda()
|
||||
{
|
||||
CALL_SUBTEST(test_default());
|
||||
}
|
Loading…
Reference in New Issue
Block a user