xref: /netbsd-src/external/gpl3/gcc.old/dist/libgfortran/intrinsics/random_init.f90 (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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