- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
here's another bug report about the Coarray implementation of the Intel Compiler (version 15.0.2). The following code fails with a segfault:
module arrays implicit none type b real,allocatable,dimension(:) :: c end type contains subroutine arraycopyinderivedtype(d,s) type(b),intent(out) :: d type(b),intent(in) :: s if (.not.allocated(d%c)) allocate(d%c(size(s%c))) d%c=s%c end subroutine end module program coarraybug use arrays implicit none type(b),codimension
Cheers,
John
---
John Donners | Senior consultant Supercomputing | SURFsara | Netherlands | www.surfsara.nl |
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I believe, from my own programming experiences (with the Intel compiler), that this does not work. But I am not sure if that is a compiler failure. In case nobody knows something better, I will produce a small working program to do something similar. (I already have a working code, but it's part of a framework). Please give me a couple of days for this.
best regards
Michael Siehl
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
with only some minor changes the code now runs and gives the expected output.
regards
michael
module arrays
implicit none
type b
real,allocatable,dimension(:) :: c
end type
contains
subroutine arraycopyinderivedtype(d,s,intImage)
type(b),intent(out) :: d
!type(b),intent(in) :: s
type(b),codimension
integer, intent(in) :: intImage
! if (.not.allocated(d%c)) allocate(d%c(size(s%c)))
! d%c=s%c
if (.not.allocated(d%c)) allocate(d%c(size(s[intImage]%c)))
d%c=s[intImage]%c
end subroutine
end module
program coarraybug
use arrays
implicit none
type(b),codimension
type(b) :: t,t0
integer image
image=this_image()
if (image.eq.1) then
allocate(v%c(2))
v%c=image
allocate(v0%c(2))
v0%c=image
print*,'image,v,v0=',image,v,v0
endif
sync all
if (image.eq.2) then
write(unit=*,fmt='(a)')'Testing copy of allocatable array component of derived type coarray in the main program..'
if (.not.allocated(t0%c)) allocate(t0%c(size(v0[1]%c)))
t0%c=v0[1]%c
print*,'t0=',t0
write(unit=*,fmt='(a)')'Testing copy of allocatable array component of derived type coarray in subroutine with derived type dummy arguments..'
!call arraycopyinderivedtype(t,v[1])
call arraycopyinderivedtype(t,v,1) ! Image 1
print*,'t=',t
endif
end
image,v,v0= 1 1.000000 1.000000 1.000000
1.000000
Testing copy of allocatable array component of derived type coarray in the main program..
t0= 1.000000 1.000000
Testing copy of allocatable array component of derived type coarray in subroutine with derived type dummy arguments..
t= 1.000000 1.000000
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Michael,
many thanks, that's a nice workaround! I should be able to get my code working with your tip.
However, I do think that this is a problem with the compiler, since it should be possible to pass a coindexed object to a subroutine as a non-coarray dummy argument (see pg. 8, the next-to-last paragraph). Also, the original example has a bit more flexibility, since:
- the s-argument can be a local variable as well as a coindexed object.
- it can be used as a definition for the assignment operator for the derived type b (the intrinsic assignment for derived type b fails as well with an error).
So hopefully the original example can still be accepted as a bug report.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We'll take a look at this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
many thanks for picking this up.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Assume you pass "a coindexed object (member variable) to a subroutine as a non-coarray dummy argument" that has inout attribute, and further assume the subroutine contains other co-array statements, including sync all. However, in the scope of the section of the subroutine the dummy variable had not changed from entry, but an external process made the change before the sync all. Is the dummy argument to be re-synched (changed)?
I hope my query is clear.
In the above case, as an example a scalar dummy, externally (memory-wise) would behave as volatile across change and synch all, but code-wise (to the compiler) would be assumed non-volatile. All kinds of mischief could occur.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To Jim's question, the language rules would generally forbid changing the value of an associated argument except through the dummy, though there would be exceptions such as TARGET. Practically speaking, the compiler would do copy-in/copy-out so such changes are unlikely. An application that did this would be poorly written.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is a known issue, issue ID is DPD200255059. There is an error in the original program in that it allocates the coarray only on image 1. This is incorrect - the language requires that you allocate the coarray to the same coshape on every image. However, when I fix that problem the error still occurs. Sometimes I get the segfault, sometimes bad values.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>There is an error in the original program in that it allocates the coarray only on image 1. This is incorrect - the language requires that you >>allocate the coarray to the same coshape on every image.
Hi,
I think this is not true here. While the above used coarrays v and v0 are indeed declared on all Images, their allocatable components are not and they do not have to be (allocated on every image). This is what Aleksandar Donev calls non-symmetric objects in his Rationale for Co-Arrays in Fortran 2008 paper. (And it is, in my opinion, a reason while main arguments of a Group of Rice University for a different coarray implementation do not hold). While the use of such non-symmetric coarrays brings additional burden to the programmer, it already gives incredible flexibility to what we already can do with Coarray Fortran today. It even allows an MPMD-style of parallel software development with Fortran 2008, instead of the SPMD-style of the common coarrays (symmetric coarrays). I personally use these extensively and exclusively, and have made very good experiences with Intels ifort support of such non-symmetric coarrays. (I currently can't detect any limitations in my own programming).
Still, I do agree with John in that I would certainly appreciate every additional (or undiscovered) feature too. However, I am not familiar with the according passage of the standards text yet, so I can't tell if there is something missing with Intels current implementation.
BTW, even the changed and now working code is not the way I would suggest how to use such non-symmetric coarrays, because this is way too much error-prone. In production code you should completely encapsulate (private) the access to allocatable (or pointer) components of derived type coarrays, e.g. because you can't never be sure there is something allocated on the foreign image. I will code a small working program the next days to show basically what I mean.
best regards
michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, you are correct. When I first looked at it I thought the coarrays themselves were allocatable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To me, the most questionable line in the original code is:
call
arraycopyinderivedtype(t,v[1])
I currently don't believe that the standard does permit an actual coarray argument with a bracket reference [ ] in it. This was also a statement in an (old) CF90 Co-array Programming Manual SR-3908 3.1 from Cray (Document Number 004-3908-001), page 7: "Bracket references cannot appear as actual arguments in subroutine calls or function calls. For example: CALL S3( Y(1,K) [IP], 100 ) ! NOT PERMITTED: BRACKET ACTUAL ".
But I also found the text passage, John mentioned above. It's in chapter 19.4 of Modern Fortran explained, the last paragraph on page 336: "A coindexed object is permitted in most contexts, such as intrinsic operations, instrinsic assignment, input/output lists, and as an actual argument corresponding to a non-coarray dummy argument."
best regards
michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just tried it out. I took the original code and only left the brackets out:
call arraycopyinderivedtype(t,v)
The code now compiles and runs without a runtime failure. But, of course, without the brackets the actual coarray argument v now stands for the (empty) coarray on the current image. According to this situation the program execution does not deliever any output for t:
image,v,v0= 1 1.000000 1.000000 1.000000
1.000000
Testing copy of allocatable array component of derived type coarray in the main program..
t0= 1.000000 1.000000
Testing copy of allocatable array component of derived type coarray in subroutine with derived type dummy arguments..
t=
This is further convincing, that ifort just can't handle the brackets. According to chapter 19.4 of Modern Fortran explained it should be possible. But see also the last sentence of chapter 19.8.1: '...if an actual argument is a coindexed object with an allocatable ultimate component, the corresponding dummy argument must be allocatable, a pointer, or have the intent in or value attribute.' Here, they say nothing that the corresponding dummy argument might be a non-coarray (dummy argument). Therefore, I am a little bit puzzled right now.
best regards
michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well,
currently I do agree with John. His original code with the brackets seems standard conforming to me now. Ifort should be able to handle a coindexed object, resp. the brackets, as an actual argument.
best regards
michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Michael, Steve, Jim,
thanks for the interesting discussion.
In section 12.5.2.4 (Ordinary dummy variables), paragraph 6 of the Fortran 2008 working document
(http://j3-fortran.org/doc/year/10/10-007r1.pdf) it says:
If the actual argument is a coindexed object with an allocatable ultimate component, the dummy argument shall
have the INTENT(IN) or the VALUE attribute.
The INTENT(IN) for coindexed objects with allocatable components is logical, since you might otherwise try to
allocate objects on remote images unknowingly. Section 12.5.2.8 is about co-array dummy variables, so the 'Ordinary' apparently means non-coarray dummy variables.
The code I submitted was indeed in no way an example of good coding practice, but a reduction of the compiler problem to the simplest possible form.
About Jim's remark: that looks indeed like a race condition and it would be the responsibility of the programmer to prevent such bad coding practice.
About the remarks in the Cray documentation: I saw that as well and it had a further
comment that the compiler would accept it if the co-array reference was turned into
an expression, by putting the reference between parentheses:
CALL S3( ( Y(1,K)[IP] ), 100 ) ! PERMITTED: ACTUAL IS EXPRESSION
I get the impression that this was more a limitation of the Cray compiler at the time
of writing of the manual, rather than a limitation of the Fortran language specification.
(it's also a document from 2003, so long before Coarray was an actual standard).

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page