1*b1e83836Smrg! Copyright (C) 2018-2022 Free Software Foundation, Inc. 2181254a7Smrg! Contributed by Steven G. Kargl <kargl@gcc.gnu.org> 3181254a7Smrg! 4181254a7Smrg! This file is part of the GNU Fortran runtime library (libgfortran). 5181254a7Smrg! 6181254a7Smrg! Libgfortran is free software; you can redistribute it and/or 7181254a7Smrg! modify it under the terms of the GNU General Public 8181254a7Smrg! License as published by the Free Software Foundation; either 9181254a7Smrg! version 3 of the License, or (at your option) any later version. 10181254a7Smrg! 11181254a7Smrg! Libgfortran is distributed in the hope that it will be useful, 12181254a7Smrg! but WITHOUT ANY WARRANTY; without even the implied warranty of 13181254a7Smrg! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14181254a7Smrg! GNU General Public License for more details. 15181254a7Smrg! 16181254a7Smrg! Under Section 7 of GPL version 3, you are granted additional 17181254a7Smrg! permissions described in the GCC Runtime Library Exception, version 18181254a7Smrg! 3.1, as published by the Free Software Foundation. 19181254a7Smrg! 20181254a7Smrg! You should have received a copy of the GNU General Public License and 21181254a7Smrg! a copy of the GCC Runtime Library Exception along with this program; 22181254a7Smrg! see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23181254a7Smrg! <http://www.gnu.org/licenses/>. 24181254a7Smrg! 25181254a7Smrg! WARNING: This file should never be compiled with an option that changes 26181254a7Smrg! default logical kind from 4 to some other value or changes default integer 27*b1e83836Smrg! kind from 4 to some other value. 28181254a7Smrg! 29*b1e83836Smrg! There are four combinations of repeatable and image_distinct. The 30*b1e83836Smrg! language below is from the F2018 standard (actually, J3/18-007r1). 31181254a7Smrg! 32*b1e83836Smrg! This routine is only used for non-coarray programs or with programs 33*b1e83836Smrg! compiled with -fcoarray=single. Use of -fcoarray=lib or -fcoarray=shared 34*b1e83836Smrg! requires different routines due to the need for communication between 35*b1e83836Smrg! images under case(iv). 36181254a7Smrg! 37*b1e83836Smrg! Technically, neither image_distinct nor image_num are now needed. The 38*b1e83836Smrg! interface to _gfortran_random_init() is maintained for libgfortran ABI. 39*b1e83836Smrg! Note, the Fortran standard requires the image_distinct argument, so 40*b1e83836Smrg! it will always have a valid value, and the frontend generates an value 41*b1e83836Smrg! of 0 for image_num. 42181254a7Smrg! 43*b1e83836Smrgimpure subroutine _gfortran_random_init(repeatable, image_distinct, image_num) 44181254a7Smrg 45181254a7Smrg implicit none 46181254a7Smrg 47181254a7Smrg logical, value, intent(in) :: repeatable 48181254a7Smrg logical, value, intent(in) :: image_distinct 49*b1e83836Smrg integer, value, intent(in) :: image_num 50181254a7Smrg 51181254a7Smrg logical, save :: once = .true. 52*b1e83836Smrg integer :: nseed, lcg_seed 53181254a7Smrg integer, save, allocatable :: seed(:) 54181254a7Smrg 55*b1e83836Smrg if (repeatable) then 56181254a7Smrg if (once) then 57181254a7Smrg once = .false. 58181254a7Smrg call random_seed(size=nseed) 59181254a7Smrg allocate(seed(nseed)) 60*b1e83836Smrg lcg_seed = 57911963 61*b1e83836Smrg call _gfortran_lcg(seed) 62*b1e83836Smrg end if 63*b1e83836Smrg call random_seed(put=seed) 64*b1e83836Smrg else 65*b1e83836Smrg call random_seed() 66181254a7Smrg ! 67*b1e83836Smrg ! This cannot happen; but, prevent gfortran complaining about 68*b1e83836Smrg ! unused variables. 69181254a7Smrg ! 70*b1e83836Smrg if (image_num > 2) then 71*b1e83836Smrg block 72*b1e83836Smrg use iso_fortran_env, only : error_unit 73*b1e83836Smrg write(error_unit, '(A)') 'whoops: random_init(.false., .false.)' 74*b1e83836Smrg if (image_distinct) error stop image_num + 1 75*b1e83836Smrg error stop image_num 76*b1e83836Smrg end block 77*b1e83836Smrg end if 78181254a7Smrg end if 79181254a7Smrg 80*b1e83836Smrg contains 81*b1e83836Smrg ! 82*b1e83836Smrg ! SK Park and KW Miller, ``Random number generators: good ones are hard 83*b1e83836Smrg ! to find,'' Comm. ACM, 31(10), 1192--1201, (1988). 84*b1e83836Smrg ! 85*b1e83836Smrg ! Implementation of a prime modulus multiplicative linear congruential 86*b1e83836Smrg ! generator, which avoids overflow and provides the full period. 87*b1e83836Smrg ! 88*b1e83836Smrg impure elemental subroutine _gfortran_lcg(i) 89*b1e83836Smrg implicit none 90*b1e83836Smrg integer, intent(out) :: i 91*b1e83836Smrg integer, parameter :: a = 16807 ! Multiplier 92*b1e83836Smrg integer, parameter :: m = huge(a) ! Modulus 93*b1e83836Smrg integer, parameter :: q = 127773 ! Quotient to avoid overflow 94*b1e83836Smrg integer, parameter :: r = 2836 ! Remainder to avoid overflow 95*b1e83836Smrg lcg_seed = a * mod(lcg_seed, q) - r * (lcg_seed / q) 96*b1e83836Smrg if (lcg_seed <= 0) lcg_seed = lcg_seed + m 97*b1e83836Smrg i = lcg_seed 98*b1e83836Smrg end subroutine _gfortran_lcg 99181254a7Smrg 100181254a7Smrgend subroutine _gfortran_random_init 101