- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I just get confused about ifort behavior.
Here is a minimal sample program causing me trouble :
[fortran]
program bug
implicit none
integer,parameter :: nb=1
integer,dimension(5,nb) :: array
integer :: n
n=1
do while (n<=size(array,1))
call fill(2,array(n,:),n)
end do
write(*,*) array
contains
subroutine fill(nb,vec,n)
integer,intent(in)::nb
integer,dimension(nb),intent(out) :: vec
integer,intent(inout) :: n
vec=n
n=n+1
end subroutine fill
end program bug
[/fortran]
output : [bash]0 1 2 3 4[/bash]
And with -check all at compilation i got : "Subscript #1 of the array ARRAY has value 6 which is greater than the upper bound of 5"
Howerer, if i change [fortran] integer,dimension(nb),intent(out) :: vec[/fortran] to an assumed-shape form : [fortran] integer,dimension(:),intent(out) :: vec[/fortran] the program behaves normally and the output is : [bash]1 2 3 4 5[/bash].
This bug (?) does not appear when using gfortran instead of ifort.
ifort version : 12.1.0 20111011
Regards,
Simon.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Very interesting. The issue is that because array(n,:) is not a contiguous slice, it has to do copy-in, copy-out, On return from fill, it is copying the result back but using the updated value of n as the subscript. It shouldn't do that. I will let the developers know.
You could make the vec argument in fill an assumed-shape array or reverse the dimensions so that the slice is contiguous (which would be faster).
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Very interesting. The issue is that because array(n,:) is not a contiguous slice, it has to do copy-in, copy-out, On return from fill, it is copying the result back but using the updated value of n as the subscript. It shouldn't do that. I will let the developers know.
You could make the vec argument in fill an assumed-shape array or reverse the dimensions so that the slice is contiguous (which would be faster).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Entered as issue DPD200249879. I have a nagging feeling that the standard prohibits what you're doing here but I can't yet find the words saying so.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your answer Steve.
I have figured out that the non-contiguous slices and the copy-out involved, are the source of the probleme. But i am not certain to well understand why the assumed shape form doesn't involve non-contiguous slice and thus similar problems (no warning, with -CB compiler option and nb>1).
I am more worried about your remark about the standard. Let me know if you find out i'm doing something wrong that will eventually be forbidden in a next update. For now i'm using assumed-shape that fit better my needs (i can't simply reverse my indexes in my full code), but if my way of doing isn't allowed by the standard i will have to find another solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Assumed-shape avoids the copies so there is no attempt to use the updated value of N after the call updates it. I would recommend your switching to that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer,parameter :: nb=1
integer,dimension(5,nb) :: array
The array is thus array(1:5,1:1)
size(array,1) is thus 5
call fill(2, array(n,:), n) ! call passes referenct to 1 element (array(n,1))
---
fill(nb, vec, n) ! receives (2, referece to one element array(n,1), n) ! n=1:5
integer,dimension(nb),intent(out) :: vec ! declares vec(1:2) !!! wrong size for call with array(5,1)
vec = n ! copies to two elements of callers array(n,1:2)
Note, in event that Fortran permits you to declare the contains routine dummy with larger than callers argument then bear in mind that when you call with n=5 that the statement v=1 writes to array(5,1) and whatever follows.
This is in error.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Jim for your answer.
This is an error I saw after Stever answered, and thus cannot edit my code.
As it doesn't impact my code (this is specific for nb=1) I didn't mention it. Anyway you are right it should be corrected, especially since such error can make debugging very painful.
The line 8 should of course be : call fill(nb, array(n,:), n).
The wrong behavior of the compiler I underlined is unaffected by this correction.
Simon.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The error will occur call whenever nb > size(array(n,:).
Since your pasted code was explicitly calling with nb=2 your above statement is correct....
Up until you copy and paste this into new code and change the first argument to something larger.
It is best not to leave something like this laying around to bite you (or someone else) later.
At least place an assert in there that is enabled in debug build.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Since array is declared as dimension(5,nb), the situation nb > size(array(n,:),2) will never occur in this code.
I agree with you that the fill subroutine should either do some test in case of bad calling or change vec=n to a safer method.
But please, keep in mind that the code I past here has for only purpose the reproduction of a potentialy bug in ifort. Then, it is minimal and the routine it contains are not made to be used elsewhere. It is a separate code, not representative of my actual code, that should not be reused in another context.
Simon.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page