Fortran random seed initialization

less than 1 minute read

Fortran 2018 specifies a new subroutine random_init(). To accommodate compilers that haven’t yet added this critical function, I use the subroutine below for Linux and MacOS.

program testinit

implicit none

call init_random_seed()


contains


subroutine init_random_seed()
  ! NOTE: this subroutine is replaced by "call random_init()" intrinsic of Fortran 2018
  integer :: n, u,ios
  integer, allocatable :: seed(:)

  call random_seed(size=n)
  allocate(seed(n))
  
  open(newunit=u, file='/dev/urandom', access="stream", &
               form="unformatted", action="read", status="old", iostat=ios)
  if (ios/=0) error stop 'failed to open random source generator'
  
  read(u,iostat=ios) seed
  if (ios/=0) error stop 'failed to read random source generator'
  
  close(u)
  
  call random_seed(put=seed)
  
  
  print *,'seed: ',seed    ! for debug/test

end subroutine

end program

Windows

For Windows, /dev/urandom is not available. Various methods have been proposed to make calls to system_clock. I cannot speak as to the quality of such methods. If you have a need for this on Windows, check in with Steve Kargl as noted below, if random_init is not yet available on your compiler.

Notes

  • Steve Kargl has implemented random_init for gfortran, for a future release (it’s not in Gfortran 8.1).
  • subroutine above is based on OpenCoarray’s init_random_seed
  • gfortran and ifort: call random_seed() give unique seed
  • flang and pgf90: call random_seed() does NOT give unique seed.

Leave a comment