1*4c3eb207Smrg! Copyright (C) 2018-2020 Free Software Foundation, Inc. 2627f7eb2Smrg! Contributed by Steven G. Kargl <kargl@gcc.gnu.org> 3627f7eb2Smrg! 4627f7eb2Smrg! This file is part of the GNU Fortran runtime library (libgfortran). 5627f7eb2Smrg! 6627f7eb2Smrg! Libgfortran is free software; you can redistribute it and/or 7627f7eb2Smrg! modify it under the terms of the GNU General Public 8627f7eb2Smrg! License as published by the Free Software Foundation; either 9627f7eb2Smrg! version 3 of the License, or (at your option) any later version. 10627f7eb2Smrg! 11627f7eb2Smrg! Libgfortran is distributed in the hope that it will be useful, 12627f7eb2Smrg! but WITHOUT ANY WARRANTY; without even the implied warranty of 13627f7eb2Smrg! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14627f7eb2Smrg! GNU General Public License for more details. 15627f7eb2Smrg! 16627f7eb2Smrg! Under Section 7 of GPL version 3, you are granted additional 17627f7eb2Smrg! permissions described in the GCC Runtime Library Exception, version 18627f7eb2Smrg! 3.1, as published by the Free Software Foundation. 19627f7eb2Smrg! 20627f7eb2Smrg! You should have received a copy of the GNU General Public License and 21627f7eb2Smrg! a copy of the GCC Runtime Library Exception along with this program; 22627f7eb2Smrg! see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23627f7eb2Smrg! <http://www.gnu.org/licenses/>. 24627f7eb2Smrg! 25627f7eb2Smrg! 26627f7eb2Smrg! WARNING: This file should never be compiled with an option that changes 27627f7eb2Smrg! default logical kind from 4 to some other value or changes default integer 28627f7eb2Smrg! kind from from 4 to some other value. 29627f7eb2Smrg! 30627f7eb2Smrg! 31627f7eb2Smrg! There are four combinations of repeatable and image_distinct. If a program 32627f7eb2Smrg! is compiled without the -fcoarray= option or with -fcoarray=single, then 33627f7eb2Smrg! execution of the compiled executable does not use image_distinct as it is 34627f7eb2Smrg! irrelevant (although required). The behavior is as follows: 35627f7eb2Smrg! 36627f7eb2Smrg! call random_init(.true., .true.) 37627f7eb2Smrg! 38627f7eb2Smrg! The sequence of random numbers is repeatable within an instance of program 39627f7eb2Smrg! execution. That is, calls to random_init(.true., .true.) during the 40627f7eb2Smrg! execution will reset the sequence of RN to the same sequence. If the 41627f7eb2Smrg! program is compiled with -fcoarray=lib and multiple images are instantiated, 42627f7eb2Smrg! then each image accesses a repeatable distinct sequence of random numbers. 43627f7eb2Smrg! There are no guarantees that multiple execution of the program will access 44627f7eb2Smrg! the same sequence. 45627f7eb2Smrg! 46627f7eb2Smrg! call random_init(.false., .false.) 47627f7eb2Smrg! call random_init(.false., .true.) 48627f7eb2Smrg! 49627f7eb2Smrg! The sequence of random numbers is determined from process-dependent seeds. 50627f7eb2Smrg! On each execution of the executable, different seeds will be used. For 51627f7eb2Smrg! -fcoarray=lib and multiple instantiated images, each image will use 52627f7eb2Smrg! process-dependent seeds. In other words, the two calls have identical 53627f7eb2Smrg! behavior. 54627f7eb2Smrg! 55627f7eb2Smrg! call random_init(.true., .false.) 56627f7eb2Smrg! 57627f7eb2Smrg! For a program compiled without the -fcoarray= option or with 58627f7eb2Smrg! -fcoarray=single, a single image is instantiated when the executable is 59627f7eb2Smrg! run. If the executable causes multiple images to be instantiated, then 60627f7eb2Smrg! image_distinct=.false. in one image cannot affect the sequence of random 61627f7eb2Smrg! numbers in another image. As gfortran gives each image its own independent 62627f7eb2Smrg! PRNG, this condition is automatically satisfied. 63627f7eb2Smrg! 64627f7eb2Smrgimpure subroutine _gfortran_random_init(repeatable, image_distinct, hidden) 65627f7eb2Smrg 66627f7eb2Smrg implicit none 67627f7eb2Smrg 68627f7eb2Smrg logical, value, intent(in) :: repeatable 69627f7eb2Smrg logical, value, intent(in) :: image_distinct 70627f7eb2Smrg integer, value, intent(in) :: hidden 71627f7eb2Smrg 72627f7eb2Smrg logical, save :: once = .true. 73627f7eb2Smrg integer :: nseed 74627f7eb2Smrg integer, save, allocatable :: seed(:) 75627f7eb2Smrg 76627f7eb2Smrg if (once) then 77627f7eb2Smrg once = .false. 78627f7eb2Smrg call random_seed(size=nseed) 79627f7eb2Smrg allocate(seed(nseed)) 80627f7eb2Smrg call random_seed(get=seed) 81627f7eb2Smrg ! 82627f7eb2Smrg ! To guarantee that seed is distinct on multiple images, add the hidden 83627f7eb2Smrg ! argument (which is the image index). 84627f7eb2Smrg ! 85627f7eb2Smrg if (image_distinct) seed = seed + hidden 86627f7eb2Smrg end if 87627f7eb2Smrg 88627f7eb2Smrg if (repeatable) then 89627f7eb2Smrg call random_seed(put=seed); 90627f7eb2Smrg else 91627f7eb2Smrg call random_seed(); 92627f7eb2Smrg end if 93627f7eb2Smrg 94627f7eb2Smrgend subroutine _gfortran_random_init 95