Fly_back
Fly_back

Reputation: 269

How to guarantee the random number generator seed to be different each time in thrust

When we write a CUDA kernel, we always do this to guarantee the seed can be updated.

__global__ void kernel(curandState *globalState){
      curandState *localState;
      localState  = globalState;
      // generate random number with localState.
      globalState = localState;
}

and if we run the kernel for several times, the random number can always be different. My question is that if we want to use thrust to generate random number based on this question: Generating a random number vector between 0 and 1.0 using Thrust

and talonmies' answer, when we need to run several times with the same functor prg, how we could have different seed for each operation? I tried to rewrite the code as following:

#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;
}

The first operation and second operation generate the same number. I know it is because the time difference is short, then how should I modify the code to get different random numbers for these two operations? I guess it is possible to assign the seed based on the operation time,(1,2,.....10000, 10001, ...N), but will it be expensive to do that?

Upvotes: 1

Views: 1020

Answers (1)

talonmies
talonmies

Reputation: 72349

To paraphrase John von Neumann "Nothing as important as random numbers should be left to chance".

If you cannot guarantee that the seeds for the random generators are different (and it appears you cannot in this case), then don't try and have different seeds. Use one seeded generator instance and take different sequences from it.

Upvotes: 3

Related Questions