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

change COMMON to MODULE

jmloriot
Beginner
1,033 Views

We are using an old FORTRAN program which I am trying to set up to date.

One of the main change is converting COMMONs to MODULEs.

But most of the COMMONs include STRUCTUREs which are in an INCLUDE file :

File DECLAR.f90

    structure /drap/

      integer*4 art

      integer*4 col

     end structure

 

Subroutine B

    subroutine b   

    include "declar.f90"   

    type (drap) d1,d2   

    common /ddarp/ d1   

    d1=d2

    return

    end

Program A

   program a   

    include "declar.f90"   

    type (drap) d1,d3   

    common /ddarp/ d1   

    call b

    d3=d1

    end

 

I did change it to :

   module structure_drap   

     structure /drap/

      integer*4 art

      integer*4 col

     end structure

    end module structure_drap

   

    module ddrap

     use structure_drap     

     type (drap) d1    

    end module ddrap   

    subroutine b

   

    use structure_drap

    use ddrap   

    type (drap) d2   

    d1=d2   

    return

    end

   

    program a   

    use structure_drap

    use ddrap   

    type (drap) d3   

    d3=d1   

    return

    end

 

The compiler output the following error :

  This type/structure name has been defined more than once. (DRAP)

 

Note that every module, every subroutine and the main programs are different files and I build all the subroutines a static library.

 

I tried to have 2 different STRUCTUREs DRAP1 and DRAP2, but then the compiler refuses d1=d2 and d3=d1.

 

How can I do ?

 

 

 

And other problem using INTERFACE : the compiler outputs and error when compiling a subroutine together with its INTERFACE. It is very complicated to turn around that + it would be a double check if the compiler could verify the compatibility of the subroutine and its INTERFACE.

 

 

 

 

0 Kudos
12 Replies
Arjen_Markus
Honored Contributor II
1,033 Views

I am not sure how the double definition comes about, but can you change the structure to a derived type? I do not know exactly what structures do, but they are not part of any standard that I know of. Getting rid of such non-standard constructs would have priority, I'd say.

As for interfaces: if a routine is contained in a module, then the interface to that routine is automatically known. There is no need to define it separately and indeed the compiler does not like that.

0 Kudos
GVautier
New Contributor III
1,033 Views

Hello

May I suggest the following structure :

NB : You can replace type by structure/record but I don't see the benefit

 

module typ_drap   
    type drap
        integer*4 art
        integer*4 col
    end structure
end module typ_drap

module com_drap
    use typ_drap     
     type (drap) d1    
end module com_drap   

subroutine b
    use com_drap
    type (drap) d2   
    d1=d2   
    return
end function

   

program a   
use com_drap
type (drap) d3   
d3=d1   
return
end

 

0 Kudos
andrew_4619
Honored Contributor III
1,033 Views
module structure_drap   

     structure /drap/
         integer*4 art
         integer*4 col
     end structure

    type (drap) :: d1

end module structure_drap

every where you put 'use structure drap' the type drap will be available to define local variables of this type

and the global 'shared' variable d1 will be available.

Structure is non standard btw the standard way would be 

type drap
    sequence
    integer(4) :: art
    integer(4) :: col
end type drap

Sequence is only needed if you are relaying on the elements of drap being stored in the order they are defined in the code.

0 Kudos
mecej4
Honored Contributor III
1,033 Views

jmloriot: In #1, you are mixing  up the syntax for declaring F90+ derived type variables and the non-standard STRUCTURE variables. For the latter, the keyword to use in variable declarations is RECORD, not TYPE (...). In your main program, for example, replace 

    type (drap)  d1,d3

by

    record /drap/ d1,d3

As others have already suggested, it is best to convert the nonstandard declarations, if doing so is feasible in your existing projects. If you are writing new code, on the other hand, there is no reason to use the STRUCTURE types at all.

0 Kudos
GVautier
New Contributor III
1,033 Views

app4619 wrote:

module structure_drap   

     structure /drap/
         integer*4 art
         integer*4 col
     end structure

    type (drap) :: d1

end module structure_drap

