[Bug fortran/98253] Conflicting random_seed/random_init results
kargl at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sat Dec 12 21:31:30 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253
--- Comment #6 from kargl at gcc dot gnu.org ---
(In reply to Dominique d'Humieres from comment #4)
> Invalid expectation?
Not sure. This long response was composed before I saw Damian's reply.
At the risk of starting an existential argument, I'll provide
my understanding of the situtation.
Prior to random_init(), Fortran had random_seed(). When J3
added random_number() and random_seed() to Fortran standard,
the individual who wrote the specification forgot to include
a statement about the state of the PRNG if random_seed() was
not called. So, this simple program
program foo
real r
call random_number(r)
print *, r
end program foo
when compiled with ifort would give a different PRN on each
invocation. A long time ago, when compiled with gfortran,
the program always gave the same PRN. (Janne changed gfortran's
behavior when he replaced replaced the KISS PRNG with xshiro++.)
The problem was that ifort used a different processor-dependent
set of seeds on each invocation whereas gfortran used the same
processor-dependent set of seeds on each invocation. Both
behaviors are standard conforming. To resolve the problem, J3
could not select one behavior over the other without causing
problems with a conforming program that relied on the old behavior.
Steve Lionel wrote the specification for random_init() in
hopes of fixing shortcomings of random_seed(). Unfortunately,
he (and/or J3) decided to conflated behavior for coarray
programs into the specification. Consider the simply non-coarray
program:
% cat u.f90
program foo
call random_init(repeatable=.false., image_distinct=.false.)
do i = 1, 3
call random_number(r)
print '(F8.5), r
end do
print *
call random_init(repeatable=.false., image_distinct=.false.)
do i = 1, 3
call random_number(r)
print '(F8.5), r
end do
end program foo
% gfcx -o z u.f90 && ./z
0.78330
0.40072
0.22728
0.44823
0.12879
0.50003
Exactly, the behavior one would expect. Reseeding the PRNG
uses a new set of processor-dependent seeds. If 'z' is run
again, a different set of processor-dependent seeds are used.
Now change the code to have 'repeatable=.true.'
% gfcx -o z u.f90 && ./z
0.67367
0.06375
0.69694
0.67367
0.06375
0.69694
Exactly, what one expects. When the second random_init() is
called, the PRNG is re-initialized with the original set of
processor-dependent seeds. What happens if the executable is
run again? Well,
% ./z
0.34318
0.90421
0.38122
0.34318
0.90421
0.38122
A different set of processor-dependent seeds are used to initially
seed the PRNG, and when random_init() is called a second time, it
uses that "different set of processor-dependent seeds" to re-initialize
the PRNG.
So, where does existentialism enter into the issue? When executable
'./z' is run the following occurs:
1) 'image0' is instantiated
2) random_init() is called
3) the do-loop executes
3) 'image0' is terminated.
a year later when './z' is run again, the following occurs:
a) 'image0' is instantiated
b) random_init() is called
c) the do-loop executes
d) 'image0' is terminated.
When 'image0' in a) is instantiated, 'image0' in 1) no longer exists.
There is no way to determined what set of processor-dependent seeds
were used for random_init() in 2) when random_init() is called in b).
It does not matter what value is assigned to image_distinct in the
above code. Is 'image0' in a) the same as 'image0' in 1) or are these
images distinct?
IMO, image_distinct only applies when more than one image is
instantiate during the execution of a co-array program. image_distinct
should have been an optional argument. Suppose you have a
program that has num_images() return a value of 2. You execute that
program and the following occurs:
I) 'image0' is instantiated
II) 'image1' is instantiated
III) one or more images call random_init()
IV) work is done
V) one or more images call random_init(), again.
VI) image1 terminates
VII) image0 terminates
It is here that image_distinct can affect the seeding of PRNG.
When I developed random_init(), I spent a few days getting
opencoarray installed on my system. I then spent some time
trying to getting a reasonable approach of dealing with
images (don't remember any consideration about teams). The
comment in libgfortran/intrinsics/random_init.f90 details
what happens with combinations of 'repeatable' and 'image_distinct'
More information about the Gcc-bugs
mailing list