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

Equivalence

Luis_Thiago_L_
Beginner
1,123 Views

Hello eveybody !

Recently I began to work on the modernization of a meteriological code. However I am not a fortran expert and I came across some problems related to equivalences. In these attached programs, there is an include "COMM_SEASO3.f90" that is nothing more than a common block. However when I pass this common block to module, the use of equivalence makes it impossible since it mentions a redemption of the data. I am trying to make such a change with the use of INTRINSIC TRANSFER. But it just worked with the first equivalence block, however for the equivalence O3O3(1,1,1) I'm getting wrong result.

Someone can help me how to solve it ?  

Thank you very much for your attention 

All the Best ! 

 

Luis Thiago Lucci - ltlcpaolicchi@gmail.com

 

SUBROUTINE O3CLIM

    PARAMETER (NL=81, NLP1=NL+1, NLGTH=37*NL, NKK=41, NK=81, NKP=NK+1)
!
    INCLUDE "COMM_SEASO3.f90"
!
#include "sp.h"
!
    COMMON /O3DATA/                                                                               &
    & PH1(45)     , PH2(37)    , P1(48)      , P2(33)      ,                                      &
    & O3HI1(10,16), O3HI2(10,9), O3LO1(10,16), O3LO2(10,16), O3LO3(10,16), O3LO4(10,16)
!
    REAL, DIMENSION(10,16) :: O3HI1
    REAL, DIMENSION(10, 9) :: O3HI2
   
    DIMENSION PSTD(NL), TEMPN(19),                                                                &
    &         O3O3(37,NL,4),                                                                      &
    &         O35DEG(37,NL),                                                                      &
    &         XRAD1(NLGTH) , XRAD2(NLGTH), XRAD3(NLGTH), XRAD4(NLGTH),                            &
    &         DDUO3N(19,NL),                                                                      &
    &          DUO3N(19,41), RO3(10,41)  , RO3M(10,40) , RO31(10,41) , RO32(10,41),               &
    &           O3HI(10,25),                                                                      &
    &         RSTD(81)     , RBAR(NL)    , RDATA(81)   , PHALF(NL)   ,  P(81)     , PH(82)
!
    EQUIVALENCE (O3HI1(1,1), O3HI(1,1)), (O3HI2(1,1), O3HI(1,17)),                                &
    &           (PH1(1), PH(1)),(PH2(1), PH(46)),                                                 &
    &           (P1(1) , P(1) ),( P2(1),  P(49))
!
    EQUIVALENCE (XRAD1(1), XDUO3N(1,1) , O3O3(1,1,1)), (XRAD2(1), XDO3N2(1,1)),                   &
    &           (XRAD3(1), XDO3N3(1,1)), (XRAD4(1), XDO3N4(1,1))
.
.
.
.
  END SUBROUTINE O3CLIM

   COMMON_SEASO3.f90

!--------------------------------------------------------------------------------------------------   
    COMMON /SEASO3/                                                                               &
    &   XDUO3N(37,NL), XDO3N2(37,NL), XDO3N3(37,NL), XDO3N4(37,NL),                               &
    &   PRGFDL(NL)
0 Kudos
1 Solution
andrew_4619
Honored Contributor II
1,123 Views
        !DO JJ=1,37
        !    DO KEN=1,NL
        !        O3O3(JJ,KEN,IPLACE) = O35DEG(JJ,KEN)
        !    END DO
        !END DO
        if    ( iplace == 1 ) then
            XDUO3N = O35DEG
        elseif( iplace == 2 ) then
            XDO3N2 = O35DEG
        elseif( iplace == 3 ) then
            XDO3N3 = O35DEG    
        elseif( iplace == 4 ) then
            XDO3N4 = O35DEG
        endif
            !    
100         END DO
!----------------------- 
! END OF LOOP OVER CASES
!----------------------- 
!
!--------------------------------------------------------------------------------------------------
! AVERAGE CLIMATOLOGICAL VALUS OF O3 FROM 5 DEG LAT MEANS, SO THAT TIME AND SPACE INTERPOLATION 
! WILL WORK (SEE SUBR OZON2D)
!--------------------------------------------------------------------------------------------------  
   do i = 1 , 37
       do j = 1 , NL
           AVG = 0.25 * (  XDUO3N(i,j) + XDO3N2(i,j) + XDO3N3(i,j) + XDO3N4(i,j) )
           A1  = 0.5  * (  XDO3N2(i,j) - XDO3N4(i,j) )
           B1  = 0.5  * (  XDUO3N (i,j) - XDO3N3(i,j) )
           B2  = 0.25 * ( (XDUO3N (i,j) + XDO3N3(i,j) ) - ( XDO3N2(i,j) + XDO3N4(i,j) ) ) 
           XDUO3N (i,j) = AVG
           XDUO3N2(i,j) = A1
           XDUO3N3(i,j) = B1
           XDUO3N4(i,j) = B2
       enddo
   enddo
   
  ! DO I=1,NLGTH
  !     AVG = 0.25 * ( XRAD1(I) + XRAD2(I)  +  XRAD3(I) + XRAD4(I))
  !     A1  = 0.5  * ( XRAD2(I) - XRAD4(I))
  !     B1  = 0.5  * ( XRAD1(I) - XRAD3(I))
  !     B2  = 0.25 * ((XRAD1(I) + XRAD3(I)) - (XRAD2(I) + XRAD4(I)))
