Fortran split module into multiple files - fortran

I have something like this:
Module ModA
contains
subroutine FooA()
....
end subroutine
subroutine FooB()
....
end subroutine
end mofule ModA
can I split the two subroutines each in a separate file and still both belongs to the same module.

Yes. You have two options.
The first is to simply INCLUDE the file with the source of a subroutine in the module subprogram part.
! Module.f90
MODULE ModA
CONTAINS
INCLUDE 'FooA.f90'
INCLUDE 'FooB.f90'
END MODULE ModA
! FooA.f90
SUBROUTINE FooA()
!...
END SUBROUTINE FooA
! FooB.f90
SUBROUTINE FooB()
!...
END SUBROUTINE FooB
The second option is to move each subroutine into its own submodule.
MODULE ModA
INTERFACE
MODULE SUBROUTINE FooA()
END MODULE SUBROUTINE FooA
MODULE SUBROUTINE FooB()
END MODULE SUBROUTINE FooB()
END INTERFACE
END MODULE ModA
! FooA.f90 (or whatever name you prefer)
SUBMODULE (ModA) FooA_submodule
CONTAINS
MODULE PROCEDURE FooA
!...
END PROCEDURE FooA
END SUBMODULE FooA_submodule
! FooB.f90 (or whatever name you prefer).
SUBMODULE (ModA) FooB_submodule
CONTAINS
MODULE PROCEDURE FooB
!...
END MODULE PROCEDURE FooB
END SUBMODULE FooB_submodule
But you will need to use a Fortran compiler that supports the Fortran 2008 submodule feature for this option.

Related

how to include a module in a .mli file?

Can I include libraries in an mli file?
For example, say I make the following mli file
include Base
val bluh : int -> int
I get an unbound module Base error.
But, If I change the file to a .ml file, and change the contents to
include Base
module type bluh1 = sig
val bluh : int -> int end
it compiles. So the Base library is clearly around, I just can't use it in an .mli file for some reason.
Thank you!
I get an unbound module Base error.
This is actually not the error that you are getting. The compiler is actually saying,
Unbound module type Base
Emphasis on module type.
When you define an interface in the mli file you're defining types and signatures not values and module implementations. So you can, but don't do this, include the signature of the module Base using the following syntax,
include module type of Base (* a very bad idea, but works *)
But don't do this. There is absolutely no reason to take the whole Base library (which is huge) and include all its implementation and interface into your own module. In order to use a library, you don't need to do anything in the source code, i.e., you don't need to include or open or otherwise require or import it. Libraries in OCaml, as well as in most compiled languages, are managed on the toolchain (aka compiler) level. So if you need a library you shall instruct your build system to link with it (e.g., add it to the libraries stanza in dune or to BuildDepends in oasis, etc).
As far as I can see, you have already done this. Now if you want to use a function (or a module or any other definition) from the Base module of the base library, you just need to prefix it with Base. e.g.,
let empty = Base.Map.empty (module Base.String)
If you don't want to prefix every name, you can use open Base in the beginning of your module, this will allow you to reference any definition in Base without explicitly prefixing it, e.g.,
(* the recommended way *)
open Base
let empty = Map.empty (module String)
While in general it is not recommended to open a module, some modules are designed to be opened, and try not to pollute your namespace with definitions. The Base module is an example of such a module, especially since it acts like an overhaul of the standard library.

Export macros in Fortran

I'd like to mimic C code in a simple fortran project, where I would #define some macros and use them in my code.
For instance, an animal module would be as follows:
#define timestwo(x) (2 * (x))
module animal_module
implicit none
! ...
! test
procedure :: answer
! ...
function answer(this) result(n)
class(animal), intent(in) :: this
integer :: n
n = timestwo(42)
end function answer
end module animal_module
If I use the macro in the module, as you can see, I have no errors and it works just fine.
However, using that macro in the main file doesn't work at all:
program oo
use animal_module
implicit none
print *, 'the macro ', timestwo(5)
end program
With the compiler complaining about the macro:
main.F90(21): error #6404: This name does not have a type, and must have an explicit type. [TIMESTWO]
print *, 'the macro ', timestwo(5)
What am I missing?
When using pre-processor macros, the effect is a simple text replacement in that file. The source file of the question does not create any module entity which can be exported, and replacements do not propagate up "use chains".
Fortran differs from C in that use module is not the same thing as #include "header.h": the source code for the module is not included in the main program's file for text replacement to occur.
If you really which to use this approach you should repeat the macro definition on the program's source. To simplify things, you can define this common macro in a pre-processor include file and #include it (not include):
#include "common_macros.fi"
program
...
end program
and similar in your module file.
Better would be to move away from using pre-processor macros to implement "simple functions". A real function in the module would be an exportable entity. A pure function that simple is highly likely to be inlined (with appropriate optimization flags) just as easily as a macro.
Here is some example code that works in a console application
#define twice(x) (2*x)
program Console1
implicit none
print *, twice(7)
! 14
end program Console1
which you need to compile with the /fpp option

How to compile Fortran FUNCTION/SUBROUTINE in separate files into a single MODULE

