From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id E3564388E835; Sat, 12 Dec 2020 21:31:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E3564388E835 From: "kargl at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug fortran/98253] Conflicting random_seed/random_init results Date: Sat, 12 Dec 2020 21:31:30 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: fortran X-Bugzilla-Version: 11.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: kargl at gcc dot gnu.org X-Bugzilla-Status: WAITING X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 12 Dec 2020 21:31:31 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D98253 --- 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=20 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=3D.false., image_distinct=3D.false.) do i =3D 1, 3 call random_number(r) print '(F8.5), r end do print * call random_init(repeatable=3D.false., image_distinct=3D.false.) do i =3D 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=3D.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=20 images (don't remember any consideration about teams). The comment in libgfortran/intrinsics/random_init.f90 details=20 what happens with combinations of 'repeatable' and 'image_distinct'=