Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
21 Views

Allocatable arrays, stack, heap

Jump to solution

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

Accepted Solutions
Highlighted
Black Belt
21 Views

It's not the allocatable

Jump to solution

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.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran

View solution in original post

0 Kudos
3 Replies
Highlighted
Black Belt
22 Views

It's not the allocatable

Jump to solution

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.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran

View solution in original post

0 Kudos
Highlighted
Beginner
21 Views

Thanks a lot, Steve! Now I

Jump to solution

Thanks a lot, Steve! Now I understand

0 Kudos
Highlighted
21 Views

Alessandro,

Jump to solution

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

0 Kudos