Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29594 Discussions

Stack overflow with f90 pointer arrays

ratty
Beginner
1,154 Views
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
0 Kudos
3 Replies
Steven_L_Intel1
Employee
1,154 Views
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
0 Kudos
ratty
Beginner
1,154 Views
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
0 Kudos
Steven_L_Intel1
Employee
1,154 Views
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
0 Kudos
Reply