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

Would EQUIVALENCE help to save local variables ?

Loius__Jim
Beginner
413 Views
Hi All,
 
I have a question on EQUIVALENCE statement in Fortran. The issue is that in a legacy Fortran code, it has lots of local variables that are not saved into a file (let's call it restart file). At certain time, the code will dump all common block data into this restart file. Later the code will read the restart file and try to continue the calculation from there. However, due to some bad coding practice it had in decades, some local variables did not get saved into the restart file, as a result, the code cannot give identical result if restarted.
In order to resolve this issue, I tried to create alias local variables and saved then into common block. The reason I did not directly save those local variables into common block is trying not to change the calculation part of the code as it raises QA issue.
However, after I saved all the alias local variable into the restart file and read those variables, the code performance did not get any better. So I doubt whether the EQUIVALENCE pass the alias local variale values to the local variable or not.
 
The process to save restart file:
local --> local_alias--> saved local_alias into restart file
 
read the restart file:
saved local_alias in restart file --> read local_alias--> EQUIVALENCE to local --> code calculation
 
Thanks a lot in advance for any help!
 
 
Sample code below:
 
 
C*******************************************************************************
C  Original Code has local variables that could cause the calculation not
C  repeatable as "local" is not saved in common block. When the calculation is 
C  restarted, code reads data from a previous saved file that contained 
C  variables and their values in common blocks. Local variables are not saved
C  in this file, as a result, their values could be different than what they 
C  were before.
      subroutine calculation
      implicit none
C example subroutine to show how to save local variables in fortran to a 
C file. So that the code can later read the file to ensure the calculation
C is repeatable
 
 
      integer*8 i,j,k
      real*8  a,b,c
      real*8 local
      common /global/ a,b,c
       
      a=b*c*local
       
      end subroutine
   
********************************************************************************  
New code -->  
********************************************************************************       
      subroutine calculation
      implicit none
C In order to ensure all variables used in the calculation to be saved so that 
C any restart will produce identical results, alias local variables are created
C and EQUIVALENCE to local variables. We are trying change the code as less as
C possible due to legacy code QA issue.
 
 
      integer*8 i,j,k
      real*8  a,b,c
      real*8 local
      real*8 local_calculation  ! <--- create a different variable equuivalent to local
      equivalence (local_calculation,local)
      common /globalvar/ a,b,c
      common /localvar/ local_calculation  ! <--- save the local variable into common block, so that it can be saved
       
      a=b*c*local
       
      end subroutine
********************************************************************************  
0 Kudos
8 Replies
Steve_Lionel
Honored Contributor III
415 Views

Once you put a variable into a common, it is no longer a local variable. I don't see why you play tricks with EQUIVALENCE and don't just put "local" into the COMMON to be saved, since that's what you want. However, if you use this same common name in more than one routine, you'll be saving only one of the variables, which I suspect is the problem you're running into. Essentially, you need to list each of the "local" variables separately in a common that the program then saves and restores. There are no shortcuts to this.

0 Kudos
andrew_4619
Honored Contributor II
415 Views

Is your real problem that these local variables are not properly initialised on a restart? How are they initialised on a first run? Are initial values of zero assumed as was a bad assumption of some older code based on the fact that on some older compilers this just happened to be the case? As Steve says you need to fundamentally look at the code. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
415 Views

>>At certain time, the code will dump all common block data into this restart file. Later the code will read the restart file and try to continue the calculation from there.

Your save and restore points are not performed at arbitrary states of the application (NOT while you are n-levels down into a call tree in the middle of a calculation), rather they are likely performed in you main loop (e.g. time integration loop) after the time step calculations. When this is the case, then the temporary variables of the subroutines in the call tree need not be saved (but some of the loop control and temporaries of the main loop may need to be saved/restored).

Andrew's advice extends the other direction too.

program xxx
  ...
  if(restarting) then
    call loadRestartData()
  else
     ... ! code to load and initialize simulation
  endif
  ...
  do while(.not. Done)
     ...
    if(atSavePointInterval) call saveState()
  end do
  ...
end program

What I mean is that the code in the LoadRestartData() may not initialize significant data that the ... ! code to load... does, and that data is require by the do while(.not. Done) loop.

As Steve says you need to fundamentally look at the code.

Jim Dempsey

0 Kudos
Loius__Jim
Beginner
415 Views

Thanks a lot, Steve. Yes, it would be better to directly save the locals into a common block. The potential issue of doing is as you said, there are thousands of subroutines in this legacy code, and many local variables have the same name in different subroutines.  If doing so, there is one subroutine to write and read all those local variables (now defined in common blocks) into a restart file, it could have issue of having identical local variable names present in different common blocks (defined for local variables). There is the problem I was trying to work around using EQUIVALENCE statement, which does not work as I thought  from the testing results.

Would there be any work around to this dilemma? Thanks a lot!

 

Jim

 

 

 

Steve Lionel (Ret.) wrote:

Once you put a variable into a common, it is no longer a local variable. I don't see why you play tricks with EQUIVALENCE and don't just put "local" into the COMMON to be saved, since that's what you want. However, if you use this same common name in more than one routine, you'll be saving only one of the variables, which I suspect is the problem you're running into. Essentially, you need to list each of the "local" variables separately in a common that the program then saves and restores. There are no shortcuts to this.

0 Kudos
mecej4
Honored Contributor III
415 Views

Why do you have to write all local variables into a restart file?

Let us call the part of the main program that has been executed before the restart file is written as 'A' and the rest of the program as 'B'.

Then, none of the local variables need to saved in those subroutines that are called only after restart, i.e., subroutines called from part B and not from part A. Similarly, there is no need to save and restore the local variables of those subroutines of part A that have not yet been called when the restart/restore point is reached.

In general, local variables need not be saved for those subroutines that are known to be called just once during a run of the program.

These considerations can help you to reduce the number of variables that need to be saved and restored.

0 Kudos
Loius__Jim
Beginner
415 Views

Yes, only if the local variables in the legacy code were properly used as "local". However, in the fact, there are many local variables in the legacy code should never be used as local, as shown in my sample code. The effort is trying to correct the mistake in the legacy code while minimize code changes due to QA requirements.

Thanks for your insights!

 

Jim

mecej4 wrote:

Why do you have to write all local variables into a restart file?

Let us call the part of the main program that has been executed before the restart file is written as 'A' and the rest of the program as 'B'.

Then, none of the local variables need to saved in those subroutines that are called only after restart, i.e., subroutines called from part B and not from part A. Similarly, there is no need to save and restore the local variables of those subroutines of part A that have not yet been called when the restart/restore point is reached.

In general, local variables need not be saved for those subroutines that are known to be called just once during a run of the program.

These considerations can help you to reduce the number of variables that need to be saved and restored.

0 Kudos
Loius__Jim
Beginner
415 Views

Yes, some local variables are not initialized during restart. The first run, all local variables should default to be 0 or false. As code calculation proceed, some local variables get calculated with different values, and these values must be saved in restart file in order to repeat the calculation as if it is run from time 0. 

 

andrew_4619 wrote:

Is your real problem that these local variables are not properly initialised on a restart? How are they initialised on a first run? Are initial values of zero assumed as was a bad assumption of some older code based on the fact that on some older compilers this just happened to be the case? As Steve says you need to fundamentally look at the code. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
415 Views

>>The first run, all local variables should default to be 0 or false

That is an incorrect assumption. Observing it once at some time does not make it certain that 0 initialization is require by the language.

Jim Dempsey

0 Kudos
Reply