- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I get a stack overflow crash when the folowing line is executed:
q = a
where q and a are 2-dimensional arrays of size 774 x 774
They come from a module in the calling routine and are allocated there and passed through into this routine as arguments.
ie.
subroutine caller
use gmod ! contains a and q
allocate (q(774,774))
allocate (a(774,774))
a = .... ! populate a
call callee(a,q)
return
end
subroutine callee(a,q)
real*8 :: a(774,774), q(774,774)
q = a ! crashes here
return
end
It works fine if I replace the line q = a by 2 do loops
do i = 1, 774
do j = 1, 774
q(i,j) = a(i,j)
enddo
enddo
So it seems q = a is creating a temporary array on the stack. Why?
q = a
where q and a are 2-dimensional arrays of size 774 x 774
They come from a module in the calling routine and are allocated there and passed through into this routine as arguments.
ie.
subroutine caller
use gmod ! contains a and q
allocate (q(774,774))
allocate (a(774,774))
a = .... ! populate a
call callee(a,q)
return
end
subroutine callee(a,q)
real*8 :: a(774,774), q(774,774)
q = a ! crashes here
return
end
It works fine if I replace the line q = a by 2 do loops
do i = 1, 774
do j = 1, 774
q(i,j) = a(i,j)
enddo
enddo
So it seems q = a is creating a temporary array on the stack. Why?
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are either q or a defined as pointers? If so, then the compiler can't prove they don't overlap and will have to create a temp for the RHS of the assignment.
Patrick Kennedy
Intel Developer Support
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, they are declared:
REAL(8), ALLOCATABLE :: a(:,:)
REAL(8), ALLOCATABLE :: q(:,:)
REAL(8), ALLOCATABLE :: a(:,:)
REAL(8), ALLOCATABLE :: q(:,:)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel compiler is too quick to use array temporaries for copy operations. It could easily test for array overlap and take the appropriate action. In this specific case, the compiler will know the intended size of a and q (8x774x774) and it can quickly determine if a and q overlap in an adverse way for the more optimal forward copy, and if adverse overlap, perform a reverse copy (IOW perform equivalent to, or simply call, C's memmove). In other situations were strides are involved you may end up having to use a temp. Most instances of "q=a" can be done without use of temp. An "optimizing" compiler should go the little extra distance to make this determination seeing as how frequentlyarrayA = arrayB is performed in programs. This would have the additional advantage of reducing unnecessary cache evictions while writing the temporary array.
Jim Dempsey
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fortran standard doesn't provide for array overlap in the cited case. ifort provides the option -assume:dummy_aliases for legacy code which violates the standard. Without that option, or one of the deprecated forms of it, ifort should not be creating a temporary, and should not require a run-time check such as the one in the memmove() library function.
It's unusual to pass an array as a dummy argument but declare a local fixed size for it (combining a rare instance of f77 syntax with f90 syntax), so the time may not have been taken to have the compiler optimize this case. While the use of f90 syntax with explicit interface or dummy procedure may not invoke all optimizations either, fixing the problem in that case might deserve higher priority.
It's unusual to pass an array as a dummy argument but declare a local fixed size for it (combining a rare instance of f77 syntax with f90 syntax), so the time may not have been taken to have the compiler optimize this case. While the use of f90 syntax with explicit interface or dummy procedure may not invoke all optimizations either, fixing the problem in that case might deserve higher priority.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am quite astonished that the compiler creates a temp for this and will investigate.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Getting back to this - I can't see a temp being created for the assignment given what you've shown us. It might be done if the option /assume:dummy_alias was specified.
If you still think there's a problem, please attach a small but complete source and show the command line you're using.
If you still think there's a problem, please attach a small but complete source and show the command line you're using.
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