public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug fortran/98253] New: Conflicting random_seed/random_init results
@ 2020-12-12 16:24 damian at sourceryinstitute dot org
  2020-12-12 17:33 ` [Bug fortran/98253] " kargl at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: damian at sourceryinstitute dot org @ 2020-12-12 16:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

            Bug ID: 98253
           Summary: Conflicting random_seed/random_init results
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: damian at sourceryinstitute dot org
  Target Milestone: ---

16.9.155 Case (i) in the Fortran 2018 standard states

  CALL RANDOM_INIT (REPEATABLE=true, IMAGE_DISTINCT=true) is equivalent to  
  invoking RANDOM_SEED with a processor-dependent value for PUT that is 
  different on every invoking image. In each execution of the program with 
  the same execution environment, if the invoking image index value in the 
  initial team is the same, the value for PUT shall be the same.

but the two programs below give different results.

% cat random_init.f90
  implicit none
  integer i
  real r
  call random_init(repeatable=.true., image_distinct=.true.)
  do i=1,5
    call random_number(r)
    print *,r 
  end do
end

% cat random_seed.f90 
  implicit none
  integer i, n
  real r
  call random_seed(size=n)
  call random_seed(put=[(i,i=1,n)])
  do i=1,5
    call random_number(r)
    print *,r 
  end do
end

% /usr/local/Cellar/gnu/11.0.0/bin/gfortran random_init.f90
% ./a.out
  0.731217086    
  0.652637541        
  0.381399393        
  0.817764997        
  0.394176722        

% /usr/local/Cellar/gnu/11.0.0/bin/gfortran random_seed.f90 
% ./a.out
  0.471070886    
  0.117344737        
  0.357547939        
  0.318134785        
  0.696753800        

% /usr/local/Cellar/gnu/11.0.0/bin/gfortran --version    
GNU Fortran (GCC) 11.0.0 20200804 (experimental)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
@ 2020-12-12 17:33 ` kargl at gcc dot gnu.org
  2020-12-12 17:47 ` kargl at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: kargl at gcc dot gnu.org @ 2020-12-12 17:33 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

kargl at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kargl at gcc dot gnu.org

--- Comment #1 from kargl at gcc dot gnu.org ---
Of course, the results are different.  When I wrote random_init(), I asked
several times on the J3 list what image_distinct meant.  No one would provide
an answer.  I concluded that image_distinct only affects co-array programs. 
You can read the long comment in libgfortran/intrinsics/random_init.f90.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
  2020-12-12 17:33 ` [Bug fortran/98253] " kargl at gcc dot gnu.org
@ 2020-12-12 17:47 ` kargl at gcc dot gnu.org
  2020-12-12 18:20 ` kargl at gcc dot gnu.org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: kargl at gcc dot gnu.org @ 2020-12-12 17:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

--- Comment #2 from kargl at gcc dot gnu.org ---
On 2nd thought.

Of course, the results are different.

In your first example, you have

  call random_init(repeatable=.true., image_distinct=.true.)

which gets you processor-dependent seeds.  In your second
example, you have

  call random_seed(size=n)
  call random_seed(put=[(i,i=1,n)])

that is not processor-dependent.  You are explicitly seeding
the PRNG.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
  2020-12-12 17:33 ` [Bug fortran/98253] " kargl at gcc dot gnu.org
  2020-12-12 17:47 ` kargl at gcc dot gnu.org
@ 2020-12-12 18:20 ` kargl at gcc dot gnu.org
  2020-12-12 18:53 ` dominiq at lps dot ens.fr
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: kargl at gcc dot gnu.org @ 2020-12-12 18:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

--- Comment #3 from kargl at gcc dot gnu.org ---
Third thought.  Here are the programs you meant to write (without error
checking such as how_to_use_random_init must be run before
how_to_seed_with_random_seed_like_random_init).

program how_to_use_random_init

   implicit none

   integer fd, i, n
   integer, allocatable :: seeds(:)
   real r

   call random_init(repeatable=.true., image_distinct=.true.)

   call random_seed(size=n)
   allocate(seeds(n))
   call random_seed(get=seeds)
   open(newunit=fd,file='seed.cache',access='stream',status='replace')
   write(fd) seeds
   close(fd)

   do i=1,5
     call random_number(r)
     print *,r 
   end do

end program how_to_use_random_init

