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

module design

BABAK
Beginner
2,578 Views

I have two questions about "modules":

1. For explicit procedure declaration(that is declaring a subroutine in a module), is it better to put every subroutine in a separate module, or putting more subroutines in a module won't cause any problem? 

2. In the following code, subroutine Z has different functionalities in modules A and B(module A and B might be in different source files). How can I distinguish between them?

module A
...
implicit none
contains
   subroutine Z(x,y)
...
   end subroutine Z
end module A

module B     
...
implicit none
contains
   subroutine Z(x,y)
...
   end subroutine Z
end module B

!!! Main program
program check
use A
use B
....
implicit none
...
call Z(x,y)     !!!! which Z???? ERROR

 

Thanks. 

0 Kudos
18 Replies
andrew_4619
Honored Contributor III
2,578 Views

1) It is simpler for maintenance to group multiple subroutines in one module. Particularly if there is some logic to the set of routines being together and if they share some common data from the module that does not necessarily need to be shared globally.  To keep interdependencies simpler I tend to only have one module per source file.

2) When you call Z in the scope of where the call is then if you have USE ModuleA you will get Z from that. If that location has USE ModuleA and USE module B there is a conflict. For which there are some solutions.

If one of the Z routines is only used within the module itself you could make it PRIVATE so it cannot be seen outside the module.

Alternatively you colud have in the Z caller:

USE moduleA, only: a,b,c,Z

USE moduleB, only: d,e,f

That way Z from module B is not visible in that location.

And for a final method:

USE moduleA, AZ=>Z

Which locally renames the Z from module A to some new name so to can then CALL AZ(x,y)

 

0 Kudos
FortranFan
Honored Contributor III
2,578 Views

BABAK,

I second app4619's comments.  And I feel strongly about applying the ONLY attribute; I apply it always almost as a matter of rule and it helps me greatly in reading, debugging, and maintaining the code.

So based on app4619's last point about renaming to avoid a local name clash, you can write your main program as

[fortran]

   !!! Main program
   PROGRAM check
      USE A, ONLY : Z_A => Z
      USE B, ONLY : Z_B => Z
      ...
      IMPLICIT NONE
      ...
      CALL Z_A (x, y)  !.. This calls Z from A
      ...
      CALL Z_B (x, y)  !.. This calls Z from B

[/fortran]

 

0 Kudos
andrew_4619
Honored Contributor III
2,578 Views

I also have a strong affinity for using the ONLY attribute I think it makes things much clearer as to what comes from where and also I believe the compile is faster.

One Compliant with the Intel  compiler, If I have USE fred, ONLY : A,B,C and later modify the code so that C is no longer used it is my opinion that the 'warn unused variables' option should complain with a warning about the ONLY on C still be present.Not having this makes it harder to maintain code correctly. 

0 Kudos
Steven_L_Intel1
Employee
2,578 Views

app4619, that is an interesting observation about /warn:unused. I will pass it on to the developers.

0 Kudos
BABAK
Beginner
2,578 Views

Thank you all for your responses. I solved my problem using the => operator. 

But in my opinion it would be better if Fortran adopts a modular scheme similar to that available in Python. In this manner we can put some modules in a source file, make them available for other modules in other files using the "USE filename" keyword, and then accessing the modules inside this file by for example a dot: "sourcefilename.module".I think this manner we are not confronted with name conflicts and our program would more organized. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,578 Views

BABAK, it looks like you want a scoping operator. Something analogous to C++'s :: operator.

X = foo::func( fee::arg );

Not part of the language. I am afraid you are stuck with USE ... => ...

Note, foo_func is as easy to code as foo::func

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor III
2,578 Views

I don't know Python, but the idea of using a source file name inside of any code doesn't sound right to me.. ughh!!

Most modern programming languages seem to have the concept of namespaces, they have explicit syntax for defining them, and these are independent of source file names.  In Fortran, the MODULE is in effect such a namespace.  I think in hindsight, it would have been cool if Fortran had allowed module references in execution statements [by the way, note the dereferencing symbol in Fortran is %, not period(.)], something along the lines of the snippet shown below:

[fortran]

        PROGRAM foo

           USE A, ONLY : Z

           USE B, ONLY : Z

           ...

           IMPLICIT NONE

           ...

           CALL A%Z(x, y)  !.. Currently illegal: but this would imply

                           !   call Z from A

           ...

           CALL B%Z(x, y)  !.. Currently illegal: but this would imply

                           !   call Z from B                 

