[J3] Corresponding Coarrays In Allocation
Brad Richardson
everythingfunctional at protonmail.com
Thu Feb 22 13:26:46 UTC 2024
Hi All,
Following up, I never heard any response to this. I'm happy to write up
an Interp if warranted. I also think it would be possible to create a
similar example where the same coarray variable is allocated on all
images, but `move_alloc`ed to different variables on different images.
Regards,
Brad
On Tue, 2023-12-12 at 15:44 +0000, Brad Richardson via J3 wrote:
> Hi All,
>
> There are a handful of places where deallocation of coarrays talk
> about
> requiring corresponding coarrays, including with regards to dummy
> arguments requiring corresponding actual arguments. It even says
> something similar with regards to allocation when the allocate-object
> is a dummy argument. But it is not 100% clear what "corresponding"
> necessarily means.
>
> Take the following example. At first it might seem valid.
>
> program allocation
> implicit none
>
> integer, allocatable :: a[:], b[:]
> integer :: i
>
> if (this_image() == 1) then
> allocate(a[1:*], b[2:*])
> else
> allocate(b[2:*], a[1:*])
> end if
> a = this_image()
> b = this_image() + num_images()
> sync all
> critical
> print *, "On image ", this_image()
> do i = lcobound(a, dim=1), ucobound(a, dim=1)
> print *, "a[", i, "] == ", a[i]
> end do
> do i = lcobound(b, dim=1), ucobound(b, dim=1)
> print *, "b[", i, "] == ", b[i]
> end do
> end critical
> end program
>
> Two compilers seem to have interpreted "corresponding" to mean same
> position in the executed allocate statements. I.e.
>
> Using crayftn I get,
>
> On image 4
> a[ 1 ] == 5
> a[ 2 ] == 2
> a[ 3 ] == 3
> a[ 4 ] == 4
> b[ 2 ] == 1
> b[ 3 ] == 6
> b[ 4 ] == 7
> b[ 5 ] == 8
> On image 3
> a[ 1 ] == 5
> a[ 2 ] == 2
> a[ 3 ] == 3
> a[ 4 ] == 4
> b[ 2 ] == 1
> b[ 3 ] == 6
> b[ 4 ] == 7
> b[ 5 ] == 8
> On image 1
> a[ 1 ] == 1
> a[ 2 ] == 6
> a[ 3 ] == 7
> a[ 4 ] == 8
> b[ 2 ] == 5
> b[ 3 ] == 2
> b[ 4 ] == 3
> b[ 5 ] == 4
> On image 2
> a[ 1 ] == 5
> a[ 2 ] == 2
> a[ 3 ] == 3
> a[ 4 ] == 4
> b[ 2 ] == 1
> b[ 3 ] == 6
> b[ 4 ] == 7
> b[ 5 ] == 8
>
> With ifx I get
>
> On image 3
> a[ 1 ] == 5
> a[ 2 ] == 2
> a[ 3 ] == 3
> a[ 4 ] == 4
> b[ 2 ] == 1
> b[ 3 ] == 6
> b[ 4 ] == 7
> b[ 5 ] == 8
> On image 4
> a[ 1 ] == 5
> a[ 2 ] == 2
> a[ 3 ] == 3
> a[ 4 ] == 4
> b[ 2 ] == 1
> b[ 3 ] == 6
> b[ 4 ] == 7
> b[ 5 ] == 8
> On image 2
> a[ 1 ] == 5
> a[ 2 ] == 2
> a[ 3 ] == 3
> a[ 4 ] == 4
> b[ 2 ] == 1
> b[ 3 ] == 6
> b[ 4 ] == 7
> b[ 5 ] == 8
> On image 1
> a[ 1 ] == 1
> a[ 2 ] == 6
> a[ 3 ] == 7
> a[ 4 ] == 8
> b[ 2 ] == 5
> b[ 3 ] == 2
> b[ 4 ] == 3
> b[ 5 ] == 4
>
> But with gfortran + OpenCoarrays I get
>
> On image 1
> a[ 1 ] == 1
> a[ 2 ] == 6
> a[ 3 ] == 7
> a[ 4 ] == 8
> b[ 2 ] == 5
> b[ 3 ] == 2
> b[ 4 ] == 3
> b[ 5 ] == 4
> On image 2
> a[ 1 ] == 5
> a[ 2 ] == 2
> ^CError: Command:
> `/usr/bin/mpiexec -n 4 ./example`
> failed to run.
>
> And then with nagfor I get
>
> Runtime Error: example.f90, line 10: Image 1 is executing a different
> ALLOCATE statement (at line 8 of example.f90)
> Program terminated by fatal error
> zsh: IOT instruction (core dumped) ./example
>
> And indeed, while I didn't seem to find it stated explicitly
> anywhere,
> my reading of the following excerpt from 9.7.1.2 would seem to imply
> that all images must execute the same allocate statement.
>
> execution on the active images of the segment (11.7.2) following the
> statement is delayed until all other active images in the current
> team
> have executed the same statement the same number of times in this
> team.
>
> I then tried moving the allocation into a subroutine, as follows:
>
> program allocation
> implicit none
>
> integer, allocatable :: a[:], b[:]
> integer :: i
>
> if (this_image() == 1) then
> call allocate_them(a, b)
> else
> call allocate_them(b, a)
> end if
> a = this_image()
> b = this_image() + num_images()
> sync all
> critical
> print *, "On image ", this_image()
> do i = lcobound(a, dim=1), ucobound(a, dim=1)
> print *, "a[", i, "] == ", a[i]
> end do
> do i = lcobound(b, dim=1), ucobound(b, dim=1)
> print *, "b[", i, "] == ", b[i]
> end do
> end critical
> contains
> subroutine allocate_them(a_, b_)
> integer, allocatable, intent(inout) :: a_[:], b_[:]
>
> allocate(a_[*], b_[*])
> end subroutine
> end program
>
> crayftn and ifx observe the same behavior, and nagfor now agrees with
> them, and gfortran+OpenCoarrays still crashes.
>
> The following excerpt from 9.7.1.2 seems to hint at the above being
> invalid, but without an explicit definition of what "corresponding"
> means, it's still not quite clear.
>
> If the coarray is a dummy argument, the ultimate arguments (15.5.2.4)
> on those images shall be corresponding coarrays. If the coarray is an
> ultimate component of a dummy argument, the ultimate arguments on
> those
> images shall be declared with the same name in the same scoping unit;
>
> I.e., it could be interpreted to mean that, after execution of the
> allocate statement, the coarray named by `a` on image 1 corresponds
> to
> the coarray named by `b` on all other images, and vice versa. Indeed,
> all of the compilers currently supporting coarrays seem to behave
> this
> way (excepting the failure to complete execution).
>
> So the questions.
>
> Must a coarray always be allocated by the same allocate statement on
> all images in the current team?
>
> Does "corresponding coarray" always mean "the same component if it is
> a
> component, of the same variable declared at the same depth of
> recursion
> if it is a local, unsaved variable of a recursive procedure"?
>
> If the answer to both questions is yes, should this be made more
> explicit (or at least more obvious)?
>
> Regards,
> Brad Richardson
>
More information about the J3
mailing list