Community
cancel
Showing results for
Did you mean:
Highlighted
New Contributor I
231 Views

## Allocatable arrays, stack, heap

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)

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

Tags (1)

Accepted Solutions
Highlighted
Black Belt Retired Employee
231 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.

3 Replies
Highlighted
Black Belt Retired Employee
232 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.

Highlighted
New Contributor I
231 Views

Thanks a lot, Steve! Now I understand

Highlighted
Black Belt
231 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