Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28323 Discussions

RANDOM_SEED and RANDOM number interaction

New Contributor II

In an existing pgm, when I need a bunch of random numbers, I am using the following code:

            CALL RANDOM_SEED (SIZE = seedArraySize)             ! get the size of the seed array
            CALL RANDOM_SEED (GET = seedArray(1:seedArraySize)) ! Reads the current seed
! ...
            CALL RANDOM_NUMBER(rSubset(1:n)) ! get random reals 0-1

This works, but I am wondering whether the random numbers generated will be reproduced if I execute this code twice. Since I have not called RANDOM_SEED with a 'PUT' arg, does Fortran select a random pair of seeds?

When I run this code multiple times, I get successively

seedArraySize=2  seedArray:  1867406816         498
seedArraySize=2  seedArray:  1144153914   961636948
seedArraySize=2  seedArray:   126261596  1969642693
seedArraySize=2  seedArray:   809624081   776615339

Does this mean the seed is updated by calls to RANDOM_NUMBER, or that a different random pair of seeds is chosen each time thru?

If I do a RANDOM_SEED with a 'PUT' arg, before calling RANDOM_NUMBER, will this give the same sequence? I'd like to be able to reproduce the rSubset array for each invocation.

0 Kudos
2 Replies
Black Belt

The compiler reference manual says "If RANDOM_SEED is not used, the processor sets the seed for RANDOM_NUMBER to a processor-dependent value". Many library RNG routines use a default seed/seeds based on the system clock. Since about five years ago, many Intel CPUs have an RDRAND instruction that can also be used for that purpose.

For debugging purposes, it is useful to have a reproducible sequence of pseudo-random numbers. Therefore, at least when debugging a program that calls RANDOM_NUMBER, one should provide ones own seeds with the PUT optional argument (as you have considered). If you are puzzled by what to choose for that PUT argument, you can print out the results from GET in an initial run and use that pair of integers with PUT in subsequent runs of your program.

After debugging, you can remove that initialization and let the default method take over. After all, most users would not want a random sequence to start at the same point in the cycle.

0 Kudos
Black Belt

The standard requires the same sequence when you PUT a specific set of seed values. You don't need to do a PUT following a GET - that's redundant - but it won't hurt. Note that the standard DOESN'T say that if you do a GET following a PUT that you get the same seed values, only that the sequence is the same.

The standard doesn't specify what the default behavior is if you don't call RANDOM_SEED with PUT. If you want the same sequence every time, have your program do a PUT with the same value. (Of course, you need to first determine the size of the seed.)

Fortran 2018 adds a RANDOM_INIT intrinsic that allows you to easily specify whether you want the same sequence every run or a different sequence. It also controls whether you get one sequence across all images in a coarray program, or whether each image has its own sequence. Intel Fortran doesn't yet support that. What Intel does support is calling RANDOM_SEED with no arguments, causing it to give a different sequence each time. The standard doesn't specify this behavior, but many implementations do this.