No replicability within threadFor loops

I use Gauss 15.1.3. build 4092. I have set a random seed (rndseed 63579246;) at the beginning of the code. Then I have generated uniformly distributed random numbers (rndu) within a threadFor loop. But every time I restart the program, the random numbers change (that does not happen within for/endfor loops). This implies that my multithreaded results are not replicable.

How can I solve this problem?

1 Answer



0



threadfor loop iterations can run in any order. When you use the global random number state with rndseed, the random numbers created will always come out in the same order. However, in a threadfor loop, since the threads may be run in a different order each time the program is executed, the threads may well get different chunks of the random numbers each time the program is executed.

You have a few options for how to make repeatable random numbers within a threadfor loop.

Create the random numbers before the threadfor loop
If the memory taken up by the entire set of needed random numbers is not too large and it suits the algorithm of your program, you may be best off creating all the random numbers you need ahead of time and then indexing into this matrix or vector as needed.

Use the skip-ahead feature
Some of the GAUSS random number generators, such as the MRG32k3a allow skip-ahead. This means that you can create an initial state vector (like a bookmark in the random number stream) and then from that state vector, you can create another state vector that is ahead of the first by N elements. Here is a brief example:

//Create a random number state with a
//random number generator that supports
//skip ahead
state = rndCreateState("mrg32k3a", 23423);

iters = 4;
nobs = 5;

//Pre-allocate 'r' to hold all random numbers
//created in 'threadfor' loop
r = zeros(iters * nobs, 1);

threadfor i(1, iters, 1);
    
    //Create 'state_tmp' to be the original state vector
    //incremented by 'nobs' numbers for each iteration
    //after the 1st
    state_tmp = rndStateSkip((i-1) * nobs, state);

    //increment starting index for next iteration
    idx = (i - 1) * nobs + 1;

    //Create block of random numbers and assign
    //to corresponding section of 'r' vector
    { r[idx:idx+nobs-1], s } = rndu(nobs,1, state_tmp);
    

threadendfor;

state = rndCreateState("mrg32k3a", 23423);
{ r_1, s } = rndu(iters * nobs, 1, state);

aptech

1,773

Your Answer

1 Answer

0

threadfor loop iterations can run in any order. When you use the global random number state with rndseed, the random numbers created will always come out in the same order. However, in a threadfor loop, since the threads may be run in a different order each time the program is executed, the threads may well get different chunks of the random numbers each time the program is executed.

You have a few options for how to make repeatable random numbers within a threadfor loop.

Create the random numbers before the threadfor loop
If the memory taken up by the entire set of needed random numbers is not too large and it suits the algorithm of your program, you may be best off creating all the random numbers you need ahead of time and then indexing into this matrix or vector as needed.

Use the skip-ahead feature
Some of the GAUSS random number generators, such as the MRG32k3a allow skip-ahead. This means that you can create an initial state vector (like a bookmark in the random number stream) and then from that state vector, you can create another state vector that is ahead of the first by N elements. Here is a brief example:

//Create a random number state with a
//random number generator that supports
//skip ahead
state = rndCreateState("mrg32k3a", 23423);

iters = 4;
nobs = 5;

//Pre-allocate 'r' to hold all random numbers
//created in 'threadfor' loop
r = zeros(iters * nobs, 1);

threadfor i(1, iters, 1);
    
    //Create 'state_tmp' to be the original state vector
    //incremented by 'nobs' numbers for each iteration
    //after the 1st
    state_tmp = rndStateSkip((i-1) * nobs, state);

    //increment starting index for next iteration
    idx = (i - 1) * nobs + 1;

    //Create block of random numbers and assign
    //to corresponding section of 'r' vector
    { r[idx:idx+nobs-1], s } = rndu(nobs,1, state_tmp);
    

threadendfor;

state = rndCreateState("mrg32k3a", 23423);
{ r_1, s } = rndu(iters * nobs, 1, state);

You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.