Targets of pointers in coarrays

module m
  type :: t
    integer, pointer :: p
  end type
  type(t) :: ca[*]
 contains
  subroutine subr
    integer, target :: j  ! local stack variable
    j = this_image()
    ca%p => j ! pointer in coarray assigned to target on same image
    sync all
    if (this_image() == 1) then
      print *, sum([(ca[k]%p,k=2,num_images())]) ! dereferences of remote pointers
    end if
    sync all
  end subroutine
end module

Is it conforming &/or supported to reference remote stack variables by means of a pointer ultimate component in a coarray of derived type? There are implementation implications for the runtime distributed memory support library that are worrisome, if this is a feature that needs to work. I can’t find any language in Fortran 2018 that precludes usage like this; can you?

I found the following statement in the standard, that seems to suggest to me that allocatable and/or pointer components of coarray objects cannot be used to access remote data.

A subobject of a coarray is a coarray if it does not have any cosubscripts, vector subscripts, allocatable component selection, or pointer component selection.

But it’s possible I’m misinterpreting that.

For whatever it’s worth, I can’t find anything either.

The standard doesn’t concern itself with stack (or heap) or how a processor arranges memory as long as the processor conforms. From the looks of it, the standard likely finds the situation in the original post not all that different from the one below:

module m
   type :: t
      integer, pointer :: p
   end type
   type(t) :: ca[*]
contains
   subroutine subr
      allocate( ca%p, source=this_image() )
      sync all
      if (this_image() == 1) then
         print *, ( ca[k]%p, k=2,num_images() ) ! dereferences of remote pointers
      end if
      sync all
   end subroutine
end module

where the standard says little about the anonymous target that comes into existence with the ALLOCATE statement. For all it could care, it can very well be a minion holding up a whiteboard!

The standard however seems to care intently, at stated in section 19, as to when variables become undefined and pointers become disassociated or undefined. Any reference to p component of ca in a context outside of the shown subroutine can be fraught and not conform depending on the circumstances.

That’s a coindexed object reference and the usage is ok, as far as I can tell, provided that the pointer is defined and associated (which it will be while subr is active, and beyond if the SAVE attribute is added to J).

MetcalfReid&Cohen have this to say

A coindexed object is permitted in most contexts, such as intrinsic operations, intrinsic
assignment, input/output lists, and as an actual argument corresponding to a non-coarray
dummy argument. On a distributed-memory machine, passing it as an actual argument is
likely to cause a local copy of it to be made before execution of the procedure starts (unless it
has intent out) and the result to be copied back on return (unless it has intent in or the value
attribute). The rules for argument association have been carefully constructed so that such
copying is always allowed.

Pointers are not allowed to have targets on remote images, because this would break the
requirement for remote access to be obvious. Therefore, the target of a pointer is not permitted to be a coindexed object

But here target is local (i.e. in same image as the pointer).

ca%p would be a subobject of a coarray that is NOT regarded as a coarray.

Yes, this is allowed. Informally known as “the pointer trick”. As for the implementation, accessing the remote non-coarray data uses two references. The first is to the parent coarray using the normal coarray referencing schemes, and then extract and fetch the target address from the struct on the remote image back to the image where the reference occurred. Then use that address to access the target data on the remote image. If your referencing scheme requires some sort of memory registration, then the safest approach is to register anything that has the TARGET attribute.