I’m having some trouble with some fortran code segfaulting when optimization is enabled in pgfortran.
Specifically, I’ve set up a 3D allocatable array. Under some circumstances, its allocated, and under these same circumstances, it is read later in the code. The circumstances which would prevent it from being allocated also prevent it from being accessed later in the code. However, when I compile with optimization (-O2) enabled, I am seeing segfaults resulting from accessing memory address 0x0. If I allocate this array even if the code shouldn’t access it, the program runs to completion. The problem also goes away if I compile with bounds checking (-Mbounds) enabled. In addition, the code compiles and runs without issue with gfortran, even when -O2 is used.
Below is a representative simplification. I’ve tried to make it as simple as possible. Note that in the actual code, I’m not doing things like empty ‘else’ statements. There is meaningful code within those regions. I removed as much code as I could while still making the problem repeatable.
It seems as though the compiler is attempting to perform the operations inside the conditionals even if the criteria is not met. Presumably this would be an optimization technique, and the results would only be used if the conditions were met?
I appreciate any help with this.
module testmod real utest real, allocatable :: height(:,:),heightveg(:,:),can(:,:,:), z(:), zm(:) integer, allocatable :: cell(:,:,:) integer mx, my, mz, ktest,un, ustar1, ustar2, el integer i,j,k,kk,klow, dummy end module program main use testmod implicit none ktest = 0 mx = 10 my = 10 mz = 10 utest = 0.0 un = 0 ustar2 = 0 dummy = 0 allocate(height(mx,my), heightveg(mx,my)) allocate(cell(mx,my,mz),zm(mz), z(mz)) !allocate(can(mx,my,mz)) height(:,:) = 0.0 heightveg(:,:) = 0.0 cell(:,:,:) = 0 zm(:) = 0.0 z(:) = 0.0 j=1 i=1 !this whole loop should do nothing. all the conditions for the 3 if blocks below should !not be met. do k=2,mz !even though this if block should never be executed (cell is always = 0), removing it allows the code to run if(cell(i,j,k) .ge. 1)then if(height(i,j) .gt. 0 .and. cell(i,j,k) .ne. 3)then else endif endif !because heightveg is zero everywhere, nothing inside this if statement should be !executed. Even so, allocating the array 'can', which is only used within this if !statement, allows the program to run to completion if(heightveg(i,j) .ge. 1)then if(k .le. 5)then else if(can(i,j,ktest) .ne. 0.0)then el=utest endif endif endif if(zm(k) .ge. 1)then do kk=2,mz klow=kk if(max(height(i,j),heightveg(i,j))<z(kk))exit !replacing 'exit' with 'dummy = dummy + 1' allows the program to run to completion enddo if(k .eq. klow+1)then if(height(i,j) .ge. heightveg(i,j))then else dummy = dummy + 1 endif endif if(k .gt. klow)then if(heightveg(i,j) .gt. height(i,j))then if(un .ge. 0)then else endif else !commenting this line out results in a working executable endif endif endif enddo print *, dummy end program