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

Subroutine constants ruined

CalifDon
Beginner
961 Views
I haveinstalled Visual Fortran andfind the environmentMUCHnicer thanwhat I was using before(1994 Fortran Powerstation 4.0). I have created a project and begun executing a simple program.

I now havea problem.The main program calls a subroutine to compute height.The subroutine is to compute4 needed constants during the first time through only. It does this correctly the first timeand computestheproper height. But during the second time through the constants have garbage in them.I have pasted the source code below.

I would appreciate any ideas.

Don

[plain]      program MAIN  ! Visual Fortran (7/21/09).
      real*8 f,e2,ht,lat,s,d,r1,r2,w,z,h
      real*8 a /6378137.d0/
      open (unit=2,file='c:usersdondesktoptemp2.out')
      f = 1.d0/298.257222101d0
      e2 = (2.d0-f)*f
      ht = 10000.d0    
      lat = 10.d0      
      s = sind(lat)
      d = 1.d0-e2*s*s       ! (lat,h) to (w,z) is easy.
      r1 = a/sqrt(d)           ! the reverse is not.
      r2 = (1.d0-e2)*r1
      w = (r1+ht)*cosd(lat) ! Geocentric w coordinate.
      z = (r2+ht)*s            ! Geocentric z coordinate.
      call height (w,z,h)      ! Estimate height
      write (2,'(1x,/"Computed height:",f15.2/)') h
      call height (w,z,h)
      write (2,'(1x,/"Computed height:",f15.2)') h      
      close (unit=2)
      end
      subroutine height (w,z,h)
      real*8 w,z,h,a,f,e2,a1,a2,a3,r,d,s,t,k
      integer init            ! Subroutine works if this,
      data init /1/          ! this,
      if (init .eq. 1) then ! this, 
         init = 0              ! this
         a = 6378137.d0
         f = 1.d0/298.257222101d0
         e2 = (2.d0-f)*f
         a1 = a*e2
         a2 = 0.5d0*e2
         a3 = 0.25d0*e2
      endif                    ! & this is commented out.
      write (2,'("Using constants:",4D15.7)//')a,a1,a2,a3 
      r = sqrt(w*w+z*z)
      d = 1.d0/r
      s = z*d
      t = s*s
      k = a1*d
      h = r-a*(1.d0-a2*t*(1.d0+k-(k-a3)*t))
      end[/plain]


0 Kudos
6 Replies
John6
Beginner
961 Views
Quoting - Donald Olson
I haveinstalled Visual Fortran andfind the environmentMUCHnicer thanwhat I was using before(1994 Fortran Powerstation 4.0). I have created a project and begun executing a simple program.

I now havea problem.The main program calls a subroutine to compute height.The subroutine is to compute4 needed constants during the first time through only. It does this correctly the first timeand computestheproper height. But during the second time through the constants have garbage in them.I have pasted the source code below.

I would appreciate any ideas.

Don

[plain]      program MAIN  ! Visual Fortran (7/21/09).
      real*8 f,e2,ht,lat,s,d,r1,r2,w,z,h
      real*8 a /6378137.d0/
      open (unit=2,file='c:usersdondesktoptemp2.out')
      f = 1.d0/298.257222101d0
      e2 = (2.d0-f)*f
      ht = 10000.d0    
      lat = 10.d0      
      s = sind(lat)
      d = 1.d0-e2*s*s       ! (lat,h) to (w,z) is easy.
      r1 = a/sqrt(d)           ! the reverse is not.
      r2 = (1.d0-e2)*r1
      w = (r1+ht)*cosd(lat) ! Geocentric w coordinate.
      z = (r2+ht)*s            ! Geocentric z coordinate.
      call height (w,z,h)      ! Estimate height
      write (2,'(1x,/"Computed height:",f15.2/)') h
      call height (w,z,h)
      write (2,'(1x,/"Computed height:",f15.2)') h      
      close (unit=2)
      end
      subroutine height (w,z,h)
      real*8 w,z,h,a,f,e2,a1,a2,a3,r,d,s,t,k
      integer init            ! Subroutine works if this,
      data init /1/          ! this,
      if (init .eq. 1) then ! this, 
         init = 0              ! this
         a = 6378137.d0
         f = 1.d0/298.257222101d0
         e2 = (2.d0-f)*f
         a1 = a*e2
         a2 = 0.5d0*e2
         a3 = 0.25d0*e2
      endif                    ! & this is commented out.
      write (2,'("Using constants:",4D15.7)//')a,a1,a2,a3 
      r = sqrt(w*w+z*z)
      d = 1.d0/r
      s = z*d
      t = s*s
      k = a1*d
      h = r-a*(1.d0-a2*t*(1.d0+k-(k-a3)*t))
      end[/plain]



Donald,
Try placing a "Save" statement in subroutine height rightafter the data statement.
0 Kudos
GVautier
New Contributor III
961 Views
Hello

All variables are now AUTOMATIC (in stack) and not STATIC so you must explicitely declare which of your variables you want io keep between calls.

At least in HEIGHT subroutine :

real*8,save :: a,f,e2,a1,a2,a3

There is also a compilation option to declare all variables as STATIC by default. See documentation. I think you must use option for Powerstation compatibility.
0 Kudos
rafadix08
Beginner
961 Views
Quoting - gvautier
Hello

All variables are now AUTOMATIC (in stack) and not STATIC so you must explicitely declare which of your variables you want io keep between calls.

At least in HEIGHT subroutine :

real*8,save :: a,f,e2,a1,a2,a3

There is also a compilation option to declare all variables as STATIC by default. See documentation. I think you must use option for Powerstation compatibility.
You have to be careful with the data statement.
In some compilers the data statement initializes only once. That appears to be the case here, since in the first call init is set to 0.
In the second call init will still be equal to zero and your constants - which are local - are not going to be initialized because they are inside the conditional if (init == 1) then ... That is why you have garbage when you print them for the second time.
0 Kudos
CalifDon
Beginner
961 Views
Quoting - gvautier
Hello

All variables are now AUTOMATIC (in stack) and not STATIC so you must explicitely declare which of your variables you want io keep between calls.

At least in HEIGHT subroutine :

real*8,save :: a,f,e2,a1,a2,a3

There is also a compilation option to declare all variables as STATIC by default. See documentation. I think you must use option for Powerstation compatibility.

0 Kudos
CalifDon
Beginner
961 Views
Thankyou, John, gvautier and rafadix08!!!!!

In Microsoft Fortran PowerStation, all variables were indeed "static" by default. In Intel Visual Fortran, all variablesare evidently"automatic" by default, soone needs tosavewhat is needed, as gvautier says.

Don

0 Kudos
Steven_L_Intel1
Employee
961 Views

Actually, in Intel Fortran scalar variables are "automatic" by default, arrays are static. Unless you enable OpenMP, use RECURSIVE, etc. If your program notices this, it is incorrect. It is certainly true that some (mainly older) Fortran compilers give you SAVE semantics by default, but the Fortran standard doesn't require that and Intel Fortran doesn't do it. The use of automatic allocation for scalars improves performance.
0 Kudos
Reply