program how_to_seed_with_random_seed_like_random_init

   implicit none

   integer fd, i, n
   integer, allocatable :: seeds(:)
   real r

   call random_seed(size=n)
   allocate(seeds(n))
   open(newunit=fd,file='seed.cache',access='stream',status='old')
   read(fd) seeds
   close(fd)

   call random_seed(put=seeds)
   do i=1,5
      call random_number(r)
      print *,r 
   end do

end program how_to_seed_with_random_seed_like_random_init

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
                   ` (2 preceding siblings ...)
  2020-12-12 18:20 ` kargl at gcc dot gnu.org
@ 2020-12-12 18:53 ` dominiq at lps dot ens.fr
  2020-12-12 21:20 ` damian at sourceryinstitute dot org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: dominiq at lps dot ens.fr @ 2020-12-12 18:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

Dominique d'Humieres <dominiq at lps dot ens.fr> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2020-12-12
             Status|UNCONFIRMED                 |WAITING
     Ever confirmed|0                           |1

--- Comment #4 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
Invalid expectation?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
                   ` (3 preceding siblings ...)
  2020-12-12 18:53 ` dominiq at lps dot ens.fr
@ 2020-12-12 21:20 ` damian at sourceryinstitute dot org
  2020-12-12 21:31 ` kargl at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: damian at sourceryinstitute dot org @ 2020-12-12 21:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

--- Comment #5 from Damian Rouson <damian at sourceryinstitute dot org> ---
Steve, thanks for all the time you put into implementing random_init and
responding to this PR.  My confusion stemmed from the first sentence that I
quoted from the standard. It states that the provided random_init call is
equivalent to a processor-dependent random_seed call so I was attempting to
replace my two random_seed calls with one random_init call. I see now that such
a replacement only works if one knows the correct, processor-dependent seed
values, but I also understand now that it would be pointless to do what I'm
trying to do.  Because the matching seeds would be processor-dependent, the
code wouldn't be portable. 

On a related note, I've been trying over time to evolve away from using
"coarray" as the blanket term for all parallel features.  Fortran now has so
many parallel features that don't necessarily involve coarrays. The
IMAGE_DISTINCT argument is one small example so I don't think IMAGE_DISTINCT
necessarily has anything to do with coarrays, but it does have to do with
multi-image execution.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
                   ` (4 preceding siblings ...)
  2020-12-12 21:20 ` damian at sourceryinstitute dot org
@ 2020-12-12 21:31 ` kargl at gcc dot gnu.org
  2020-12-12 22:54 ` damian at sourceryinstitute dot org
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: kargl at gcc dot gnu.org @ 2020-12-12 21:31 UTC (permalink / raw)
  To: gcc-bugs

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'

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
                   ` (5 preceding siblings ...)
  2020-12-12 21:31 ` kargl at gcc dot gnu.org
@ 2020-12-12 22:54 ` damian at sourceryinstitute dot org
  2020-12-12 23:55 ` damian at sourceryinstitute dot org
  2020-12-13  0:20 ` sgk at troutmask dot apl.washington.edu
  8 siblings, 0 replies; 10+ messages in thread
From: damian at sourceryinstitute dot org @ 2020-12-12 22:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

--- Comment #7 from Damian Rouson <damian at sourceryinstitute dot org> ---
I agree that it would have been better for image_distinct to be optional.  I
co-hosted the 2018 WG5 meeting at which there were lengthy discussions around
random number generation.  I don't recall whether making that argument optional
was discussed.  I assume it wouldn't break any existing code to make it
optional in a future standard.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
                   ` (6 preceding siblings ...)
  2020-12-12 22:54 ` damian at sourceryinstitute dot org
@ 2020-12-12 23:55 ` damian at sourceryinstitute dot org
  2020-12-13  0:20 ` sgk at troutmask dot apl.washington.edu
  8 siblings, 0 replies; 10+ messages in thread
From: damian at sourceryinstitute dot org @ 2020-12-12 23:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

Damian Rouson <damian at sourceryinstitute dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|WAITING                     |RESOLVED

--- Comment #8 from Damian Rouson <damian at sourceryinstitute dot org> ---
Steve, one more question.  How do you interpret the second sentence in the text
that I originally quoted: "In each execution of the program with the same
execution environment, if the invoking image index value in the initial team is
the same, the value for PUT shall be the same."  This is in 16.9.155 Case (i)
describing the relationship between random_init and random_seed.  I originally
interpreted this quote to mean that each image would use the same seed each
time the program runs, which would be a constraint on the PRNG.  I'm now
thinking that the reference to PUT implies that the user is setting the seed
and this is saying that the program must set the same seed each a given image
executes, but that seems like an odd constraint so I'm probably still horribly
confused.  Feel free to mark this issue as invalid if this is starting to seem
like a waste of time.  I'm just trying to understand.

Either way, an image number is defined for all programs whether or not there
are coarrays anywhere in the program and whether or not the program is ever
executed in multiple images -- for example, this_image() is just an intrinsic
function rather than a (hypothetical) "coarray" intrinsic function.  This point
is most meaningful with a compiler like the Cray compiler, which requires no
special flags to compile a program that invokes this_image().  In some sense,
all Fortran programs are now parallel programs whether the user takes advantage
of that fact in any explicit way or not. I suspect that's the reason that
IMAGE_DISTINCT is not optional. Possibly the committee deemed it better to
require users to specify the desired behavior in multi-image execution. Even
libraries that were never designed in any way to exploit parallelism can be
linked into parallel programs so it seems better to have developers of such a
library specify the desired behavior if their code is ultimately linked into a
parallel program -- analogous to requiring that code be thread-safe even if the
code makes no explicit use of multi-threading.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug fortran/98253] Conflicting random_seed/random_init results
  2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
                   ` (7 preceding siblings ...)
  2020-12-12 23:55 ` damian at sourceryinstitute dot org
@ 2020-12-13  0:20 ` sgk at troutmask dot apl.washington.edu
  8 siblings, 0 replies; 10+ messages in thread
