1 /* Implementation of the RANDOM intrinsics
2 Copyright (C) 2002-2019 Free Software Foundation, Inc.
3 Contributed by Lars Segerlund <seger@linuxmail.org>,
4 Steve Kargl and Janne Blomqvist.
6 This file is part of the GNU Fortran runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 Ligbfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
30 #include "libgfortran.h"
40 #ifdef HAVE_SYS_RANDOM_H
41 #include <sys/random.h>
47 #include <_mingw.h> /* For __MINGW64_VERSION_MAJOR */
50 extern void random_r4 (GFC_REAL_4
*);
51 iexport_proto(random_r4
);
53 extern void random_r8 (GFC_REAL_8
*);
54 iexport_proto(random_r8
);
56 extern void arandom_r4 (gfc_array_r4
*);
57 export_proto(arandom_r4
);
59 extern void arandom_r8 (gfc_array_r8
*);
60 export_proto(arandom_r8
);
62 #ifdef HAVE_GFC_REAL_10
64 extern void random_r10 (GFC_REAL_10
*);
65 iexport_proto(random_r10
);
67 extern void arandom_r10 (gfc_array_r10
*);
68 export_proto(arandom_r10
);
72 #ifdef HAVE_GFC_REAL_16
74 extern void random_r16 (GFC_REAL_16
*);
75 iexport_proto(random_r16
);
77 extern void arandom_r16 (gfc_array_r16
*);
78 export_proto(arandom_r16
);
82 #ifdef __GTHREAD_MUTEX_INIT
83 static __gthread_mutex_t random_lock
= __GTHREAD_MUTEX_INIT
;
85 static __gthread_mutex_t random_lock
;
88 /* Helper routines to map a GFC_UINTEGER_* to the corresponding
89 GFC_REAL_* types in the range of [0,1). If GFC_REAL_*_RADIX are 2
90 or 16, respectively, we mask off the bits that don't fit into the
91 correct GFC_REAL_*, convert to the real type, then multiply by the
96 rnumber_4 (GFC_REAL_4
*f
, GFC_UINTEGER_4 v
)
99 #if GFC_REAL_4_RADIX == 2
100 mask
= ~ (GFC_UINTEGER_4
) 0u << (32 - GFC_REAL_4_DIGITS
);
101 #elif GFC_REAL_4_RADIX == 16
102 mask
= ~ (GFC_UINTEGER_4
) 0u << ((8 - GFC_REAL_4_DIGITS
) * 4);
104 #error "GFC_REAL_4_RADIX has unknown value"
107 *f
= (GFC_REAL_4
) v
* GFC_REAL_4_LITERAL(0x1.p
-32);
111 rnumber_8 (GFC_REAL_8
*f
, GFC_UINTEGER_8 v
)
114 #if GFC_REAL_8_RADIX == 2
115 mask
= ~ (GFC_UINTEGER_8
) 0u << (64 - GFC_REAL_8_DIGITS
);
116 #elif GFC_REAL_8_RADIX == 16
117 mask
= ~ (GFC_UINTEGER_8
) 0u << (16 - GFC_REAL_8_DIGITS
) * 4);
119 #error "GFC_REAL_8_RADIX has unknown value"
122 *f
= (GFC_REAL_8
) v
* GFC_REAL_8_LITERAL(0x1.p
-64);
125 #ifdef HAVE_GFC_REAL_10
128 rnumber_10 (GFC_REAL_10
*f
, GFC_UINTEGER_8 v
)
131 #if GFC_REAL_10_RADIX == 2
132 mask
= ~ (GFC_UINTEGER_8
) 0u << (64 - GFC_REAL_10_DIGITS
);
133 #elif GFC_REAL_10_RADIX == 16
134 mask
= ~ (GFC_UINTEGER_10
) 0u << ((16 - GFC_REAL_10_DIGITS
) * 4);
136 #error "GFC_REAL_10_RADIX has unknown value"
139 *f
= (GFC_REAL_10
) v
* GFC_REAL_10_LITERAL(0x1.p
-64);
143 #ifdef HAVE_GFC_REAL_16
145 /* For REAL(KIND=16), we only need to mask off the lower bits. */
148 rnumber_16 (GFC_REAL_16
*f
, GFC_UINTEGER_8 v1
, GFC_UINTEGER_8 v2
)
151 #if GFC_REAL_16_RADIX == 2
152 mask
= ~ (GFC_UINTEGER_8
) 0u << (128 - GFC_REAL_16_DIGITS
);
153 #elif GFC_REAL_16_RADIX == 16
154 mask
= ~ (GFC_UINTEGER_8
) 0u << ((32 - GFC_REAL_16_DIGITS
) * 4);
156 #error "GFC_REAL_16_RADIX has unknown value"
159 *f
= (GFC_REAL_16
) v1
* GFC_REAL_16_LITERAL(0x1.p
-64)
160 + (GFC_REAL_16
) v2
* GFC_REAL_16_LITERAL(0x1.p
-128);
167 We use the xoshiro256** generator, a fast high-quality generator
170 - passes TestU1 without any failures
172 - provides a "jump" function making it easy to provide many
173 independent parallel streams.
175 - Long period of 2**256 - 1
177 A description can be found at
179 http://prng.di.unimi.it/
183 https://arxiv.org/abs/1805.01407
185 The paper includes public domain source code which is the basis for
186 the implementation below.
197 /* master_state is the only variable protected by random_lock. */
198 static prng_state master_state
= { .init
= false, .s
= {
199 0xad63fa1ed3b55f36ULL
, 0xd94473e78978b497ULL
, 0xbc60592a98172477ULL
,
200 0xa3de7c6e81265301ULL
}
204 static __gthread_key_t rand_state_key
;
207 get_rand_state (void)
209 /* For single threaded apps. */
210 static prng_state rand_state
;
212 if (__gthread_active_p ())
214 void* p
= __gthread_getspecific (rand_state_key
);
217 p
= xcalloc (1, sizeof (prng_state
));
218 __gthread_setspecific (rand_state_key
, p
);
226 static inline uint64_t
227 rotl (const uint64_t x
, int k
)
229 return (x
<< k
) | (x
>> (64 - k
));
234 prng_next (prng_state
* rs
)
236 const uint64_t result
= rotl(rs
->s
[1] * 5, 7) * 9;
238 const uint64_t t
= rs
->s
[1] << 17;
240 rs
->s
[2] ^= rs
->s
[0];
241 rs
->s
[3] ^= rs
->s
[1];
242 rs
->s
[1] ^= rs
->s
[2];
243 rs
->s
[0] ^= rs
->s
[3];
247 rs
->s
[3] = rotl(rs
->s
[3], 45);
253 /* This is the jump function for the generator. It is equivalent to
254 2^128 calls to prng_next(); it can be used to generate 2^128
255 non-overlapping subsequences for parallel computations. */
258 jump (prng_state
* rs
)
260 static const uint64_t JUMP
[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
266 for(size_t i
= 0; i
< sizeof JUMP
/ sizeof *JUMP
; i
++)
267 for(int b
= 0; b
< 64; b
++) {
268 if (JUMP
[i
] & UINT64_C(1) << b
) {
284 /* Splitmix64 recommended by xoshiro author for initializing. After
285 getting one uint64_t value from the OS, this is used to fill in the
286 rest of the xoshiro state. */
289 splitmix64 (uint64_t x
)
291 uint64_t z
= (x
+= 0x9e3779b97f4a7c15);
292 z
= (z
^ (z
>> 30)) * 0xbf58476d1ce4e5b9;
293 z
= (z
^ (z
>> 27)) * 0x94d049bb133111eb;
294 return z
^ (z
>> 31);
298 /* Get some bytes from the operating system in order to seed
302 getosrandom (void *buf
, size_t buflen
)
304 /* rand_s is available in MinGW-w64 but not plain MinGW. */
305 #if defined(__MINGW64_VERSION_MAJOR)
306 unsigned int* b
= buf
;
307 for (size_t i
= 0; i
< buflen
/ sizeof (unsigned int); i
++)
311 #ifdef HAVE_GETENTROPY
312 if (getentropy (buf
, buflen
) == 0)
315 int flags
= O_RDONLY
;
319 int fd
= open("/dev/urandom", flags
);
322 int res
= read(fd
, buf
, buflen
);
326 uint64_t seed
= 0x047f7684e9fc949dULL
;
329 if (gf_gettime (&secs
, &usecs
) == 0)
335 pid_t pid
= getpid();
338 size_t size
= buflen
< sizeof (uint64_t) ? buflen
: sizeof (uint64_t);
339 memcpy (buf
, &seed
, size
);
341 #endif /* __MINGW64_VERSION_MAJOR */
345 /* Initialize the random number generator for the current thread,
346 using the master state and the number of times we must jump. */
349 init_rand_state (prng_state
* rs
, const bool locked
)
352 __gthread_mutex_lock (&random_lock
);
353 if (!master_state
.init
)
356 getosrandom (&os_seed
, sizeof (os_seed
));
357 for (uint64_t i
= 0; i
< sizeof (master_state
.s
) / sizeof (uint64_t); i
++)
359 os_seed
= splitmix64 (os_seed
);
360 master_state
.s
[i
] = os_seed
;
362 master_state
.init
= true;
364 memcpy (&rs
->s
, master_state
.s
, sizeof (master_state
.s
));
365 jump (&master_state
);
367 __gthread_mutex_unlock (&random_lock
);
372 /* This function produces a REAL(4) value from the uniform distribution
376 random_r4 (GFC_REAL_4
*x
)
378 prng_state
* rs
= get_rand_state();
380 if (unlikely (!rs
->init
))
381 init_rand_state (rs
, false);
382 uint64_t r
= prng_next (rs
);
383 /* Take the higher bits, ensuring that a stream of real(4), real(8),
384 and real(10) will be identical (except for precision). */
385 uint32_t high
= (uint32_t) (r
>> 32);
390 /* This function produces a REAL(8) value from the uniform distribution
394 random_r8 (GFC_REAL_8
*x
)
397 prng_state
* rs
= get_rand_state();
399 if (unlikely (!rs
->init
))
400 init_rand_state (rs
, false);
406 #ifdef HAVE_GFC_REAL_10
408 /* This function produces a REAL(10) value from the uniform distribution
412 random_r10 (GFC_REAL_10
*x
)
415 prng_state
* rs
= get_rand_state();
417 if (unlikely (!rs
->init
))
418 init_rand_state (rs
, false);
426 /* This function produces a REAL(16) value from the uniform distribution
429 #ifdef HAVE_GFC_REAL_16
432 random_r16 (GFC_REAL_16
*x
)
434 GFC_UINTEGER_8 r1
, r2
;
435 prng_state
* rs
= get_rand_state();
437 if (unlikely (!rs
->init
))
438 init_rand_state (rs
, false);
441 rnumber_16 (x
, r1
, r2
);
448 /* This function fills a REAL(4) array with values from the uniform
449 distribution with range [0,1). */
452 arandom_r4 (gfc_array_r4
*x
)
454 index_type count
[GFC_MAX_DIMENSIONS
];
455 index_type extent
[GFC_MAX_DIMENSIONS
];
456 index_type stride
[GFC_MAX_DIMENSIONS
];
460 prng_state
* rs
= get_rand_state();
464 dim
= GFC_DESCRIPTOR_RANK (x
);
466 for (index_type n
= 0; n
< dim
; n
++)
469 stride
[n
] = GFC_DESCRIPTOR_STRIDE(x
,n
);
470 extent
[n
] = GFC_DESCRIPTOR_EXTENT(x
,n
);
477 if (unlikely (!rs
->init
))
478 init_rand_state (rs
, false);
482 /* random_r4 (dest); */
483 uint64_t r
= prng_next (rs
);
484 uint32_t high
= (uint32_t) (r
>> 32);
485 rnumber_4 (dest
, high
);
487 /* Advance to the next element. */
490 /* Advance to the next source element. */
492 while (count
[n
] == extent
[n
])
494 /* When we get to the end of a dimension, reset it and increment
495 the next dimension. */
497 /* We could precalculate these products, but this is a less
498 frequently used path so probably not worth it. */
499 dest
-= stride
[n
] * extent
[n
];
515 /* This function fills a REAL(8) array with values from the uniform
516 distribution with range [0,1). */
519 arandom_r8 (gfc_array_r8
*x
)
521 index_type count
[GFC_MAX_DIMENSIONS
];
522 index_type extent
[GFC_MAX_DIMENSIONS
];
523 index_type stride
[GFC_MAX_DIMENSIONS
];
527 prng_state
* rs
= get_rand_state();
531 dim
= GFC_DESCRIPTOR_RANK (x
);
533 for (index_type n
= 0; n
< dim
; n
++)
536 stride
[n
] = GFC_DESCRIPTOR_STRIDE(x
,n
);
537 extent
[n
] = GFC_DESCRIPTOR_EXTENT(x
,n
);
544 if (unlikely (!rs
->init
))
545 init_rand_state (rs
, false);
549 /* random_r8 (dest); */
550 uint64_t r
= prng_next (rs
);
553 /* Advance to the next element. */
556 /* Advance to the next source element. */
558 while (count
[n
] == extent
[n
])
560 /* When we get to the end of a dimension, reset it and increment
561 the next dimension. */
563 /* We could precalculate these products, but this is a less
564 frequently used path so probably not worth it. */
565 dest
-= stride
[n
] * extent
[n
];
581 #ifdef HAVE_GFC_REAL_10
583 /* This function fills a REAL(10) array with values from the uniform
584 distribution with range [0,1). */
587 arandom_r10 (gfc_array_r10
*x
)
589 index_type count
[GFC_MAX_DIMENSIONS
];
590 index_type extent
[GFC_MAX_DIMENSIONS
];
591 index_type stride
[GFC_MAX_DIMENSIONS
];
595 prng_state
* rs
= get_rand_state();
599 dim
= GFC_DESCRIPTOR_RANK (x
);
601 for (index_type n
= 0; n
< dim
; n
++)
604 stride
[n
] = GFC_DESCRIPTOR_STRIDE(x
,n
);
605 extent
[n
] = GFC_DESCRIPTOR_EXTENT(x
,n
);
612 if (unlikely (!rs
->init
))
613 init_rand_state (rs
, false);
617 /* random_r10 (dest); */
618 uint64_t r
= prng_next (rs
);
619 rnumber_10 (dest
, r
);
621 /* Advance to the next element. */
624 /* Advance to the next source element. */
626 while (count
[n
] == extent
[n
])
628 /* When we get to the end of a dimension, reset it and increment
629 the next dimension. */
631 /* We could precalculate these products, but this is a less
632 frequently used path so probably not worth it. */
633 dest
-= stride
[n
] * extent
[n
];
651 #ifdef HAVE_GFC_REAL_16
653 /* This function fills a REAL(16) array with values from the uniform
654 distribution with range [0,1). */
657 arandom_r16 (gfc_array_r16
*x
)
659 index_type count
[GFC_MAX_DIMENSIONS
];
660 index_type extent
[GFC_MAX_DIMENSIONS
];
661 index_type stride
[GFC_MAX_DIMENSIONS
];
665 prng_state
* rs
= get_rand_state();
669 dim
= GFC_DESCRIPTOR_RANK (x
);
671 for (index_type n
= 0; n
< dim
; n
++)
674 stride
[n
] = GFC_DESCRIPTOR_STRIDE(x
,n
);
675 extent
[n
] = GFC_DESCRIPTOR_EXTENT(x
,n
);
682 if (unlikely (!rs
->init
))
683 init_rand_state (rs
, false);
687 /* random_r16 (dest); */
688 uint64_t r1
= prng_next (rs
);
689 uint64_t r2
= prng_next (rs
);
690 rnumber_16 (dest
, r1
, r2
);
692 /* Advance to the next element. */
695 /* Advance to the next source element. */
697 while (count
[n
] == extent
[n
])
699 /* When we get to the end of a dimension, reset it and increment
700 the next dimension. */
702 /* We could precalculate these products, but this is a less
703 frequently used path so probably not worth it. */
704 dest
-= stride
[n
] * extent
[n
];
723 /* Number of elements in master_state array. */
724 #define SZU64 (sizeof (master_state.s) / sizeof (uint64_t))
727 /* Keys for scrambling the seed in order to avoid poor seeds. */
729 static const uint64_t xor_keys
[] = {
730 0xbd0c5b6e50c2df49ULL
, 0xd46061cd46e1df38ULL
, 0xbb4f4d4ed6103544ULL
,
731 0x114a583d0756ad39ULL
735 /* Since a XOR cipher is symmetric, we need only one routine, and we
736 can use it both for encryption and decryption. */
739 scramble_seed (uint64_t *dest
, const uint64_t *src
)
741 for (size_t i
= 0; i
< SZU64
; i
++)
742 dest
[i
] = src
[i
] ^ xor_keys
[i
];
746 /* random_seed is used to seed the PRNG with either a default
747 set of seeds or user specified set of seeds. random_seed
748 must be called with no argument or exactly one argument. */
751 random_seed_i4 (GFC_INTEGER_4
*size
, gfc_array_i4
*put
, gfc_array_i4
*get
)
753 uint64_t seed
[SZU64
];
754 #define SZ (sizeof (master_state.s) / sizeof (GFC_INTEGER_4))
756 /* Check that we only have one argument present. */
757 if ((size
? 1 : 0) + (put
? 1 : 0) + (get
? 1 : 0) > 1)
758 runtime_error ("RANDOM_SEED should have at most one argument present.");
763 prng_state
* rs
= get_rand_state();
765 /* Return the seed to GET data. */
768 /* If the rank of the array is not 1, abort. */
769 if (GFC_DESCRIPTOR_RANK (get
) != 1)
770 runtime_error ("Array rank of GET is not 1.");
772 /* If the array is too small, abort. */
773 if (GFC_DESCRIPTOR_EXTENT(get
,0) < (index_type
) SZ
)
774 runtime_error ("Array size of GET is too small.");
777 init_rand_state (rs
, false);
779 /* Unscramble the seed. */
780 scramble_seed (seed
, rs
->s
);
782 /* Then copy it back to the user variable. */
783 for (size_t i
= 0; i
< SZ
; i
++)
784 memcpy (&(get
->base_addr
[(SZ
- 1 - i
) * GFC_DESCRIPTOR_STRIDE(get
,0)]),
785 (unsigned char*) seed
+ i
* sizeof(GFC_UINTEGER_4
),
786 sizeof(GFC_UINTEGER_4
));
791 __gthread_mutex_lock (&random_lock
);
793 /* From the standard: "If no argument is present, the processor assigns
794 a processor-dependent value to the seed." */
795 if (size
== NULL
&& put
== NULL
&& get
== NULL
)
797 master_state
.init
= false;
798 init_rand_state (rs
, true);
803 /* If the rank of the array is not 1, abort. */
804 if (GFC_DESCRIPTOR_RANK (put
) != 1)
805 runtime_error ("Array rank of PUT is not 1.");
807 /* If the array is too small, abort. */
808 if (GFC_DESCRIPTOR_EXTENT(put
,0) < (index_type
) SZ
)
809 runtime_error ("Array size of PUT is too small.");
811 /* We copy the seed given by the user. */
812 for (size_t i
= 0; i
< SZ
; i
++)
813 memcpy ((unsigned char*) seed
+ i
* sizeof(GFC_UINTEGER_4
),
814 &(put
->base_addr
[(SZ
- 1 - i
) * GFC_DESCRIPTOR_STRIDE(put
,0)]),
815 sizeof(GFC_UINTEGER_4
));
817 /* We put it after scrambling the bytes, to paper around users who
818 provide seeds with quality only in the lower or upper part. */
819 scramble_seed (master_state
.s
, seed
);
820 master_state
.init
= true;
821 init_rand_state (rs
, true);
824 __gthread_mutex_unlock (&random_lock
);
828 iexport(random_seed_i4
);
832 random_seed_i8 (GFC_INTEGER_8
*size
, gfc_array_i8
*put
, gfc_array_i8
*get
)
834 uint64_t seed
[SZU64
];
836 /* Check that we only have one argument present. */
837 if ((size
? 1 : 0) + (put
? 1 : 0) + (get
? 1 : 0) > 1)
838 runtime_error ("RANDOM_SEED should have at most one argument present.");
840 #define SZ (sizeof (master_state.s) / sizeof (GFC_INTEGER_8))
844 prng_state
* rs
= get_rand_state();
846 /* Return the seed to GET data. */
849 /* If the rank of the array is not 1, abort. */
850 if (GFC_DESCRIPTOR_RANK (get
) != 1)
851 runtime_error ("Array rank of GET is not 1.");
853 /* If the array is too small, abort. */
854 if (GFC_DESCRIPTOR_EXTENT(get
,0) < (index_type
) SZ
)
855 runtime_error ("Array size of GET is too small.");
858 init_rand_state (rs
, false);
860 /* Unscramble the seed. */
861 scramble_seed (seed
, rs
->s
);
863 /* This code now should do correct strides. */
864 for (size_t i
= 0; i
< SZ
; i
++)
865 memcpy (&(get
->base_addr
[i
* GFC_DESCRIPTOR_STRIDE(get
,0)]), &seed
[i
],
866 sizeof (GFC_UINTEGER_8
));
871 __gthread_mutex_lock (&random_lock
);
873 /* From the standard: "If no argument is present, the processor assigns
874 a processor-dependent value to the seed." */
875 if (size
== NULL
&& put
== NULL
&& get
== NULL
)
877 master_state
.init
= false;
878 init_rand_state (rs
, true);
883 /* If the rank of the array is not 1, abort. */
884 if (GFC_DESCRIPTOR_RANK (put
) != 1)
885 runtime_error ("Array rank of PUT is not 1.");
887 /* If the array is too small, abort. */
888 if (GFC_DESCRIPTOR_EXTENT(put
,0) < (index_type
) SZ
)
889 runtime_error ("Array size of PUT is too small.");
891 /* This code now should do correct strides. */
892 for (size_t i
= 0; i
< SZ
; i
++)
893 memcpy (&seed
[i
], &(put
->base_addr
[i
* GFC_DESCRIPTOR_STRIDE(put
,0)]),
894 sizeof (GFC_UINTEGER_8
));
896 scramble_seed (master_state
.s
, seed
);
897 master_state
.init
= true;
898 init_rand_state (rs
, true);
902 __gthread_mutex_unlock (&random_lock
);
905 iexport(random_seed_i8
);
908 #if !defined __GTHREAD_MUTEX_INIT || defined __GTHREADS
909 static void __attribute__((constructor
))
910 constructor_random (void)
912 #ifndef __GTHREAD_MUTEX_INIT
913 __GTHREAD_MUTEX_INIT_FUNCTION (&random_lock
);
915 if (__gthread_active_p ())
916 __gthread_key_create (&rand_state_key
, &free
);
921 static void __attribute__((destructor
))
922 destructor_random (void)
924 if (__gthread_active_p ())
925 __gthread_key_delete (rand_state_key
);