every where you put 'use structure drap' the type drap will be available to define local variables of this type

and the global 'shared' variable d1 will be available.

Structure is non standard btw the standard way would be 

type drap
    sequence
    integer(4) :: art
    integer(4) :: col
end type drap

Sequence is only needed if you are relaying on the elements of drap being stored in the order they are defined in the code.

 

I always separate définitions typ_xxx module from common variables definitions com_xxx module. I find this way more clear and I can use typ_xxx module in function/subroutine déclarations where I doesn't need the common variables:
 

function dummy(x)
use typ_xxx
type (xxx) x

end function

 

0 Kudos
andrew_4619
Honored Contributor III
1,033 Views

gvautier wrote:
I always separate définitions typ_xxx module from common variables definitions com_xxx module. I find this way more clear and I can use typ_xxx module in function/subroutine déclarations where I doesn't need the common variables:

A matter of choice really, I make great use of use xxx, only: yyy  where I want to use a limited number selection of things from a module.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,033 Views

>>A matter of choice really, I make great use of use xxx, only: yyy  where I want to use a limited number selection of things from a module.

Agreed, however, I prefer gvautier's position as my experience from converting large projects (100's to 1,000's of files) that the type declarations and data tend to change less frequently than the code (that which would be in the CONTAINS section of the module). Having both combined in the same module results in a large number of unnecessary compiles. The only:yyy will not inhibit the unnecessary compilation. An additional step over gvautiler's recommendation is to create an interfaces module to declare the interfaces used in the module containing the code (contains section). Interfaces of the code tends to change less frequently than the code. When I adopted this strategy it was on a P4 system where a build all would take on the order of 15 minutes. Prior to adopting this strategy, a one line change in some contains section resulted in 10+ minute recompile. After the adoption, ~10 second recompile. Note, this is most effective during conversion while not using multi-file IPO.

Jim Dempsey

 

0 Kudos
dboggs
New Contributor I
1,033 Views

When updating old code, you should not have to replace structures with types. At least in IVF, the old syntax works just fine. As already mentioned, when writing new code you would be advised to use the newer syntax; or if you REALLY want to modernize the old codes you should replace it anyway.

Regarding SEQUENCE, it is not a sufficient explanation to say that it is only needed if you want to rely on the storage order of the elements. The problem is that there are places where you may be relying on it without realizing it. For example, if you want to use the "structure" (derived type) as an argument in a subroutine call, without providing an explicit interface, you will need the SEQUENCE statement. Unfortunately this is not very well documented (as described in a recent post on this forum).

0 Kudos
andrew_4619
Honored Contributor III
1,033 Views

@Jim #8 > Valid points and and I fully understand where you are coming from. However in the case of an interfaces module I dislike that solution in principal because there is extra work in creating the interfaces and and additional opportunity to get it wrong. That scheme is a workaround for a deficiency the the Fortran module concept that creates massive build cascades in large complex projects. I concede that it is a workaround that my have to be used sometimes. I guess we will all have to wait for the SUBMODULE feature of F2008 to be implemented, which if my understanding is correct should  eliminate this problem if used appropriately.

Does Dr Fortran have some when ifort might have Submodules, Is it a next 12 months thing or a further horizon?

 

0 Kudos
Steven_L_Intel1
Employee
1,033 Views

Hmm, how can I put this... You should pay attention when we announce our next beta test...

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,033 Views

>>a deficiency the the Fortran module concept that creates massive build cascades in large complex projects..

Prior to the three-way partitioning it was rather difficult to NOT have circular dependencies (while not having one humongous module with everything in it).

I am not sure if SUBMODULEs will fix this (resolution of unnecessary recompilation by segregating code from data from interfaces).

Jim Dempsey

0 Kudos
GVautier
New Contributor III
1,033 Views

To solve this massive rebuild cascade, I use a method that is not clean but efficient. I put the .mod files of my libraries manually in an modules directory added to the include directory list of all projects that depends of these modules. The only point is not to forget to copy the modified modules files after a change in public symbols (declarations, variables or function and subroutines).

I have'nt found a better solution.

 

 

0 Kudos
Reply