From: sgk at troutmask dot apl.washington.edu @ 2020-12-13  0:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253

--- Comment #9 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Sat, Dec 12, 2020 at 11:55:41PM +0000, damian at sourceryinstitute dot org
wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98253
> 
> Damian Rouson <damian at sourceryinstitute dot org> changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>          Resolution|---                         |FIXED
>              Status|WAITING                     |RESOLVED
> 
> --- Comment #8 from Damian Rouson <damian at sourceryinstitute dot org> ---
> Steve, one more question.  How do you interpret the second sentence in the text
> that I originally quoted: "In each execution of the program with the same
> execution environment, if the invoking image index value in the initial team is
> the same, the value for PUT shall be the same."  This is in 16.9.155 Case (i)
> describing the relationship between random_init and random_seed.  I originally
> interpreted this quote to mean that each image would use the same seed each
> time the program runs, which would be a constraint on the PRNG.  I'm now
> thinking that the reference to PUT implies that the user is setting the seed
> and this is saying that the program must set the same seed each a given image
> executes, but that seems like an odd constraint so I'm probably still horribly
> confused.  Feel free to mark this issue as invalid if this is starting to seem
> like a waste of time.  I'm just trying to understand.
> 
> Either way, an image number is defined for all programs whether or not there
> are coarrays anywhere in the program and whether or not the program is ever
> executed in multiple images -- for example, this_image() is just an intrinsic
> function rather than a (hypothetical) "coarray" intrinsic function.  This point
> is most meaningful with a compiler like the Cray compiler, which requires no
> special flags to compile a program that invokes this_image().  In some sense,
> all Fortran programs are now parallel programs whether the user takes advantage
> of that fact in any explicit way or not. I suspect that's the reason that
> IMAGE_DISTINCT is not optional. Possibly the committee deemed it better to
> require users to specify the desired behavior in multi-image execution. Even
> libraries that were never designed in any way to exploit parallelism can be
> linked into parallel programs so it seems better to have developers of such a
> library specify the desired behavior if their code is ultimately linked into a
> parallel program -- analogous to requiring that code be thread-safe even if the
> code makes no explicit use of multi-threading.
> 

It's been awhile since I implemented random_init(),
and thought about the combinations for the two 
arguments.  Presonally, I think the standard is 
flawed.  If someone wants to review the wording of
the standard and the implementation details of 
random_init(), I am certainly not going to object.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-12-13  0:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-12 16:24 [Bug fortran/98253] New: Conflicting random_seed/random_init results damian at sourceryinstitute dot org
2020-12-12 17:33 ` [Bug fortran/98253] " kargl at gcc dot gnu.org
2020-12-12 17:47 ` kargl at gcc dot gnu.org
2020-12-12 18:20 ` kargl at gcc dot gnu.org
2020-12-12 18:53 ` dominiq at lps dot ens.fr
2020-12-12 21:20 ` damian at sourceryinstitute dot org
2020-12-12 21:31 ` kargl at gcc dot gnu.org
2020-12-12 22:54 ` damian at sourceryinstitute dot org
2020-12-12 23:55 ` damian at sourceryinstitute dot org
2020-12-13  0:20 ` sgk at troutmask dot apl.washington.edu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).