!
  !     XRAD1(I) = AVG
  !     XRAD2(I) = A1
  !     XRAD3(I) = B1
  !     XRAD4(I) = B2
  ! END DO

So something like the above means than xrad1,2,3,4 and 0303 declarations and equivalences cease to exits...

View solution in original post

0 Kudos
14 Replies
mecej4
Honored Contributor III
1,123 Views

The only syntax errors that you have to fix is to remove the duplicated dimensioning of arrays O3HI1 and O3HI2, once in the COMMON declaration and again as REAL, DIMENSION ... For instance, you can simple remove the line numbered 11 in the first piece of code and the next piece, which has a single line.

0 Kudos
andrew_4619
Honored Contributor II
1,123 Views

Equivalence is an obsolete language feature and if not used with extreme care is a good source of very confusing bugs. If modernising/updating the code and objective should be to remove it. There is not a simple route to doing this as you need to examine what the program is actually doing. For example if the local arrays are simply using the common as a work space you can just simply allocate the local arrays in the subroutine and they will automatically deallocate when you leave the subroutine.

0 Kudos
LRaim
New Contributor I
1,123 Views

andrew_4619 wrote:

Equivalence is an obsolete language feature and if not used with extreme care is a good source of very confusing bugs. If modernising/updating the code and objective should be to remove it. There is not a simple route to doing this as you need to examine what the program is actually doing. For example if the local arrays are simply using the common as a work space you can just simply allocate the local arrays in the subroutine and they will automatically deallocate when you leave the subroutine.

​I strongly disagree with this statement. Like UNION (in C++), EQUIVALENCE force the compiler to place variables where the programmer wants.
​A good and advanced sw architect needs this capability.
​Regards

 

 


 

 

 

0 Kudos
dboggs
New Contributor I
1,123 Views

fwiw I agree that EQUIVALENCE has its place, and can be a very simple of accomplishing certain objectives that might be awkward and unintuitive. I am sorry to see it go. Or at least to see it downplayed in the manner illustrated above.

0 Kudos
Luis_Thiago_L_
Beginner
1,123 Views

However I continue with doubts:
If I remove the common block / SEASO3 / and put it as a module.  I will have: 

MODULE SEASO3

REAL, DIMENSION (37,NL) :: XDUO3N, XDO3N2, XDO3N3, XDO3N4

REAL, DIMENSION(NL) :: PRGFDL

END MODULE SEASO3
 
Now the program will not work because it will say I'm redeclarating the Variables.
How can i solve it ?
 
Thank you very much for your attention

 

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,123 Views

In modules, any equivalence is required to be in the same module as the declaration.

!  equiv.f90 
module mod_a
    real :: A(5)
    ! ** place the equivalence in the same module
    equivalence (A(3),A3)
end module mod_a

module mod_b
    use mod_a
    ! ** the following is in error
!   equivalence (A(3),A3)
    real :: SomethingToAvoidEmptyyModule
end module mod_b
    
program equiv
    use mod_b
    implicit none
    integer :: i
    do i=1,size(A)
        A(i) = i
    end do
    print *, A3
end program equiv

Jim Dempsey

0 Kudos
andrew_4619
Honored Contributor II
1,123 Views

Your code snippets leave us guessing. What code actual creates the error, what are the error messages? My guess is that you are trying to EQUIVALENCE local variables to variables in the module. I do not believe that is legal, equivalence does not work with many more modern features. 

