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

How to initialize all local variables to zero

Michael_Barall
Beginner
7,867 Views

I've been given a program developed for gfortran that relies on the -finit-local-zero option, which initializes all local variables to zero. (The option is documented here: https://gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html.) This is different than the Intel -init option, which apples only to SAVEd variables. I would really like to use Intel Fortran with this program. Is there some way to get the Intel compiler to initialize all local variables to zero, like gfortran does?

0 Kudos
13 Replies
mecej4
Honored Contributor III
7,867 Views

In my humble opinion, you are asking for a lot of trouble. Before I state why, please humor me and consider the example program below, which I constructed with the sole purpose of dissuading you from starting on the thorny path that you have chosen. Without compiling and running the program, just inspect the code and write down the expected output. Then run it with Gfortran with the various options that you described and compare the output to what you wrote down earlier. Thank you.

program loczero
implicit none
integer, dimension(5) :: a,b
integer :: i,dot,x,y
!
do i=1,5
   a(i)=2*i-1
   b(i)=7-3*i
end do
x=dot(a,b,5)
y=dot(b,a,5)
write(*,*)x,y
do i=1,3
   y=dot(a,b,5)
   write(*,*)i,y
end do   
end

integer function dot(a,b,n)
implicit none
integer i,n,a(n),b(n)
do i=1,n
   dot=dot+a(i)*b(i)
end do
return
end

 

0 Kudos
Michael_Barall
Beginner
7,867 Views
mecej4 -- Oh I agree, this is a very bad programming practice. The problem is that I have to use an existing Fortran program written by people with no training in software development. Their code is even worse than your example, because they don't use IMPLICIT NONE and make heavy use of local variables that are not explicitly declared. But I can't just rewrite the whole program, I have to somehow use it as is. That's why I'm asking if I can make Intel Fortran behave like gfortran and initialize local variables to zero, just so I can get the program running. And P.S. I see the bug on your line 23.
0 Kudos
mecej4
Honored Contributor III
7,867 Views

There are a couple of key questions regarding which the authors of the program, you and the compiler have to agree.

The word "initialization" means different things in C and Fortran. In C, initialization of local variables takes place immediately after a function is entered, before the execution of the executable statements in the function starts. If the function is called more than once, the initialization takes place each time the function is entered. In Fortran, initialization takes place at program start-up, and only at start-up, and initialization causes the variable to acquire the SAVE attribute.

And P.S. I see the bug on your line 23.

Normally, that is a bug -- the local variable "dot" is used without initialization. However, if you use a flag such as -finit-local-zero, that variable may get initialized in a way different from the way that you want. I followed your link, and the description there does not clearly state whether "initialization" takes place in the C way or the Fortran way. We can experiment with the code and the option, and deduce what it does, but then can we count on that behavior? With that kind of uncertainty, I would not trust a program that depends on such a non-standard, under-documented extension.

0 Kudos
Michael_Barall
Beginner
7,867 Views
mecej4 - I just ran a small test program on gfortran, and confirmed that -finit-local-zero does C-style initialization, so that local variables are initialized to zero each time the function is called. That is how I interpreted the description of -finit-local-zero, but I agree with you that the wording is unclear. I completely agree that relying on -finit-local-zero is bad programming practice. But I have this existing Fortran program (not written by me) that relies on -finit-local-zero, and I'm trying to find out if there is a way to make it run with Intel Fortran without rewriting the whole program.
0 Kudos
mecej4
Honored Contributor III
7,867 Views

How big is this program that you are thinking of reusing, and what does it do (I mean, what is the application area/problem category that it solves)?

0 Kudos
Michael_Barall
Beginner
7,867 Views
The program is roughly 6,000 lines of Fortran plus 50 megabytes of data files. The data files are a sort of scientific database, and the Fortran code is used to query the database. The data files are in non-standard undocumented formats, and so can only be queried with this particular Fortran code. The query process is a lot more complicated than a simple table lookup (take my word for it), and so I can't just write a new query program, I have to use the existing one.
0 Kudos
TimP
Honored Contributor III
7,867 Views

To my knowledge, -finit-local-zero was more often used together with -fno-automatic, in order to emulate the behavior of compilers such as CVF, and f2c (a direct predecessor of gfortran) when used without the -a option.  In that case, the zero initialization occurs only at link time. 

I was surprised at the assertion that someone would write a program so as to rely on a non-standard behavior which, even with gfortran, has to be achieved by an option which is documented as provided for compatibility with invalid legacy code.

0 Kudos
mecej4
Honored Contributor III
7,867 Views

Your program and data set size are, by today's standards, moderate. If the data files are, to some degree, normalized (see https://en.wikipedia.org/wiki/Database_normalization#Normal_forms), with a well-defined and well-known set of attributes, I'd be inclined to try running queries using some tool other than the non-standard Fortran program, such as Arthur Whitney's kx (http://kx.com/).

If the program as it is is working correctly with Gfortran, accepting that you can only use Gfortran with -finit-local-zero is the choice that requires the least effort. If you would rather have  a standard Fortran program, you can run tests to identify and isolate those subroutines that require -finit-local-zero, and bring those subroutines into standard-conformance. I believe that few data entities, be they temperatures, land areas or year of birth, have zero as a meaningful value (exception: sums, averages, etc.). If I am correct, initialization to zero is just a way of formally satisfying the requirement that variables be initialized before use, and it is quite likely that the initialization to zero is followed by re-initialization to a true and meaningful non-zero value.

