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
で数回実行する必要があり、我々は異なるシードを持っている可能性がどのように: 私の質問は、私たちがこの質問に基づいて乱数を生成するための推力を使用する場合ということです各操作のために? Iは、次のようにコードを書き換えることを試みた:
#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動作は同じ番号を生成します。時差が短いため、この2つの操作で異なる乱数を得るためにコードをどのように変更すればよいのでしょうか?私は操作時間、(1,2、..... 10000、10001、... N)に基づいてシードを割り当てることは可能だと思いますが、それを行うには高価でしょうか?
ありがとう、@タロン。それをするのは費用がかかりますか?例えば、各ループiはrng(i)を取る。 –
違いはありません。変換呼び出しに異なるオフセットを渡しているだけです。 – talonmies
もう一度ありがとうございます。私はそれをテストし、ellapseがほぼ同じ時間を見つける。 –