From: Jared Ahern on
Hi all,

So I was reading the g95 site the other day and found this paragraph:

"... sent in an illegal coarray code he had a derived type that he was
assigning across images. On a regular code, this causes allocations to
be copied. On a coarray code, this would have been hideous to
implement. Fixed. It turns out to be legal to pass around derived
types that contain pointers, but the pointers are considered to be
undefined on different images."

This got me thinking, why not? Allocatable coarray subcomponents are
allowed. I understand that image A cannot allocate anything on image
B, but why could not image B copy such an object to itself? e.g.

TYPE(mytype)
INTEGER, ALLOCATABLE :: a
END TYPE
TYPE(mytype) :: obj[*]
IF (THIS_IMAGE()==1) THEN
ALLOCATE(obj%a(3))
obj%a = [1,2,3]
ENDIF
SYNC ALL
IF (THIS_IMAGE()==2) obj=obj[1]
WRITE(*,*) THIS_IMAGE()," local ",obj%a," [1] ",obj[1]%a," [2]
",obj[2]%a

Having no luck compiling this on g95, I skimmed N1824 and N1826. This
paragraph in the former may apply:

"To avoid the possibility of a remote allocation, the shapes and
length parameters are required to
agree in an intrinsic assignment to a coindexed object that is an
allocatable array and intrinsic
assignment to a coindexed object with an allocatable ultimate
component is not allowed."

Okay, so perhaps only intrinsic assignment does not work, still not
sure why though. I tried my example above with the addition of a copy
function, but was still unsuccessful: image 2 does not seem to
properly see obj[1]%a, so I can't copy the values. Should this be
possible? Why would my original example not be allowed?

Thanks!
Jared
From: Reinhold Bader on
Hello,

Am 22.04.2010 21:38, schrieb Jared Ahern:
> Hi all,
>
> So I was reading the g95 site the other day and found this paragraph:
>
> "... sent in an illegal coarray code he had a derived type that he was
> assigning across images. On a regular code, this causes allocations to
> be copied. On a coarray code, this would have been hideous to
> implement. Fixed. It turns out to be legal to pass around derived
> types that contain pointers, but the pointers are considered to be
> undefined on different images."
>
> This got me thinking, why not? Allocatable coarray subcomponents are
> allowed. I understand that image A cannot allocate anything on image
> B, but why could not image B copy such an object to itself? e.g.
>
> TYPE(mytype)
> INTEGER, ALLOCATABLE :: a
> END TYPE
> TYPE(mytype) :: obj[*]
> IF (THIS_IMAGE()==1) THEN
> ALLOCATE(obj%a(3))
> obj%a = [1,2,3]
> ENDIF
> SYNC ALL
> IF (THIS_IMAGE()==2) obj=obj[1]
> WRITE(*,*) THIS_IMAGE()," local ",obj%a," [1] ",obj[1]%a," [2]
> ",obj[2]%a
>
> Having no luck compiling this on g95, I skimmed N1824 and N1826. This
> paragraph in the former may apply:
>
> "To avoid the possibility of a remote allocation, the shapes and
> length parameters are required to
> agree in an intrinsic assignment to a coindexed object that is an
> allocatable array and intrinsic
> assignment to a coindexed object with an allocatable ultimate
> component is not allowed."

I think this would not apply, since the entity assigned to in your
code is not coindexed. Apart from problems in your type definition,
which presumably should read

type :: mytype
integer, allocatable :: a(:)
end type

I believe your code to be legal, since a non-coindexed entity is
treated as if it were a "normal" Fortran entity. It should auto-allocate
the component to the right size and transfer the remote component
values into it.

Note that the matter would be different if the type component had the
pointer attribute instead of the allocatable attribute. In this case,
component assignment rules would imply establishing pointer association
to a remote object, which is disallowed. Hence in this case, the pointer
component becomes undefined.

