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

Code generation flags and automatic array confusion

Nathan
Beginner
431 Views

Hello, 

I'm attempting to understand stack overflows brought about by large statically-sized local arrays using ifort on linux. I hoped to produce a stack overflow error by reducing the stack size to 1000kb using "ulimit -s 1000" and then running a test program included below. 

For reference, I compiled this program with gfortran using a variety of options and was given an output: 

In sub1:              1200000
Segmentation fault (core dumped)
 

This makes sense to me. The compiler does not know the size of the array in sub1, so it allocates it to the heap. 

However, compiling with ifort using three different flags: 

ifort -qopenmp test.f90   

ifort -recursive test.f90 

ifort -auto  -heap-arrays 1500 test.f90  

 

All three executables produce the output: 

 In sub1:               1200000
 In sub2:               1200000
 

So, my question is, why is the second subroutine not producing a stack overflow?  I've tried using ifort 16.0.8 and 14.0.4 with similar results. 

I would think that since the compiler knows the size of array p in sub2, it should put it on the stack, given the chosen options at compile time. 

 

 

 

 

program test                                                                                                                                                                                                
  implicit none                                                                                                                                                                                             
                                                                                                                                                                                                            
  integer :: a                                                                                                                                                                                              
                                                                                                                                                                                                            
  a = 300000                                                                                                                                                                                                
                                                                                                                                                                                                            
  call sub1(a)                                                                                                                                                                                              
  call sub2(a)                                                                                                                                                                                              
end program                                                                                                                                                                                                 
                                                                                                                                                                                                            
subroutine sub1(a)                                                                                                                                                                                          
  implicit none                                                                                                                                                                                             
                                                                                                                                                                                                            
  integer,intent(in) :: a                                                                                                                                                                                   
  integer,dimension(a) :: q                                                                                                                                                                                 
                                                                                                                                                                                         
  print*, "In sub1:", sizeof(q)                                                                                                                                                                             
  q = 0                                                                                                                                                                                                     
                                                                                                                                                                                                            
end subroutine sub1                                                                                                                                                                                         
                                                                                                                                                                                                            
subroutine sub2(a)                                                                                                                                                                                          
  implicit none                                                                                                                                                                                             
                                                                                                                                                                                                            
  integer,intent(in) :: a                                                                                                                                                                                   
  integer,dimension(300000) :: p                                                                                                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                            
  print*, "In sub2:", sizeof(p)                                                                                                                                                                             
  p = 0                                                                                                                                                                                                     
                                                                                                                                                                                                            
end subroutine sub2    

 

Thank you. 

0 Kudos
2 Replies
Steve_Lionel
Honored Contributor III
431 Views

ifort's default (-auto-scalars) is that local arrays are statically allocated (unless you made the procedure RECURSIVE or used -auto or some other option that implies -auto.) It's actually sub1 where I might expect a stack overflow, but the compiler probably realized that you never used the array and eliminated it.

0 Kudos
Nathan
Beginner
431 Views

 Indeed the compiler seems to have foregone creating the array. Adding some random numbers and sums to the mix brought about the stack overflows I was expecting.  Thank you for your response.

0 Kudos
Reply