Usually, when I write a collection of Fortran functions, I put them into a MODULE like this:
!mystuff.f90
MODULE mymodule
IMPLICIT NONE
CONTAINS
SUBROUTINE mysubroutine1(a,b)
!code
END SUBROUTINE
SUBROUTINE mysubroutine2(a,b)
!code
END SUBROUTINE
!lots more functions and subroutines
END MODULE
and I successfully compile it like this gfortran -c mystuff.f90. This creates mystuff.o which I can use in my main program.
However, the number and individual sizes of functions/subroutines in my MODULE have become so huge, that I really need to split up this up into different files.
!mysubrtn1.f90
SUBROUTINE mysubroutine1(a,b)
!code
END SUBROUTINE
and
! mysubrtn2.f90
SUBROUTINE mysubroutine2(a,b)
!code
END SUBROUTINE
and so forth...
But I'd still like to keep all these functions inside a single MODULE. How can I tell the compiler to compile the functions in mysubrtn1.f90, mysubrtn2.f90, ... such that it produces a single module in a .o file?
You can simply use include to include another file of Fortran source code:
!mystuff.f90
MODULE mymodule
IMPLICIT NONE
CONTAINS
include 'mysubrtn1.f90'
include 'mysubrtn2.f90'
!lots more functions and subroutines
END MODULE
From here:
The INCLUDE statement directs the compiler to stop reading statements
from the current file and read statements in an included file or text
So you can see that the resulting module will still contain both subroutines.
An alternative that achieves the same thing is to use a pre-processor directive, if your compiler supports it:
#include "filename"
For readability, it is nice to separate a large module into more manageable chunks. Each of the smaller modules may be compiled individually, and used in another "master" module which is then used in the main program. The main benefit of this approach is that you can have a variety of very general modules, and pick only the procedures/data that are useful at the moment. For example:
module mod_1
implicit none
subroutine proc_1
! ...
end subroutine
! other procedures, etc.
end module mod_1
And so on, for each of your separate modules. Then collect them in a single module.
module collection
use mod_1, only: proc_1 ! pick & choose what to use
use mod_2
use mod_3
! ...
end module collection
program main
use collection
implicit none
! ...
end program main
When you compile the main program, you can link to each of the necessary object files, or even combine them into a single archive/library and just link to that.

How to include a module from a different file in Fortran 95?

The question is obvious I think, although I googled it, I could not find any solutions. I want to split my source code to keep it more maintainable. How can I reference a module in another file?
I think that you are looking for the use statement. You might, for example, have one source file containing the definition of a module, outline:
module abstract_types
implicit none
! declarations
contains
! procedure definitions
end module abstract_types
and then, in another source file, a program which uses the module, outline:
program hello_there
use abstract_types
implicit none
! declarations
! executable statements
end program hello_there
Note:
Any use statements precede the implicit statement.
The use statement refers to the module by name.
When it comes to compilation, make sure that you compile the module source file before the program source file; at compilation time (not at link time) the compiler will look for a module file (often called a mod file) to satisfy the reference to the module in the use statement. The mod file is a bit like a header file, but it's created by the compiler.
Later, when you link your program you'll need the object files for both module and program.

Fortran 'parameter' type not included in compiled object

I have a Fortran module that contains some variables that have the attribute parameter and some have the attribute save. The parameter ones are not included in the compiled object, which becomes a problem when trying to assemble a library. For example, consider a file testModule.f90:
module testMOD
integer, save :: thisIsSaved = 1
integer, parameter :: thisIsParametered = 2
end module testMOD
I compile this with: ifort -c testModule.f90. When I check what's inside it:
>$ nm testModule.o
0000000000000000 T testmod._
0000000000000000 D testmod_mp_thisissaved_
only the thisIsSaved variable is there. I know that I can just change thisIsParametered to save rather than parameter but, ideally, I'd like to prevent a linking user from changing this value. Is there a way to do this?
Edit: I'd like this library to be accessible to C codes, as well, not just Fortran.
That should actually be stored in the .mod file. All of the data types and function prototypes are stored there which is why you need to include it when you send someone a .lib file. Try linking in the module after using it in something else and it should work just fine.
Essentially the .mod file serves the same purpose as the .h file in c, so of course you are going to have to include it with your library.
[update:]
If you are attempting to use this in C, then as you said, there is no means for you to easily maintain the named constant. As an alternative, you can use the protected attribute on the entity. At least with Fortran, anything outside of the module is restricted from writing to the variable. I don't know if the C compiler and the linker will respect this behavior, but I think this is probably your best shot.
module testMOD
INTEGER, PROTECTED, BIND(C) :: globalvar = 1
end module testMOD
Unfortunately I don't really do much with interoperability with C, so I can't really guarantee that C will respect the protected attribute and not allow the variable to be changed.
As others have noted, a parameter is a named constant and implementations may not set aside storage for that constant in the object code (particularly for scalars).
Your library should provide a header file for your C clients. You can define the value of the Fortran parameter in that header file, either by #define or const.
This requires maintenance of the value of the parameter in two places, but you already have that maintenance burden with other aspects of the library's interface.