>
> Okay, so perhaps only intrinsic assignment does not work, still not
> sure why though. I tried my example above with the addition of a copy
> function, but was still unsuccessful: image 2 does not seem to
> properly see obj[1]%a, so I can't copy the values. Should this be
> possible? Why would my original example not be allowed?
>
> Thanks!
> Jared

Regards
Reinhold

From: Jared Ahern on
> type :: mytype
> integer, allocatable :: a(:)
> end type

Ah yes, this is of course correct. Typo, sorry.

> If your components are of polymorphic
> allocatables, or parameterized derived types, then how do you expect
> the compiler to figure out what data type and type parameters to copy
> over from image 1?

So this is actually a question that I had when reading N1824. Of
late, I have been starting to use the polymorphic features of F03, now
that more implementations are closer to completely supporting that
standard. But Reid states:

"So that the implementation does not need to access the dynamic type
of an object on another
image, no references are permitted to a polymorphic subobject of a
coindexed object or to a
coindexed object that has a polymorphic allocatable subcomponent"

I generally end up creating types with many nested allocations, some
of whose entities are polymorphic; I had planned to integrate coarrays
in the future. But this seems to say that you can't use polymorphism
in combination with coarrays, which to me greatly lessens the
usefulness of polymorphism in general. It would be unfortunate if you
couldn't efficiently use significant polymorphism for any code that
needs to use parallel processing.

> > One may be excited about coarrays in F08, but if you use allocatable
> > components in your coarrays, I'd love to know how robust your compiler
> > is in supporting them :-)
>
> I'm sure initial implementations will generally have limitations in this area.

I hope that I'm mistaken, and that it's only an implementation issue,
and that allocatables and CLASS/SELECT TYPE/ABSTRACT/DEFERRED/etc are
allowed be used with coarray entities and their subcomponents.
Clearly it's challenging, but it would be terribly useful.
From: Jared Ahern on
> So this is actually a question that I had when reading N1824.  Of
> late, I have been starting to use the polymorphic features of F03, now
> that more implementations are closer to completely supporting that
> standard. But Reid states:
>
> "So that the implementation does not need to access the dynamic type
> of an object on another image, no references are permitted to a
> polymorphic subobject of a coindexed object or to a coindexed object
> that has a polymorphic allocatable subcomponent"

I think that C617 in N1826 is the constraint in question, fyi.
From: Jim Xia on


>
> type :: mytype
>   integer, allocatable :: a(:)
> end type
>
> I believe your code to be legal, since a non-coindexed entity is
> treated as if it were a "normal" Fortran entity. It should auto-allocate
> the component to the right size and transfer the remote component
> values into it.



Not that simple. Or is it?


"
IF (THIS_IMAGE()==2) obj=obj[1]
"


I recall we have debated intensely on the supports for coindexed
objects with allocatable components during WG5 meetings. As I can
remember as the final outcome, the quoted line is legal by the
standard. However there are many hairy details exposed if you're
going further. The intrinsic assignment being the easiest case, even
so the implementations may not be nearly as easy as it seems. In your
example, you have integer types as the component and it seems feasible
to copy data from remote image. If your components are of polymorphic
allocatables, or parameterized derived types, then how do you expect
the compiler to figure out what data type and type parameters to copy
over from image 1? How much information can you think the compiler
has to figure out? Imagine you're on the distributed system and your
local libraies may not even be the same as the remote machine, and you
have no clue as to the dynamic type of the component of the coindexed
object on a remote image.


The next trouble will be the function calls. "call foo (obj[1])". If
foo() modifies its dummy arguments, how would you expect the modified
value being passed back to image 1? And what state of "obj on image 1"
would be in during the execution of foo? If this is allowed, then
you're essentially doing a remote allocation and remote operation,
which is against the coarray operation principle. So the final
decision is to allow "call foo(obj[1])" ONLY IF foo() does not modify
its dummy. But again, finding out the all the relevant information on
the data being fetched from image 1 will pose challenges to compilers
on a distributed system.


One may be excited about coarrays in F08, but if you use allocatable
components in your coarrays, I'd love to know how robust your compiler
is in supporting them :-)


Cheers,

Jim