For example EQUIVALENCE (XRAD1(1), XDUO3N(1,1)...    XDUO3N is a "global" variable from you module. XRAD1 is a 'local' variable. What do we do with XRAD1 do we make some calculation of these values? Is the equvalance just giving it some memory to work in? Do we actually keep any modified XDUO3N that result from XRAD1 calculations? You need to understand why the equivalence is used. This is one of its problems it leads to unclear programming in many cases. If it is simply a workspace for XRAD1 allocate XRAD1 as a local variable do the calculation and copy any results to a global that takes the results.

 

0 Kudos
andrew_4619
Honored Contributor II
1,123 Views

How big is routine O3CLIM? Can you post it?

0 Kudos
Luis_Thiago_L_
Beginner
1,123 Views

Ok

That`s the beggining of everything.

Thank you very much for your attention.

0 Kudos
andrew_4619
Honored Contributor II
1,123 Views

I saw a version of the same routine at http://box.mmm.ucar.edu/mm5/mpp/wrfbrowser/html_code/phys/module_ra_gfdleta.F.html#O3CLIM 

It seems to me that all the equivalence stuff is just creating 'short cut names' to slices of larger arrays . for example some simple mods to the loop that uses rad1,2,3,4 to take array averages and differences would make them cease to exist and would be faster as you would use all array operations rather than lots of looping.

0 Kudos
andrew_4619
Honored Contributor II
1,124 Views
        !DO JJ=1,37
        !    DO KEN=1,NL
        !        O3O3(JJ,KEN,IPLACE) = O35DEG(JJ,KEN)
        !    END DO
        !END DO
        if    ( iplace == 1 ) then
            XDUO3N = O35DEG
        elseif( iplace == 2 ) then
            XDO3N2 = O35DEG
        elseif( iplace == 3 ) then
            XDO3N3 = O35DEG    
        elseif( iplace == 4 ) then
            XDO3N4 = O35DEG
        endif
            !    
100         END DO
!----------------------- 
! END OF LOOP OVER CASES
!----------------------- 
!
!--------------------------------------------------------------------------------------------------
! AVERAGE CLIMATOLOGICAL VALUS OF O3 FROM 5 DEG LAT MEANS, SO THAT TIME AND SPACE INTERPOLATION 
! WILL WORK (SEE SUBR OZON2D)
!--------------------------------------------------------------------------------------------------  
   do i = 1 , 37
       do j = 1 , NL
           AVG = 0.25 * (  XDUO3N(i,j) + XDO3N2(i,j) + XDO3N3(i,j) + XDO3N4(i,j) )
           A1  = 0.5  * (  XDO3N2(i,j) - XDO3N4(i,j) )
           B1  = 0.5  * (  XDUO3N (i,j) - XDO3N3(i,j) )
           B2  = 0.25 * ( (XDUO3N (i,j) + XDO3N3(i,j) ) - ( XDO3N2(i,j) + XDO3N4(i,j) ) ) 
           XDUO3N (i,j) = AVG
           XDUO3N2(i,j) = A1
           XDUO3N3(i,j) = B1
           XDUO3N4(i,j) = B2
       enddo
   enddo
   
  ! DO I=1,NLGTH
  !     AVG = 0.25 * ( XRAD1(I) + XRAD2(I)  +  XRAD3(I) + XRAD4(I))
  !     A1  = 0.5  * ( XRAD2(I) - XRAD4(I))
  !     B1  = 0.5  * ( XRAD1(I) - XRAD3(I))
  !     B2  = 0.25 * ((XRAD1(I) + XRAD3(I)) - (XRAD2(I) + XRAD4(I)))
!
  !     XRAD1(I) = AVG
  !     XRAD2(I) = A1
  !     XRAD3(I) = B1
  !     XRAD4(I) = B2
  ! END DO

So something like the above means than xrad1,2,3,4 and 0303 declarations and equivalences cease to exits...

0 Kudos
andrew_4619
Honored Contributor II
1,123 Views

What you may not have noticed is the local 0303 array spans over XDUO3N, XDO3N2 , XDO3N3 and XDO3N4 and the code only works if they are stored in sequential memory locations (as they are when in a common). Removing the equivalence method as I did makes this no longer a requirement. Note that in a module there is no guarantee of the storage order of the variables. This is a problem with equivalence used this way as without careful study the link between o3o3 and  XDO3N2 , XDO3N3 and XDO3N4 is not apparent. 

0 Kudos
mecej4
Honored Contributor III
1,123 Views

The files attached in #10 need other files if one wants to run them through the compiler: the include files sp.h and MPP.h,  and the source code for the module PARMETA.

Reading Andrew's comments made me speculate whether using ASSOCIATE ... END ASSOCIATE could be used instead of employing variables associated with array segments by EQUIVALENCE.

0 Kudos
garylscott1
Beginner
1,123 Views

Luigi R. wrote:

Quote:

andrew_4619 wrote:

Equivalence is an obsolete language feature and if not used with extreme care is a good source of very confusing bugs. If modernising/updating the code and objective should be to remove it. There is not a simple route to doing this as you need to examine what the program is actually doing. For example if the local arrays are simply using the common as a work space you can just simply allocate the local arrays in the subroutine and they will automatically deallocate when you leave the subroutine.


​I strongly disagree with this statement. Like UNION (in C++), EQUIVALENCE force the compiler to place variables where the programmer wants.
​A good and advanced sw architect needs this capability.
​Regards

I also strongly disagree.  I only use equivalence in a very small number of strategic ways largely aimed at improving performance or data encryption where I want to efficiently treat non-integer data as integer for manipulation.  I'm usually trying to avoid procedure call overhead or some such in that case.  Some may not like my methods but it is totally unacceptable to declare something so fundamental as obsolete.

0 Kudos
Reply