Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper use of modules in Fortran

I work with FORTRAN a lot, but I never had formal instruction in the proper way to write source code. I currently use modules to store global variables, but I understand you could also use them to store subroutines and functions. The codes I work with have many subroutines, as they are very large and complex. Should all functions and subroutines be in modules? If so, why?

like image 626
rks171 Avatar asked Aug 14 '12 13:08

rks171


People also ask

What is module in Fortran?

A module is like a package where you can keep your functions and subroutines, in case you are writing a very big program, or your functions or subroutines can be used in more than one program. Modules provide you a way of splitting your programs between multiple files.

What is the difference between a module and a procedure?

A procedure is a unit of code enclosed either between the Suband End Sub statements or between the Function and End Function statements. A procedure should accomplish a simple well-defined task. Modules are workbook sheets that contain code. Each module can contain a declarations section followed by procedures.

Why is creating procedures in a module useful?

Procedures allow you to break your programs into discrete logical units. You can debug separate units more easily than you can debug an entire program without procedures. After you develop procedures for use in one program, you can use them in other programs, often with little or no modification.

What does use do in Fortran?

Any declared entities in a module that are intended to be used externally can be accessed by Fortran 90's 'USE' statement. The 'USE' statement can be included in any program unit, function or subroutine of a Fortran 90 code. Its syntax can be described in two forms.


2 Answers

In general the answer to your first question is Yes and I'll come to an answer to your second question in a moment. Note first that this is a general answer to a general question and the bright sparks who hang around SO Fortran questions may well come up with special circumstances in which modules are inapplicable. I retort, in advance, that this answer is aimed at a newcomer to modules. Once you are no longer a newcomer you can formulate your own answer to your questions.

Modules are most useful to the programmer as an aid to organising and structuring a program or suite of programs. They provide a mechanism for encapsulating the definitions of user-defined types and functions/subroutines which operate on those types. In Fortran 90 and 95 this encapsulation was somewhat ad-hoc in the sense that it relied on the programmer's ideas about how to decompose a program into parts. With the introduction of the object-oriented facilities in Fortran 2003 there are now even clearer 'rules' for identifying what elements belong in each module.

You could, for example, conceive of a module for types and procedures for rational arithmetic. By keeping all the code which implements your great ideas in one module you can hide the implementation from other parts of your program (which do not need to know the details) and expose only those parts you wish to expose (look at the PRIVATE and PUBLIC keywords). You can, right away, see another advantage to organising your code into modules; it's much easier to USE your rational arithmetic module in a new program than it is to cut and past the code from your mega-source file into another mega-source file. When you want to work on your rational arithmetic, you work on code in one module, not in code spread all around your files.

Modules also allow you to manage name clashes. For example, your rational arithmetic module might define an operation called add, and you might also have a multiple-precision integer arithmetic module which defines an operation called add. If you attempt to USE both these modules in a program (or another module) then compiler will warn (possibly raise an error) that the same name is defined twice within the scope that uses the modules. You can use renaming when you use associate module entities. You can also use an ONLY clause to import only those module entities that the user needs.

Note that module USE is transitive, if A uses B and B uses C you don't have to also declare that A uses C (though if you've renamed entities or specified ONLY clauses you'll have to make sure what is transitive in a particular case).

In a nutshell, modules are the principal Fortran mechanism for dealing with complexity in programs by breaking them into manageable chunks. Fortran 2008, when the feature is implemented by compilers, introduces SUBMODULEs too, which promise even better support for dealing with complexity in this way.

Modules are also useful in that the language standards require that compilers generate explicit interfaces to procedures defined in modules for type-checking against the arguments at compile time. Note that these interfaces (which you never really see) are called explicit to contrast with implicit interfaces which is what procedures which are not defined inside modules (or CONTAINed within a program unit which uses them) have. You can, of course, write explicit interfaces for such procedures, but it's almost always easier in the short and long runs to let the compiler do it for you.

As @Telgin has already noted, modules are an aid to incremental compilation too.

like image 73
High Performance Mark Avatar answered Oct 02 '22 18:10

High Performance Mark


One of the major benefits of using modules is that your compiler will automatically perform interface checking on any functions or subroutines you use from a module to ensure that your are calling the routine with the appropriate parameter types. A good article on this topic is Doctor Fortran Gets Explicit - Again!. From this article:

There are several ways to provide an explicit interface. The simplest and best way is to put the procedure in a module, or make it a CONTAINed procedure of the calling program or procedure. This has the advantage of not requiring you to write the information twice and thus increasing the chances of getting it wrong in one of the places. When you have a module procedure, or a contained procedure, its interface is automatically visible to everything else in the module or in the parent scope. Assuming the name hasn't been declared PRIVATE, the interface is also available to places where you USE a module containing a module procedure.

I would recommend putting all related routines in the same module. Modules are, to me, the equivalent of classes in other languages. Modules are a way to group related data and routines (which may operate on that data). So modules offer a way of making your code easier to navigate, if your routines are grouped logically into modules, and add type checking to your function and subroutine calls.

like image 35
Chris Avatar answered Oct 02 '22 20:10

Chris