Commit 0e99e093 by Janne Blomqvist

PR fortran/91414: Improved PRNG

Update the PRNG from xorshift1024* to xoshiro256** by the same
author. For details see

http://prng.di.unimi.it/

and the paper at

https://arxiv.org/abs/1805.01407

Also the seeding is slightly improved, by reading only 8 bytes from
the operating system and using the simple splitmix64 PRNG to fill in
the rest of the PRNG state (as recommended by the xoshiro author),
instead of reading the entire state from the OS.

Regtested on x86_64-pc-linux-gnu, Ok for trunk?

gcc/fortran/ChangeLog:

2019-08-13  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/91414
	* check.c (gfc_check_random_seed): Reduce seed_size.
	* intrinsic.texi (RANDOM_NUMBER): Update to match new PRNG.

gcc/testsuite/ChangeLog:

2019-08-13  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/91414
	* gfortran.dg/random_seed_1.f90: Update to match new seed size.

libgfortran/ChangeLog:

2019-08-13  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/91414
	* intrinsics/random.c (prng_state): Update state struct.
	(master_state): Update to match new size.
	(get_rand_state): Update to match new PRNG.
	(rotl): New function.
	(xorshift1024star): Replace with prng_next.
	(prng_next): New function.
	(jump): Update for new PRNG.
	(lcg_parkmiller): Replace with splitmix64.
	(splitmix64): New function.
	(getosrandom): Fix return value, simplify.
	(init_rand_state): Use getosrandom only to get 8 bytes, splitmix64
	to fill rest of state.
	(random_r4): Update to new function and struct names.
	(random_r8): Likewise.
	(random_r10): Likewise.
	(random_r16): Likewise.
	(arandom_r4): Liekwise.
	(arandom_r8): Likewise.
	(arandom_r10): Likwewise.
	(arandom_r16): Likewise.
	(xor_keys): Reduce size to match new PRNG.
	(random_seed_i4): Update to new function and struct names, remove
	special handling of variable p used in previous PRNG.
	(random_seed_i8): Likewise.

From-SVN: r274361
parent 519acab0
2019-08-13 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/91414
* check.c (gfc_check_random_seed): Reduce seed_size.
* intrinsic.texi (RANDOM_NUMBER): Update to match new PRNG.
2019-08-12 Thomas Koenig <tkoenig@gcc.gnu.org> 2019-08-12 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/91424 PR fortran/91424
......
...@@ -6484,9 +6484,8 @@ gfc_check_random_seed (gfc_expr *size, gfc_expr *put, gfc_expr *get) ...@@ -6484,9 +6484,8 @@ gfc_check_random_seed (gfc_expr *size, gfc_expr *put, gfc_expr *get)
mpz_t put_size, get_size; mpz_t put_size, get_size;
/* Keep the number of bytes in sync with master_state in /* Keep the number of bytes in sync with master_state in
libgfortran/intrinsics/random.c. +1 due to the integer p which is libgfortran/intrinsics/random.c. */
part of the state too. */ seed_size = 32 / gfc_default_integer_kind;
seed_size = 128 / gfc_default_integer_kind + 1;
if (size != NULL) if (size != NULL)
{ {
......
...@@ -11792,10 +11792,10 @@ end program test_random_seed ...@@ -11792,10 +11792,10 @@ end program test_random_seed
Returns a single pseudorandom number or an array of pseudorandom numbers Returns a single pseudorandom number or an array of pseudorandom numbers
from the uniform distribution over the range @math{ 0 \leq x < 1}. from the uniform distribution over the range @math{ 0 \leq x < 1}.
The runtime-library implements the xorshift1024* random number The runtime-library implements the xoshiro256** pseudorandom number
generator (RNG). This generator has a period of @math{2^{1024} - 1}, generator (PRNG). This generator has a period of @math{2^{256} - 1},
and when using multiple threads up to @math{2^{512}} threads can each and when using multiple threads up to @math{2^{128}} threads can each
generate @math{2^{512}} random numbers before any aliasing occurs. generate @math{2^{128}} random numbers before any aliasing occurs.
Note that in a multi-threaded program (e.g. using OpenMP directives), Note that in a multi-threaded program (e.g. using OpenMP directives),
each thread will have its own random number state. For details of the each thread will have its own random number state. For details of the
...@@ -11852,7 +11852,7 @@ called either without arguments or with the @var{PUT} argument, the ...@@ -11852,7 +11852,7 @@ called either without arguments or with the @var{PUT} argument, the
given seed is copied into a master seed as well as the seed of the given seed is copied into a master seed as well as the seed of the
current thread. When a new thread uses @code{RANDOM_NUMBER} for the current thread. When a new thread uses @code{RANDOM_NUMBER} for the
first time, the seed is copied from the master seed, and forwarded first time, the seed is copied from the master seed, and forwarded
@math{N * 2^{512}} steps to guarantee that the random stream does not @math{N * 2^{128}} steps to guarantee that the random stream does not
alias any other stream in the system, where @var{N} is the number of alias any other stream in the system, where @var{N} is the number of
threads that have used @code{RANDOM_NUMBER} so far during the program threads that have used @code{RANDOM_NUMBER} so far during the program
execution. execution.
......
2019-08-13 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/91414
* gfortran.dg/random_seed_1.f90: Update to match new seed size.
2019-08-13 Eric Botcazou <ebotcazou@adacore.com> 2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/discr56.adb, gnat.dg/discr56.ads, * gnat.dg/discr56.adb, gnat.dg/discr56.ads,
......
...@@ -10,11 +10,12 @@ ...@@ -10,11 +10,12 @@
PROGRAM random_seed_1 PROGRAM random_seed_1
IMPLICIT NONE IMPLICIT NONE
INTEGER, PARAMETER :: nbytes = 128 ! Should match sizeof(master_state) in
! libgfortran/intrinsics/random.c
INTEGER, PARAMETER :: nbytes = 32
! +1 due to the special 'p' value in xorshift1024*
! '+1' to avoid out-of-bounds warnings ! '+1' to avoid out-of-bounds warnings
INTEGER, PARAMETER :: n = nbytes / KIND(n) + 2 INTEGER, PARAMETER :: n = nbytes / KIND(n) + 1
INTEGER, DIMENSION(n) :: seed INTEGER, DIMENSION(n) :: seed
! Get seed, array too small ! Get seed, array too small
......
2019-08-13 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/91414
* intrinsics/random.c (prng_state): Update state struct.
(master_state): Update to match new size.
(get_rand_state): Update to match new PRNG.
(rotl): New function.
(xorshift1024star): Replace with prng_next.
(prng_next): New function.
(jump): Update for new PRNG.
(lcg_parkmiller): Replace with splitmix64.
(splitmix64): New function.
(getosrandom): Fix return value, simplify.
(init_rand_state): Use getosrandom only to get 8 bytes, splitmix64
to fill rest of state.
(random_r4): Update to new function and struct names.
(random_r8): Likewise.
(random_r10): Likewise.
(random_r16): Likewise.
(arandom_r4): Liekwise.
(arandom_r8): Likewise.
(arandom_r10): Likwewise.
(arandom_r16): Likewise.
(xor_keys): Reduce size to match new PRNG.
(random_seed_i4): Update to new function and struct names, remove
special handling of variable p used in previous PRNG.
(random_seed_i8): Likewise.
2019-08-07 Janne Blomqvist <jb@gcc.gnu.org> 2019-08-07 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/53796 PR fortran/53796
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment