[J3] Revisiting correspondence of unallocated coarrays

Bader, Reinhold Reinhold.Bader at lrz.de
Fri Mar 29 14:16:46 UTC 2024


Dear all,

attached a draft J3 document for discussion.

Regards
Reinhold
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20240329/b34c9732/attachment.htm>
-------------- next part --------------
To: J3                                                     J3/##-###
From: TBD
Subject: Correspondence of unallocated coarrays
Date: 2024-April-##
References: 24-007, 23-219

Introduction
~~~~~~~~~~~~

9.7.1.2 paras 3-5 specify rules and restrictions for allocation of 
coarrays that are intended to assure that the resulting objects are 
consistently set up. This paper attempts to demonstrate that the 
specifications for this are incomplete, and to provide corrections for 
this.

Examples
~~~~~~~~

Consider the following programs, executed on two images:

program allocation_1
   implicit none

   integer, allocatable :: a[:], b[:]
   integer :: i

   if (this_image() == 1) then
      allocate(a[1:*], b[2:*])     ! (1A)
   else
      allocate(b[2:*], a[1:*])     ! (1B)
   end if
   a = 1
   b = 2
   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

Compilers produce widely varying behaviour for this:
- a run time error report that two different ALLOCATE statements
  were executed for the same object on different images
- output like

On image            1
 a[           1 ] ==            1
 a[           2 ] ==            2
 b[           2 ] ==            2
 b[           3 ] ==            1
 On image            2
 a[           1 ] ==            2
 a[           2 ] ==            1
 b[           2 ] ==            1
 b[           3 ] ==            2
 
  which indicates that correspondence of coarrays is set up by 
  appearance of the object in an ALLOCATE statement, and as a 
  result there is no agreement between images on what coarrays 
  "a" and "b" refer to (at least not in the same sense as for
  nonallocatable coarrays)
- crashes at run-time  


program allocation_2
   implicit none

   integer, allocatable :: a[:], b[:]
   integer :: i

   if (this_image() == 1) then
      call allocate_them(a, b)    ! (2A)
   else
      call allocate_them(b, a)    ! (2B)
   end if
   a = 1
   b = 2
   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_[1:*], b_[2:*])
   end subroutine
end program

- The typical output for this is:

 On image            1
 a[           1 ] ==            1
 a[           2 ] ==            2
 b[           2 ] ==            2
 b[           3 ] ==            1
 On image            2
 a[           2 ] ==            2
 a[           3 ] ==            1
 b[           1 ] ==            1
 b[           2 ] ==            2

 so again there is no agreement between images on what coarrays "a"
 and "b" are, and in this case even the lower cobounds differ.
 
Questions
~~~~~~~~~

(Q1) Is allocation_1 standard-conforming?

(Q2) Is allocation_2 standard-conforming?

Answers and discussion
~~~~~~~~~~~~~~~~~~~~~~

(A1) No, allocation_1 is not standard-conforming. This is implied by
     9.7.2.1 para 5, which states that 
     "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." 
      However, this is only rather indirectly deduced from text that
      deals with the synchronization properties of ALLOCATE, so a 
      clarifying edit is supplied. An analogous argument can be made
      for DEALLOCATE.
     
     
(A2) 9.7.2.1 para 4 has "If the coarray is a dummy argument, the 
     ultimate arguments (15.5.2.4) on those images shall be 
     corresponding coarrays.", which seems to have the intention of 
     making this invalid. However, the definition of "corresponding
     coarray" in 5.4.7 is insufficient to support this interpretation, 
     since it limits itself to established coarrays, and unallocated
     coarrays are not established. Coarrays therefore can never be 
     allocated via a dummy argument because they cannot satisfy the 
     correspondence requirement. This was not intended, so edits are
     supplied to correct this omission.

Edits to 14-007
~~~~~~~~~~~~~~~

In "5.4.7 Coarray", para 3, after "(5.4.8).", replace the subsequent
sentence by

"For each unallocated coarray or coarray potential subobject component
 (7.5.1), there exists a corresponding unallocated object or subobject 
 with the same declared type, rank, corank and non-deferred type 
 parameters on each image of the current team. For such objects that 
 are not dummy arguments or subobjects thereof, the corresponding object
 is
 * the coarray with the same name on those images, and, if the object 
   is a local unsaved variable of a recursive procedure, at the same 
   depth of recursion of that procedure, or
 * the potential subobject component of the same named object on those
   images, with the same component name, at the same level of component 
   selection, if a subobject of an array, the same position in 
   array element order, and if the named object is a local unsaved
   variable of a recursive procedure, at the same depth of recursion
   of that procedure.
 For such objects that are dummy arguments or subobjects thereof, the 
 corresponding object or subobject is that of its ultimate argument on
 those images, which shall be declared with the same name in the same 
 scoping unit."
 
{The additional complexity is needed to also cover all kinds of 
 subobject selection, as well as coarrays in recursive procedures}.
   
In "5.4.7 Coarray", para 4, replace "The set of corresponding coarrays"
by "The set of corresponding established coarrays".

{Now that unallocated coarrays can correspond, the sentence otherwise
 becomes wrong}.
 
In "9.7.1.2 Execution of an ALLOCATE statement", replace para 4 by

"If an allocation specifies a coarray or a coarray potential subobject
 component, the same ALLOCATE statement shall be executed for its 
 corresponding object or subobject (5.4.7) on each active image of the
 current team, with the same dynamic type and the same values of 
 corresponding type parameters. The values of corresponding bounds 
 and corresponding cobounds shall be the same on those images." 

{significantly shortened, since we now have a solid definition to 
 refer to that covers all the situations}.
 
In "9.7.3.2 Deallocation of allocatable variables", replace para 11 by

"If an allocate-object is a coarray or a coarray subobject, the same
 DEALLOCATE statement shall be executed for its corresponding object or
 subobject on those images." 
 
{It may also be appropriate to move para 11 to come before para 10}.
 
{No edits done to 15.5.2.14 and 16.6, assuming that the 5.4.7 para 4 
 edit covers this already}. 
 







More information about the J3 mailing list