[/fortran]

I don't know if there are any true limitations to the above syntax from a pure computer science point-of-view and if that's why it never got included.  My hunch is it was not considered.  But I would have really liked a feature such as this.

0 Kudos
Steven_L_Intel1
Employee
2,578 Views

The way you would do this in Fortran is:

PROGRAM foo
  USE A, ONLY : A_Z => Z
  USE B, ONLY : B_Z => Z
...
  IMPLICIT NONE
...
  CALL A_Z(x,y)
...
  CALL B_Z(x,y)

 

0 Kudos
FortranFan
Honored Contributor III
2,578 Views

Steve Lionel (Intel) wrote:

The way you would do this in Fortran is:

.. USE A, ONLY : Z_A => A ..

 

Steve,

Yes, we got that - see Quotes #2 and #3.

 

Also, see original poster's comments in quote #6 who mentioned a "better way" to do the same instead of renaming.   See Quote #8 - I'm trying to say a module referencing feature would have obviated the need to do such renaming in Fortran.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,578 Views

If you want to use a pseudo scoping operator (always)

[fortran]
module A
  type AtextToHideType
    real :: X
  end type AtextToHideType
  type(AtextToHideType) :: A
end module A
-------------
module B
  type BtextToHideType
    real :: X
  end type BtextToHideType
  type(BtextToHideType) :: B
end module B
---------------------
subroutine foo
  USE A
  USE B
  real :: X
  X = A%X + B%X
end subroutine foo
[/fortran]

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor III
2,578 Views

jimdempseyatthecove wrote:

If you want to use a pseudo scoping operator (always)

[fortran]

    ...

    module A

       ...

       type(AtextToHideType) :: A

       ...

[/fortran]

Jim,

You may know this is not standard Fortran.  In Intel Fortran, the following error will get raised:

[plain]

error #6406: Conflicting attributes or multiple declaration of name.

[/plain]

gfortran 4.9 simply states:

[plain]

type(AtextToHideType) :: A

                         1

Error: Symbol 'a' at (1) cannot have a type

[/plain]

0 Kudos
Steven_L_Intel1
Employee
2,578 Views

I imagine Jim forgot that he had already used A as the module name.

0 Kudos
FortranFan
Honored Contributor III
2,578 Views

Steve Lionel (Intel) wrote:

I imagine Jim forgot that he had already used A as the module name.

Steve,

Well, I thought that was Jim's main idea in response to Quotes #6 and #8  i.e., if there is a module A, then being able to reference an entity X from this module as A%X.

Do you know why the Fortran standard (I'm guessing this goes back to Fortran 90 when, perhaps, the concept of namespaces were still in its infancy) does not allow such referencing?

Note in many modern languages that have the concept of namespaces, one can reference an entity in those namespaces both directly and via the full reference: consider a namespace foo in C#, in code one can say

[csharp]

...

using foo.bar;

...

X = ...; ' X is an entity in foo

...

foo.bar.X = ...; ' another way to access X from foo

[/csharp]

 

0 Kudos
Steven_L_Intel1
Employee
2,578 Views

Asking "why" a language feature was not proposed or accepted is often difficult to answer. I am familiar with namespaces, but it isn't "Fortran-like", and I don't recall that it was ever seriously proposed.

Modules were, in my opinion, inspired by Ada 83, which did not have namespaces.

0 Kudos
BABAK
Beginner
2,578 Views

I think having some form of Namespace in Fortran, like that I mentioned in my last post, would be a big help in better organizing our codes. Although the current form of Modules is a very powerful tool. This might be something as a suggestion. 

I have another question about modules. In term of error handling by compiler and efficiency, is it better to put every subroutine in a separate module, or putting more subroutines in a module won't cause any problem? 

0 Kudos
Steven_L_Intel1
Employee
2,578 Views

I would put all related procedures in the same module. The more modules you have, the slower compilation is.

0 Kudos
Steven_L_Intel1
Employee
2,578 Views

app4619's suggestion to have USE, ONLY variables included in unused variable checking has been implemented for the release later this year.

0 Kudos
andrew_4619
Honored Contributor III
2,578 Views

excellent new - this will greatly assist in keeping my code 'clean'.

0 Kudos
Reply