- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I' m using the following compiler:
Intel Fortran Intel 64 Compiler XE for applications running on Intel 64, Version 12.1.1.256 Build 20111011
Check out the following code:
The results that I get are the following, using the -assume realloc_rhs option which applies Fortran 2003 rules:
Thanks,
Alexandros
I' m using the following compiler:
Intel Fortran Intel 64 Compiler XE for applications running on Intel 64, Version 12.1.1.256 Build 20111011
Check out the following code:
[fortran]program test implicit none real, allocatable, dimension(:,:) :: a1, a2, a3, a4 real, dimension (4,3) :: c c = reshape( real([ 1,2,3,4, 5,6,7,8, 9,0,1,2 ]), [4,3] ) allocate(a1(0:3,0:2)) allocate(a2(0:3,0:2)) allocate(a3(0:5,0:7)) allocate(a4(0:5,0:7)) a1 = c a2(:,:) = c a3 = c a4(:,:) = c print *, shape(c) print *, lbound(c,1), lbound(c,2) print *, ubound(c,1), ubound(c,2) print * print *, shape(a1) print *, lbound(a1,1), lbound(a1,2) print *, ubound(a1,1), ubound(a1,2) print * print *, shape(a2) print *, lbound(a2,1), lbound(a2,2) print *, ubound(a2,1), ubound(a2,2) print * print *, shape(a3) print *, lbound(a3,1), lbound(a3,2) print *, ubound(a3,1), ubound(a3,2) print * print *, shape(a4) print *, lbound(a4,1), lbound(a4,2) print *, ubound(a4,1), ubound(a4,2) end program test [/fortran]
The results that I get are the following, using the -assume realloc_rhs option which applies Fortran 2003 rules:
[plain] 4 3 1 1 4 3 4 3 0 0 3 2 4 3 0 0 3 2 4 3 1 1 4 3 6 8 0 0 5 7 [/plain]The results for arrays a2, a3 and a4 are as expected, but for array a1 they are not. From what I understand the assignement a1=c should also cause the bounds of a1 to become the same as those of c. However, this does not happen, in contrast to the case of the assignement a3=c which works fine. It seems that in the case a1=c, since the shapes of a1 and c match, the compiler chooses not to deallocate/reallocate a1 for efficiency. However, shouldn't the bounds of a1 change to match those of c?
Thanks,
Alexandros
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The standard says that if the shape (and other characteristics not applicable here) match, then the array is not reallocated. Consequently the bounds do not change.
If the bounds were changed then this would be different behaviour to something that was well defined under Fortran 95.
If the bounds were changed then this would be different behaviour to something that was well defined under Fortran 95.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear IanH,
I'm sorry but I don't agree with you, it still seems to me like a bug. This is an important issue which makes the use of allocatable array assigment difficult. It basically means that in a code where the bounds of the arrays change dynamically you can't know in advance what the bounds of the array "a1" will be after the assignement "a1=c". Will lbound(a1) equal lbound(c)? Or will it equal 1? Nobody knows. So, instead of a plain assignement "a1=c" one would have to use everywhere the following bulky piece of code:
I don't know much about how compilers work internally, but I assume that in case "a1" and "c" have the same shape but different bounds, "a1" does not have to be completely reallocated: It could still point to the same adress in memory, where the contents of "c" will be copied (which is possible since the shapes match). However, the bounds of "a1" could change to match those of "c", which is just a change in the descriptor of the array "a1". This would enable one to use the assignement "a1=c" instead of the bulky piece of code I've included above.
I'm sorry but I don't agree with you, it still seems to me like a bug. This is an important issue which makes the use of allocatable array assigment difficult. It basically means that in a code where the bounds of the arrays change dynamically you can't know in advance what the bounds of the array "a1" will be after the assignement "a1=c". Will lbound(a1) equal lbound(c)? Or will it equal 1? Nobody knows. So, instead of a plain assignement "a1=c" one would have to use everywhere the following bulky piece of code:
[fortran]if ( all(shape(a1) == shape(c)) ) then deallocate(a1) allocate(a1(lbound(c,1):ubound(c,1),lbound(c,2):ubound(c,2))) a1 = c else a1 = c end if[/fortran]I'm sure this is not what was intended by those who wrote the Fortran standard. I haven't read the standard myself, but I've read "modern Fortran Explained" by Metcalf et al which follows the standard very closely, and there it says that if the shapes of a1 and c match then the compiler is free to choose whether a1 will be reallocated or not. Since all compilers should produce the same result, whether a1 is reallocated or not should not lead to different lbounds for a1, which should be the same as those of array "c". If one wishes to ratain the original bounds of a1, then the statement "a1(:,:)=c" should be used instead of "a1=c", according to "modern Fortran explained" - this is the well defined Fortran 95 behaviour that you mention.
I don't know much about how compilers work internally, but I assume that in case "a1" and "c" have the same shape but different bounds, "a1" does not have to be completely reallocated: It could still point to the same adress in memory, where the contents of "c" will be copied (which is possible since the shapes match). However, the bounds of "a1" could change to match those of "c", which is just a change in the descriptor of the array "a1". This would enable one to use the assignement "a1=c" instead of the bulky piece of code I've included above.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The F2003 (and F2008) standard says:
"If variable is an allocated allocatable variable, it is deallocated if expr is an array of different shape or any of the corresponding length type parameter values of variable and expr differ. If variable is or becomes an unallocated allocatable variable, then it is allocated with each deferred type parameter equal to the corresponding type parameters of expr , with the shape of expr , and with each lower bound equal to the corresponding element of LBOUND(expr )."
There's a link at the top of the forum for the standard document. The relevant bit is in 7.4.1.3 of F2003. Have a read!
If you care about the bounds, pass the variable as an actual argument to an INTENT(OUT), ALLOCATABLE dummy argument of a subroutine, or make the variable a component of a derived type. You could also simplify your example code to:
I have Modern Fortran Explained too. I feel that its treatment of this area needs work. Note that it describes the allocate on assignment added in F2003 (15.5.2) as an extension of the rules for allocatable components. This is unfortunate - the behaviour is very similar but not the same - crucially for your example no reallocation happens for an allocatable variable when the shape already matches, while allocatable components are always (effectively) deallocated first and then reallocated (keep reading the same section of the standard as quoted above for the text that deals with them).
If the bound of the allocatable was changed when the shape matched then that would have been a change in well defined behaviour from Fortran 95. That's what would have been a bug!
"If variable is an allocated allocatable variable, it is deallocated if expr is an array of different shape or any of the corresponding length type parameter values of variable and expr differ. If variable is or becomes an unallocated allocatable variable, then it is allocated with each deferred type parameter equal to the corresponding type parameters of expr , with the shape of expr , and with each lower bound equal to the corresponding element of LBOUND(expr )."
There's a link at the top of the forum for the standard document. The relevant bit is in 7.4.1.3 of F2003. Have a read!
If you care about the bounds, pass the variable as an actual argument to an INTENT(OUT), ALLOCATABLE dummy argument of a subroutine, or make the variable a component of a derived type. You could also simplify your example code to:
[fortran]if (allocated(a1)) deallocate(a1) a1 = c[/fortran]
I have Modern Fortran Explained too. I feel that its treatment of this area needs work. Note that it describes the allocate on assignment added in F2003 (15.5.2) as an extension of the rules for allocatable components. This is unfortunate - the behaviour is very similar but not the same - crucially for your example no reallocation happens for an allocatable variable when the shape already matches, while allocatable components are always (effectively) deallocated first and then reallocated (keep reading the same section of the standard as quoted above for the text that deals with them).
If the bound of the allocatable was changed when the shape matched then that would have been a change in well defined behaviour from Fortran 95. That's what would have been a bug!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, thanks. I see your point, and it is reasonable: In Fortran 95 an expression such as "a1=c" would be legal if they had the same shape, in which case the bounds of a1 would not change. And this behaviour should be exhibited also by F2003 / F2008 since in the standard, in section 1.6.1 it doesn't say that F2003 adopts a different behaviour concerning this matter (thanks also for the link to the standards by the way).
However, I am a bit confused because in the man page of ifort it says that there is an option -assume [no]realloc_lhs which:
"Determines whether allocatable objects on the left-hand side of an assignment are treated according to
Fortran 2003 rules or Fortran 95/90 rules."
This seems to imply that F2003 and F95 behave differently! And it should refer to the case when the shapes of "variable" and "expr" are the same, because the case when their shapes are different is not allowed in F95 anyway if I interpret the F95 standard correctly (it says "variable and expr shall conform in shape" in section 7.5.1.4 of the F95 standard).
I have to apologise also for a mistake I made in my previous post: Metcalf et al do not say that the compiler is free to choose whether "variable" will be reallocated (section 15.5.2 as you noted) - but they say this in connection with allocatable components in section 6.5.6 (p. 108 "Note that if the component of variable is already allocated with the same shape, the compiler may choose to avoid the overheads of deallocation and reallocation"). Hopefully this does not introduce the possibility that the bounds of the corresponding allocatable components of "variable" and "expr" are different!
Anyway, its a pitty that due to the F95 conformance issue the programmer can't be sure that after an assignement such as "a1=c" the allocatable variable "a1" is an exact copy of "c".
However, I am a bit confused because in the man page of ifort it says that there is an option -assume [no]realloc_lhs which:
"Determines whether allocatable objects on the left-hand side of an assignment are treated according to
Fortran 2003 rules or Fortran 95/90 rules."
This seems to imply that F2003 and F95 behave differently! And it should refer to the case when the shapes of "variable" and "expr" are the same, because the case when their shapes are different is not allowed in F95 anyway if I interpret the F95 standard correctly (it says "variable and expr shall conform in shape" in section 7.5.1.4 of the F95 standard).
I have to apologise also for a mistake I made in my previous post: Metcalf et al do not say that the compiler is free to choose whether "variable" will be reallocated (section 15.5.2 as you noted) - but they say this in connection with allocatable components in section 6.5.6 (p. 108 "Note that if the component of variable is already allocated with the same shape, the compiler may choose to avoid the overheads of deallocation and reallocation"). Hopefully this does not introduce the possibility that the bounds of the corresponding allocatable components of "variable" and "expr" are different!
Anyway, its a pitty that due to the F95 conformance issue the programmer can't be sure that after an assignement such as "a1=c" the allocatable variable "a1" is an exact copy of "c".

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