Querying a file-based database with a program in Fortran (or other procedural language) has a major disadvantage: a small change to the query criteria can require major changes in the program, because the program has to describe not only the "what" but also the "how" for the new query.

0 Kudos
Simon_Geard
New Contributor I
7,867 Views

The short answer is no - the Intel compiler doesn't have that option. As others have pointed out there are good reasons for not doing it. If you have to have that capability then sticking with gfortran is probably the only option.

However 6000 lines of code is not very much and you can use the Intel compiler options to identify use of uninitialized and undeclared variables. If you update the program then it will become much more maintainable because you'll add explanatory comments every so often. Personally I'd leave the queries themselves alone and just get the code into a standard form, with that amount of data it should be fairly easy to test your changes. I'd also strongly recommend turning on the 'treat warnings as errors' switch so that you have a nice clean build at the end of the process.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
7,867 Views

You should  be aware that the observation that the use of a specific version of, and likely old version of, gfortran with -finit-local-zero permits a program to run and produce results, whereas IVF produces a program that either does not run .or. produces different results, is NO assurance that the original program is producing correct results. You may have a case of GIGO without recognizing the GO.

If you rely on this program, then take the time to correct it. In the process, you will better understand what it is doing (and not doing) and may very well correct latent bugs in the code.

(it only hurts once)

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor III
7,867 Views

Michael Barall wrote:

mecej4 - I just ran a small test program on gfortran, and confirmed that -finit-local-zero does C-style initialization, so that local variables are initialized to zero each time the function is called. That is how I interpreted the description of -finit-local-zero, but I agree with you that the wording is unclear.

I completely agree that relying on -finit-local-zero is bad programming practice. But I have this existing Fortran program (not written by me) that relies on -finit-local-zero, and I'm trying to find out if there is a way to make it run with Intel Fortran without rewriting the whole program.

Michael,

As mentioned by others, it seems unlikely you'll find what you describe.  However you don't show the actual code and one can never be sure what the code does is exactly as you say.

However you can look into /Qinit compiler option in Intel Fortran as described here: https://software.intel.com/en-us/node/579555 and also the /Qauto one explained here: https://software.intel.com/en-us/node/579534

And also look into run-time checking options as shown here: https://software.intel.com/en-us/node/579521, especially /check:uninit.

Perhaps a path forward for you will be to try the /Qinit option and see whether your code works as expected (it probably won't).  However I suggest you don't stop there: make an attempt to create a new version of your code that a) does not rely on such compiler-specific initialization options, something you can identify using various compiler and run-time checking options in both gfortran and Intel Fortran and b) that is standard-conforming, again you can verify using /stand and -std options in Intel and gfortran respectively,  To explain this a bit further, if you take the code by mecej4 in Message #2 above and compile with /check:uninit along with traceback generation (/traceback https://software.intel.com/en-us/node/579574) and run it, you will get an exception as shown below:

forrtl: severe (194): Run-Time Check Failure. The variable \'DOT$DOT\' is being
used in \'d.f90(5,7)\' without being defined
Image              PC                Routine            Line        Source

p64.exe            000000013F845DB9  Unknown               Unknown  Unknown
p64.exe            000000013F84164E  DOT                         5  d.f90
p64.exe            000000013F84124F  MAIN__                      9  p.f90
p64.exe            000000013F8D57FE  Unknown               Unknown  Unknown
p64.exe            000000013F8D5F6C  Unknown               Unknown  Unknown
p64.exe            000000013F8D60AE  Unknown               Unknown  Unknown
kernel32.dll       0000000076C459DD  Unknown               Unknown  Unknown
ntdll.dll          0000000076E7A631  Unknown               Unknown  Unknown
Press any key to continue . . .

Now if you take the same code and compile with /Qinit:zero and /Qauto (notice this is now the default in Intel Fortran) and run again, you'll get:

 -110 -110
 1 -110
 2 -110
 3 -110
Press any key to continue . . .

Good luck,

0 Kudos
Michael_Barall
Beginner
7,867 Views
OK, I have my answer -- Intel Fortran can't do this. This is not my first encounter with really bad Fortran code. It seems to be endemic in the field in which I work. If I had any intention of maintaining or modifying this program, I would convert it to standard Fortran as several of you have recommended. I've done such conversions before with other programs, using the features of the Intel compiler to find undeclared and uninitialized variables. But this particular program is one that I simply need to use, not maintain. So I guess I'll have to use it with gfortran only. And it really doesn't surprise me that the program's authors would intentionally write it so that it depends on non-standard behavior unique to gfortran, which is activated by an option that is only supposed to be used with legacy code. I've seen worse.
0 Kudos
Lorri_M_Intel
Employee
7,867 Views

Well, hang on a second.

In V16.0 we extended the scope of /Qinit:zero to also apply to local variables, and yes, it does it in the C-method of setting them, in code, at routine-entrance time.

So, while I agree with many of the other posters here (that you should run more diagnostics, and fix the problems to avoid more problems in the future!) you might be able to use a newer compiler to "get by" in the meantime.

                      --Lorri

0 Kudos
Reply