如何保证随机数生成器seed每次推力都不一样
How to guarantee the random number generator seed to be different each time in thrust
当我们编写 CUDA 内核时,我们总是这样做以保证种子可以更新。
__global__ void kernel(curandState *globalState){
curandState *localState;
localState = globalState;
// generate random number with localState.
globalState = localState;
}
而如果我们运行内核多次,随机数总是不同的。
我的问题是,如果我们想根据这个问题使用推力生成随机数:
Generating a random number vector between 0 and 1.0 using Thrust
和 talonmies 的回答,当我们需要使用同一个函子 prg
多次 运行 时,我们如何为每个操作提供不同的种子?
我尝试重写代码如下:
#include<thrust/random.h>
#include<thrust/device_vector.h>
#include<thrust/transform.h>
#include<thrust/iterator/counting_iterator.h>
#include<iostream>
#include<time.h>
struct prg
{
float a, b;
unsigned int N;
__host__ __device__
prg(float _a=0.f, float _b=1.f, unsigned int _N = time(NULL)) : a(_a), b(_b), N(_N) {};
__host__ __device__
float operator()(const unsigned int n) const
{
thrust::default_random_engine rng(N);
thrust::uniform_real_distribution<float> dist(a, b);
rng.discard(n);
return dist(rng);
}
};
int main(void)
{
const int N = 5;
thrust::device_vector<float> numbers(N);
thrust::counting_iterator<unsigned int> index_sequence_begin(0);
// first operation
thrust::transform(index_sequence_begin,index_sequence_begin + N, numbers.begin(),prg(1.f,2.f));
for(int i = 0; i < N; i++)
{
std::cout << numbers[i] << std::endl;
}
// second operation
thrust::transform(index_sequence_begin,index_sequence_begin + N, numbers.begin(),prg(1.f,2.f));
for(int i = 0; i < N; i++)
{
std::cout << numbers[i] << std::endl;
}
return 0;
}
第一次运算和第二次运算生成相同的数字。我知道是因为时间差很短,那我应该如何修改代码让这两个操作得到不同的随机数呢?我想可以根据操作时间分配种子,(1,2,.....10000, 10001, ...N),但是这样做会很昂贵吗?
套用 John von Neumann "Nothing as important as random numbers should be left to chance"。
如果您不能保证随机生成器的种子不同(在这种情况下您似乎不能),那么不要尝试使用不同的种子。使用一个种子生成器实例并从中获取不同的序列。
当我们编写 CUDA 内核时,我们总是这样做以保证种子可以更新。
__global__ void kernel(curandState *globalState){
curandState *localState;
localState = globalState;
// generate random number with localState.
globalState = localState;
}
而如果我们运行内核多次,随机数总是不同的。 我的问题是,如果我们想根据这个问题使用推力生成随机数: Generating a random number vector between 0 and 1.0 using Thrust
和 talonmies 的回答,当我们需要使用同一个函子 prg
多次 运行 时,我们如何为每个操作提供不同的种子?
我尝试重写代码如下:
#include<thrust/random.h>
#include<thrust/device_vector.h>
#include<thrust/transform.h>
#include<thrust/iterator/counting_iterator.h>
#include<iostream>
#include<time.h>
struct prg
{
float a, b;
unsigned int N;
__host__ __device__
prg(float _a=0.f, float _b=1.f, unsigned int _N = time(NULL)) : a(_a), b(_b), N(_N) {};
__host__ __device__
float operator()(const unsigned int n) const
{
thrust::default_random_engine rng(N);
thrust::uniform_real_distribution<float> dist(a, b);
rng.discard(n);
return dist(rng);
}
};
int main(void)
{
const int N = 5;
thrust::device_vector<float> numbers(N);
thrust::counting_iterator<unsigned int> index_sequence_begin(0);
// first operation
thrust::transform(index_sequence_begin,index_sequence_begin + N, numbers.begin(),prg(1.f,2.f));
for(int i = 0; i < N; i++)
{
std::cout << numbers[i] << std::endl;
}
// second operation
thrust::transform(index_sequence_begin,index_sequence_begin + N, numbers.begin(),prg(1.f,2.f));
for(int i = 0; i < N; i++)
{
std::cout << numbers[i] << std::endl;
}
return 0;
}
第一次运算和第二次运算生成相同的数字。我知道是因为时间差很短,那我应该如何修改代码让这两个操作得到不同的随机数呢?我想可以根据操作时间分配种子,(1,2,.....10000, 10001, ...N),但是这样做会很昂贵吗?
套用 John von Neumann "Nothing as important as random numbers should be left to chance"。
如果您不能保证随机生成器的种子不同(在这种情况下您似乎不能),那么不要尝试使用不同的种子。使用一个种子生成器实例并从中获取不同的序列。