I have an issue with gfortran that I am trying to understand on a general level to avoid encountering it again in the future. Specifically, I am trying to understand the behavior of nested implied do loops when reading in data and how this is affected by gfortran optimization flags.
As part of a larger program that I am modifying, I am trying to read in some data and store them in a matrix, sttheight
, which in my specific case is a vector given the dimensions of the variables used when allocating it. A minimum working example showing the issue is given below.
The problem is pertaining to the nested implied do loop construct used when reading the variable from the input-file. When compiling the program with gfortran Read_fct.f90 -o Read
, and running it, it produces the desired output, which is printing the 8 floating point variables in Input.txt
:
0.00000000 14370.0117 14370.0117 14370.0117 14370.0117 14370.0117 14370.0117 14370.0117
I'm using: "GNU Fortran (GCC) 12.2.0 20220819 (HPE)"
However, if I compile it with gfortran -O2 Read_fct.f90 -o Read
, the output is "0.00000000" printed 8 times. The same is obtained with -O1
or higer optimization flags (-O3 to -O5). The program does not throw any errors or warnings which means that the issue can easily be overlooked. Further debugging by gfortran -O2 -g -fcheck=bounds Read_fct.f90 -o Read
reveals the source of the error:
At line 18 of file Read_fct.f90
Fortran runtime error: Index '0' of dimension 1 of array 'noheight' below lower bound of 1
I.e. it seems that the program attempts to initialize noheight(jpuff)
, before assigning a value to jpuff
. So for this specific case, I can easily resolve the issue, but that would make my code less general, possibly introducing other issues down the line. Also, having spent several hours trying to locate the problem, I would like to understand the underlying issue to reduce my chances of encountering this problem again.
Compiling with -O3 with both: "Cray Fortran : Version 16.0.1" and "ifort (IFORT) 2021.7.1 20221019" leads to the intended behavior of printing the correct floating point values.
So in short: 1) Is something wrong with my code, 2) is this the expected behavior with gfortran's optimization flags or 3) is this a bug in gfortran? The latter seems unlikely to me, but I guess that nothing is impossible.
I hope someone will be able to point me in the right direction here.
MWE:
Read_fct.f90:
program Read_fct
implicit none
integer :: ntraj, mpuff
integer :: jheight, jt, jpuff
real,allocatable :: sttheight(:,:,:)
integer, dimension(:), allocatable :: noheight
open(1, file='Input.txt')
ntraj = 8
mpuff = 1
allocate(noheight(mpuff))
noheight(1) = 1
allocate(sttheight(noheight(1), ntraj, mpuff))
read (1,*) (((sttheight(jheight,jt,jpuff),jheight=1,noheight(jpuff)),jt=1,ntraj),jpuff=1,mpuff)
write(*,*) sttheight
close(1)
end program
The file "Input.txt" has only a single line with the data I am trying to read:
0.00000000,14370.01149861,14370.01149861,14370.01149861,14370.01149861,14370.01149861,14370.01149861,14370.01149861 ! sttheight
Edit: implicit none
included and ierr removed accordingly
The program can be greatly simplified, this is the MRE I came up with
program implied_do_bug
implicit none
integer :: i,j,k
real :: arr(1,1,1)
integer :: ni(1)
ni(1) = 1
arr = 1
write(*,*) (((arr(i,j,k), i=1,ni(k)), j=1,1), k=1,1)
end program
I have submitted this into the GCC Bugzilla as a likely compiler bug that is a regression as bug 111837.
According to the replies, a workaround is to disable frontend optimizations by -fno-frontend-optimize
.