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

Allocatable arrays, stack, heap

Alessandro_D_
New Contributor I
2,933 Views

Dear users,

my understanding of memory allocation is that allocatable arrays are put by default on the heap. However the following simple code generate a stack overflow error:

program test
implicit none

! Purpose: Generate a random array of dimensions(1000,10,30) 
! and limit the maximum value of any array element to be less than or equal to 0.5
! Write two set of statemente: (1) using nested DO-IF loops, (2) using WHERE

!Declaration section
integer :: n1,n2,n3 !Dimensions of allocatable arrays
integer :: i,j,k,status,status_de
real(8), allocatable :: array(:,:,:),array_final(:,:,:),array_final_vec(:,:,:) 

!Execution section

n1 = 1000
n2 = 10
n3 = 30

allocate(array(n1,n2,n3),array_final(n1,n2,n3),array_final_vec(n1,n2,n3),STAT=status)
if (status/=0) then
    write(*,*) 'Allocation failed'
    stop
endif


call RANDOM_SEED()
call RANDOM_NUMBER(array)

!Nested DO-IF loops
do k=1,n3
    do j=1,n2
        do i=1,n1
            if (array(i,j,k)<=0.5d0) then
                array_final(i,j,k) = array(i,j,k)
            elseif(array(i,j,k)>0.5d0) then
                array_final(i,j,k) = 0.5d0
            else
                write(*,*) 'Something is wrong!'
            endif 
        enddo 
    enddo
enddo

!Vectorized WHERE

where (array<=0.5d0)  !Here stack overflow error occurs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    array_final_vec = array
elsewhere
    array_final_vec = 0.5d0
endwhere 

write(*,'(1X,A)') 'Original vector:'
write(*,'(1X,F10.3)') (array(i,1,1), i=1,10)
write(*,*) '...'
write(*,'(1X,A)') 'Nested do-if loops, results:'
write(*,'(1X,F10.3)') (array_final(i,1,1), i=1,10)
write(*,*) '...'
write(*,'(1X,A)') 'Vectorized WHERE, results:'
write(*,'(1X,F10.3)') (array_final_vec(i,1,1), i=1,10)


write(*,*) "Ready to deallocate big arrays..."
deallocate(array,array_final,array_final_vec,STAT=status_de)
if (status_de/=0) then
    write(*,*) 'De-allocation failed'
    stop
endif

end program test

 

The error occurs when the WHERE statement is reached. The surprising thing is that the allocation, the call to random number and the statements with the nested DO-IF loops are executed ok, but as soon as the code reaches the WHERE statement, it throws a stack overflow error, reported below:

Unhandled exception at 0x00D979D9 in Console1.exe: 0xC00000FD: Stack overflow (parameters: 0x00000000, 0x00A42000)

See attached txt for more info.

I was able to solve the problem by setting Fortran>Optimization>Heap Arrays to 0 (which means that all arrays are put on the heap and not on the stack). Can someone clarify why allocatable arrays are put on the stack?? Thanks

(Note: the code above is just a toy example to understand heap vs stack issues)

Best,

Alessandro
 

 

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
2,933 Views

It's not the allocatable array going on the stack, but a temporary array the compiler created in order to evaluate (array<=0.5d0). By enabling the Heap Arrays option, that temporary array now goes on the heap instead of the stack.

View solution in original post

3 Replies
Steve_Lionel
Honored Contributor III
2,934 Views

It's not the allocatable array going on the stack, but a temporary array the compiler created in order to evaluate (array<=0.5d0). By enabling the Heap Arrays option, that temporary array now goes on the heap instead of the stack.

Alessandro_D_
New Contributor I
2,933 Views

Thanks a lot, Steve! Now I understand

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,933 Views

Alessandro,

You should be aware that you can conditionally select and not select the heap array option on a file-by-file basis (provided the offending file is not inlined via IPO). IOW select only the source files that require excessively large temporary arrays to have heap arrays enabled. This can result in some performance improvement.

Jim Dempsey

Reply