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

Modules & multiple source files

andrew_line
Beginner
557 Views
Hi,

I have several modules, each of which is stored in a separate file. Each module contains a number of routines which 'use' data or routines from the other modules. I'm finding that regardless of how I include these files in my main source code, it can't compile.

Consider this simple example. In 'fileA.f90' I have this,

MODULE A
REAL:: varA
CONTAINS

SUBROUTINE MULTIPLY(result)
USE B
REAL:: result
result = varA * varB
END SUBROUTINE

END MODULE

.... and in 'fileB.f90' I have this,

MODULE B
REAL:: varB
CONTAINS

SUBROUTINE ADD(result)
USE A
REAL:: result
result = varA + varB
END SUBROUTINE

END MODULE

and in my 'main.f90' file I might have

PROGRAM MAIN

INCLUDE 'fileA.f90'
INCLUDE 'fileB.f90'
REAL:: answer

CALL ADD(answer)
CALL MULTIPLY(answer)

END PROGRAM

In order for the compiler to main.exe it first needs A.mod B.mod. Now, in order to compile module A into A.mod, the compiler must have access to B.mod. However, B.mod can't be created until A.mod exists!

How do I resolve this problem ?
0 Kudos
7 Replies
Steven_L_Intel1
Employee
557 Views
This sort of circular dependency will give dependency analyzers fits. The most appropriate solution is to put variables varA and varB in a module C which is USEd from A and B.

Also, you should not be using INCLUDE here. Use the USE statement.
0 Kudos
andrew_line
Beginner
557 Views
Thanks Steve,

I see the sense in your solution, but surely this limits the benefits of using modules in the first place.

If I were to create a large code which could logically be split up into a number of components, it would be sensible to separate them out into modules. Obviously these components will have to speak to each other at some point and hence it would make sense to create a number of interfacing routines to allow this to happen. In my model I 'contain' these routines within each module (which may be the source of the problem). However, if this model were to contain only a small number of components, surely it could contain many of these circular dependencies.

Is there no way of predefining these troublesome function calls as one would in C/C++ headers?
0 Kudos
Steven_L_Intel1
Employee
557 Views
No, I don't see that it limits the benefits. If you want the C way, then use INCLUDE and INTERFACE blocks, but that's a step back to the 1970s, in my view.

There are a number of ways to organize things so that you don't have circular dependencies. In your case, it might make more sense to put the routines in the same module rather than separate modules, if they have to call each other.
0 Kudos
andrew_line
Beginner
557 Views
Don't worry, I don't intend to move back to the 70's. I totally agree with you regarding include statements and interface blocks. I will try to find a neater way of partitioning the code into modules.

My code was originally contained in asingle file. These problems only arose when I split it into a number of separate files (the source code itself was identical). What does the compiler do differently when it uses multiple source files which would lead to this problem?

Thanks !
0 Kudos
Steven_L_Intel1
Employee
557 Views
The compiler itself doesn't care about anything except that the .mod file for any module referenced is already there when it compiles the USE. But if compiling module A depends on module B having been compiled, and module B depends on module A, there's no way to satisfy the compiler on this. It also will cause any build dependency analyzer to have fits.

There are ways to "fake out" the compiler by declaring one of the variables with the EXTERN attribute and an ALIAS that has the properly decorated external name of the module variable. I really, really don't recommend you go this route.
0 Kudos
nijhuis
Beginner
557 Views
I do not agree with the next statement:
"If I were to create a large code which could logically be split up into a number of components, it would be sensible to separate them out into modules."
I have seen before the idea to put all files into modules, but I think thatit is not sensible to use this method when you want to split up a large program.
I think it is sensible to split up a large program in functional parts. These functional parts should be programmed as routines (subroutines or functions). It is an other point where you put thse routines.
In my opinion, you could can do one of the following:
  1. Put each routine in a separate file of which the file name is directly related to the routine name (e.g. routine xxx in file xxx.90)
  2. Collect some functional relatedroutines (short one's) in one file with a name related to the function
  3. Put some functional related routines in a module after the CONTAINS-statement.

I always use a mix of the three possibilities in one program.

I don't prefer option 3, because all routines which use the module (by calling "use module-name") will be re-compiled when you modify one of the routines in the module. Option 3 is needed when you use for example module procedures. Further I use module only for declarations of variables that are used in various routines.

Guus

0 Kudos
aliho
Beginner
557 Views
In my experience, I see two ways to solve this problem :
1 - Separate A and B modules into data and functions modules
"file a_data.f90"
MODULE A_DATA
REAL:: varA
END MODULE

"file a.f90"
MODULE A
USE A_DATA
CONTAINS

SUBROUTINE MULTIPLY(result)
USE B_DATA
REAL:: result
result = varA * varB
END SUBROUTINE

and so on.

2 - If A and B modules are cross dependent, think about merge them
into one AB module
0 Kudos
Reply