- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear All
With Compaq Visual Fortran Professional v6.6.0 I have encountered a stack overflow problem when using f90 pointers. I understood that pointers are assigned to the HEAP so was not expecting a stack error. The attached code snippet demonstrates this error ... (I have run on a PIII machine with 250MB RAM ... you may have to increase the array dimension N to reproduce the error). It appears that the statement X=Y is using additional storage on the STACK ... and exceeding my stack limit. But why is this (temporary) storage necessary??? Thanks in advance for any comments. Jon.
PROGRAM TEST
INTERFACE
SUBROUTINE S(X,Y,N)
REAL,POINTER::X(:,:,:),Y(:,:,:)
INTEGER::N
END SUBROUTINE S
END INTERFACE
REAL,POINTER::X(:,:,:),Y(:,:,:)
INTEGER::N
N=250
ALLOCATE(X(N,N,N),Y(N,N,N))
X=0.0
CALL S(X,Y,N)
DEALLOCATE(X,Y)
STOP
END
SUBROUTINE S(X,Y,N)
REAL,POINTER::X(:,:,:),Y(:,:,:)
INTEGER::L,M,N
DO I=1,N
DO J=1,N
DO K=1,N
Y(I,J,K)=X(I,J,K) ! Executes OK
ENDDO
ENDDO
ENDDO
Y=Y*Y+Y*Y*Y ! Executes OK
Y=X !!!!! Gives stack overflow !!!!!
RETURN
END SUBROUTINE S
With Compaq Visual Fortran Professional v6.6.0 I have encountered a stack overflow problem when using f90 pointers. I understood that pointers are assigned to the HEAP so was not expecting a stack error. The attached code snippet demonstrates this error ... (I have run on a PIII machine with 250MB RAM ... you may have to increase the array dimension N to reproduce the error). It appears that the statement X=Y is using additional storage on the STACK ... and exceeding my stack limit. But why is this (temporary) storage necessary??? Thanks in advance for any comments. Jon.
PROGRAM TEST
INTERFACE
SUBROUTINE S(X,Y,N)
REAL,POINTER::X(:,:,:),Y(:,:,:)
INTEGER::N
END SUBROUTINE S
END INTERFACE
REAL,POINTER::X(:,:,:),Y(:,:,:)
INTEGER::N
N=250
ALLOCATE(X(N,N,N),Y(N,N,N))
X=0.0
CALL S(X,Y,N)
DEALLOCATE(X,Y)
STOP
END
SUBROUTINE S(X,Y,N)
REAL,POINTER::X(:,:,:),Y(:,:,:)
INTEGER::L,M,N
DO I=1,N
DO J=1,N
DO K=1,N
Y(I,J,K)=X(I,J,K) ! Executes OK
ENDDO
ENDDO
ENDDO
Y=Y*Y+Y*Y*Y ! Executes OK
Y=X !!!!! Gives stack overflow !!!!!
RETURN
END SUBROUTINE S
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I discussed this with another engineer here familiar with the issues. We note that in the Y=X case, the compiler has to assume that the arrays are noncontiguous with different strides. While they do have to be shape-conformant (same number of elements in each dimension), array X could have been passed in as, for example, (1:100:3,:,:) and Y as (201:400:6,:,:).
This means that the compiler has to keep track of, in this case, six different array indices and strides. The case is complex enough that the compiler chooses to simplify life by copying the right-hand side to a contiguous temp before doing the assignment. The compiler might try harder in a future version, but I'd think the effort would be better spent on using the heap instead of the stack for temps.
An interesting observation is that if you replace POINTER in all cases with ALLOCATABLE, no temp is created, because the compiler then is allowed to assume that it is being passed an entire array with unit stride. I suggest getting 6.6B before you try this!
Steve
This means that the compiler has to keep track of, in this case, six different array indices and strides. The case is complex enough that the compiler chooses to simplify life by copying the right-hand side to a contiguous temp before doing the assignment. The compiler might try harder in a future version, but I'd think the effort would be better spent on using the heap instead of the stack for temps.
An interesting observation is that if you replace POINTER in all cases with ALLOCATABLE, no temp is created, because the compiler then is allowed to assume that it is being passed an entire array with unit stride. I suggest getting 6.6B before you try this!
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve for your info! However, I am a little confused by the latter part of your reply ... when you refer to replacing POINTER with ALLOCATABLE as 'an interesting observation' do you mean a code such as below? And can you expand on your comment 'I suggest getting 6.6B before you try this'. Are you suggesting a modification which is not permitted under Compaq Visual Fortran Professional Edition 6.6.0? I am a little tired so sorry if I am being a bit obtuse. Regards, Jon.
PROGRAM TEST
REAL,ALLOCATABLE::X(:,:,:),Y(:,:,:)
INTEGER::N
N=250
ALLOCATE(X(N,N,N),Y(N,N,N))
X=0.0
CALL S(X,Y,N)
DEALLOCATE(X,Y)
STOP
END
SUBROUTINE S(X,Y,N)
REAL::X(N,N,N),Y(N,N,N)
INTEGER::N
DO I=1,N
DO J=1,N
DO K=1,N
Y(I,J,K)=X(I,J,K) ! Executes OK
ENDDO
ENDDO
ENDDO
Y=Y*Y+Y*Y*Y ! Executes OK
Y=X !!!!! Gives stack overflow !!!!!
RETURN
END SUBROUTINE S
PROGRAM TEST
REAL,ALLOCATABLE::X(:,:,:),Y(:,:,:)
INTEGER::N
N=250
ALLOCATE(X(N,N,N),Y(N,N,N))
X=0.0
CALL S(X,Y,N)
DEALLOCATE(X,Y)
STOP
END
SUBROUTINE S(X,Y,N)
REAL::X(N,N,N),Y(N,N,N)
INTEGER::N
DO I=1,N
DO J=1,N
DO K=1,N
Y(I,J,K)=X(I,J,K) ! Executes OK
ENDDO
ENDDO
ENDDO
Y=Y*Y+Y*Y*Y ! Executes OK
Y=X !!!!! Gives stack overflow !!!!!
RETURN
END SUBROUTINE S
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I meant doing a replace of POINTER with ALLOCATABLE eveywhere it appears in your original code. This is a new feature (it comes from the draft of Fortran 2000) and is first supported in 6.6A, not 6.6.0.
Steve
Steve
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