Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26757 Discussions

Initializing the random_seed with /dev/urandom

Vishnu
Novice
241 Views

The example given on the GCC page for the same, uses /dev/urandom is as follows:

          subroutine init_random_seed()

            use iso_fortran_env, only: int64

            implicit none
            integer, allocatable :: seed(:)
            integer :: i, n, un, istat, dt(8), pid
            integer(int64) :: t
          
            call random_seed(size = n)
            allocate(seed(n))
            ! First try if the OS provides a random number generator

            open(newunit=un, file="/dev/urandom", access="stream", &
                 form="unformatted", action="read", status="old", iostat=istat)

            if (istat == 0) then
               read(un) seed
               close(un)
            else
            .
            .
            end if
            call random_seed(put=seed)

          end subroutine init_random_seed

 

I have a couple of questions:

  • Shouldn't the 'FORM' of the file opened be "BINARY"?
  • I don't understand how much data the READ pulls from /dev/urandom.
  • Here /dev/urandom is just used to initialize the seed for RANDOM_NUMBER(). But is there a way I can directly use /dev/urandom?
0 Kudos
1 Solution
mecej4
Black Belt
241 Views

FORM='binary' is non-standard and was provided by some compilers before ACCESS='stream' became available in the Fortran standard. Intel Fortran supports lots of "legacy" features, and FORM='binary' is one of them. In new code, you should not use such features.

The purpose of the call to RANDOM_SEED with the SIZE=n argument is to query the RNG provided by the Fortran RTL. The query returns the size n, which is then used to allocate a sufficiently large array and to obtain values from /dev/urandom to fill that array. If the two lines that you marked with "." are left blank, you get yet another (but definitely insecure) seeding technique -- using a just-recently allocated variable without initialization.

There are many reasons for choosing one RNG over another. The "shopper"'s needs may range from "as secure as possible", for example in crypto-applications, to "reasonably random but really fast" for Monte-Carlo simulations.

In the debugging stage of program development, experienced programmers may use their own pet seeds in order to ensure reproducibility and, after debugging is completed, switch to a different method of setting the seed.

View solution in original post

7 Replies
mecej4
Black Belt
242 Views

FORM='binary' is non-standard and was provided by some compilers before ACCESS='stream' became available in the Fortran standard. Intel Fortran supports lots of "legacy" features, and FORM='binary' is one of them. In new code, you should not use such features.

The purpose of the call to RANDOM_SEED with the SIZE=n argument is to query the RNG provided by the Fortran RTL. The query returns the size n, which is then used to allocate a sufficiently large array and to obtain values from /dev/urandom to fill that array. If the two lines that you marked with "." are left blank, you get yet another (but definitely insecure) seeding technique -- using a just-recently allocated variable without initialization.

There are many reasons for choosing one RNG over another. The "shopper"'s needs may range from "as secure as possible", for example in crypto-applications, to "reasonably random but really fast" for Monte-Carlo simulations.

In the debugging stage of program development, experienced programmers may use their own pet seeds in order to ensure reproducibility and, after debugging is completed, switch to a different method of setting the seed.

View solution in original post

Vishnu
Novice
241 Views

mecej4 wrote:

The purpose of the call to RANDOM_SEED with the SIZE=n argument is to query the RNG provided by the Fortran RTL. The query returns the size n, which is then used to allocate a sufficiently large array and to obtain values from /dev/urandom to fill that array.

Okay, but where is 'n' defined?

I need a "reasonably random but really fast" generation of random numbers, but I suppose the seed won't affect the speed, as it is a one time thing. I use the RANDOM_NUMBER function, which I assume is the fastest possible option for serial generation.

Steve_Lionel
Black Belt Retired Employee
241 Views

If you call RANDOM_SEED with no arguments, the seed is set to a value based on the clock (in Intel Fortran - this is unspecified by the standard). ifort's RANDOM_NUMBER is reasonably fast, but one could come up with faster algorithms.

mecej4
Black Belt
241 Views

Vishnu wrote:

Okay, but where is 'n' defined?

The question suggests that you think that your chosen value of n is to be passed to the RNG. On the contrary, this is an "inquiry" call, asking the RNG to divulge the size of the seed that it uses. The IFort documentation says:

size

(Output; optional) Must be scalar and of type integer. Set to the number of integers (N) that the processor uses to hold the value of the seed.

For many simple RNG-s, n = 1 (i.e., the seed is a single integer).

Steve_Lionel
Black Belt Retired Employee
241 Views

ifort uses two 32-bit values for the seed. The algorithm is based on L'Ecuyer '90.

Vishnu
Novice
241 Views

Steve Lionel (Ret.) wrote:

but one could come up with faster algorithms

Could you point me in their direction, if you know any? I would've thought that the fastest way would be to use '/dev/random' and use a function onto what ever space I want, say, real: [0,1), but then would it guarantee a distribution? I suppose that would depend on the specific function I used. Is there such an implementation already available?

mecej4 , Thanks for all the fish!

Steve_Lionel
Black Belt Retired Employee
241 Views

Do you want good or fast? See https://en.wikipedia.org/wiki/Linear_congruential_generator for simple ones. More uniform generators are more complex. I have no idea what /dev/random uses, and really, neither do you.

Reply