From: Jared Ahern on 22 Apr 2010 15:38 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 22 Apr 2010 17:53 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 23 Apr 2010 09:19 > 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 23 Apr 2010 10:48 > 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 22 Apr 2010 22:54
> > 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 |