How to unit test functions whose interfaces are defined within submodules - unit-testing

It seems to me that one of the nice features of submodules is that you can create a helper function in a submodule at very little cost to the programmer; you don't trigger a compilation cascade, you don't clutter the namespace or your documentation, and it is immediately clear where that function can and can't be used. They're like nicer versions of private functions.
However, functions in submodules cannot be used. While this is working as intended, it also appears that this prevents the function from being unit tested. Both unit test frameworks that I'm aware of, pFUnit and fruit, require use syntax to operate.
There are some (imho somewhat inelegant) workarounds for the same problem with private functions discussed in How to access private variables in fortran modules?, but none of those solutions appear to work for functions in submodules, at least not without negating all of the benefits of putting those functions in submodules in the first place.
So are there any solutions to this problem?

The primary purpose of introducing the submodule concept was to avoid long recompilation cascades when only a minor non-interface-breaking change had been introduced to a module file. This is done by separating the interface of the procedures and putting them in the parent module and keeping the implementation in the submodule.
Submodules are themselves permitted to have submodules, which is useful for very large
programs. The number of levels of submodules that I have seen typically does not exceed two (that is, a module with submodules that themselves have submodules) but there is no limit. Each module or submodule is the root of a tree whose other nodes are its descendants and have access to it by host association. No other submodules have such access, which is helpful for developing parts of large modules independently. Furthermore, there is no mechanism for accessing anything declared in a submodule from elsewhere – it is effectively private, as you said.
Therefore, in summary, if you need anything from any submodule at any level to be accessed by any other parts of the program, it must be declared in the original parent module of the submodule. There is no other way, as far as I am aware to access anything in any submodule whose interface or declaration is not given in the original parent module.
Once you put the procedure interfaces and variable/type declarations in the parent module, you can use them anywhere in your program, even though the procedure implementations could be buried in submodules of the parent module.

I have little experience with submodules (so not sure if this is useful), but just to extend my comment above...
!! parent_mod.f90 (public things)
module parent_mod
implicit none
type myint_t
integer :: n = 100
contains
procedure :: add, show
endtype
interface
module subroutine add( x )
class(myint_t) :: x
end
module subroutine show( x )
class(myint_t) :: x
end
endinterface
end
!! parent_helper.f90 (private things to be used by parent_impl.f90
!! and possibly by unit tests)
module parent_helper
use parent_mod, only: myint_t
implicit none
contains
subroutine debug_show( x )
type(myint_t) :: x
print *, "debug: x = ", x
end
end
!! parent_impl.f90 (implementation)
submodule (parent_mod) parent_impl
implicit none
contains
module procedure add
x% n = x% n + 1
end
module procedure show
use parent_helper, only: debug_show
call debug_show( x )
end
end
!! main.f90
program main
use parent_mod, only: myint_t
implicit none
type(myint_t) :: a
call a% add()
call a% show() !! 101
call a% add()
call a% show() !! 102
block
use parent_helper
call debug_show( a ) !! 102
endblock
end
!! build
$ gfortran-10 -fcheck=all -Wall -Wextra parent_mod.f90 parent_helper.f90 parent_impl.f90 main.f90
Does this possibly help avoid recompilation of parent_mod.f90 (even when parent_helper or parent_impl are modified)? (And I noticed that the module name "parent" has no meaning here... XD)

Related

Difference between subroutine inside module "contains" and outside module

I have a large source code where subroutines in modules are defined outside the module ... end module statement (ie. not inside a contains statement). I've included a simplified module below:
module core
implicit none
type :: disc_status
sequence
real*8 :: alpha1, alpha2, alpha3
end type disc_status
end module core
subroutine tester(input)
use core
type(disc_status), intent(in) :: input
print *, input%alpha1, input%alpha2, input%alpha3
end subroutine tester
Here's an example program using the module and subroutine:
program flyingDiscSimulator
use core
implicit none
type(disc_status) :: disc
disc%alpha1 = 1.1D0
disc%alpha2 = 1.2D0
disc%alpha3 = 1.3D0
call tester(disc)
print *, 'it works'
end program flyingDiscSimulator
Normally, I end up seeing subroutines use the contains statement within a module:
module core
implicit none
type :: disc_status
sequence
real*8 :: alpha1, alpha2, alpha3
end type disc_status
contains
subroutine tester(input)
type(disc_status), intent(in) :: input
print *, input%alpha1, input%alpha2, input%alpha3
end subroutine tester
end module core
However, the program file referenced above doesn't require any changes to use either way of including a subroutine in a module (using gfortran anyways). Thus, there appears to be no difference in the usage of the module or it's subroutine between the two solutions. Are there any "under the hood" differences between the two styles?
The versions
module m
contains
subroutine s()
end subroutine s
end module m
and
module m
end module m
subroutine s()
end subroutine s
say completely different things, but in the case of the question the end results are much the same.
The first version here creates a module procedure s with host m; the second version has an external procedure s with no host.
Although the example of the question has the external procedure using the module, there is more generally a difference: the module procedure has access to all entities in the module (except when made inaccessible through an import statement or by being obscured by local names; the external procedure using the module has access only to those public entities.
However, come the main program the effects are different. The external subroutine and its name are global entities. Going to my second version, then
program main
call s
end program
is a valid program which calls the external subroutine s. This subroutine reference is valid because the implicit interface for s in the main program suffices. If the external subroutine s were such than an explicit interface were required then main program here would not be allowed. It is acceptable, but not required, to have an external s statement in the main program to reinforce to the reader that the subroutine is an external one (with implicit interface). (implicit none external would make external s necessary.)
The example of the question is such that an explicit interface is not required.
A module procedure always has an explicit interface available when accessible. However, a module procedure is not a global entity and its name is not a global identifier.
Under the hood, there are implementation differences (stemming from the above): most notably compilers will often "name mangle" module procedures.
In summary, there are differences between the two approaches of the question, but they won't be noticed by the programmer in this case.
The procedure inside the module will have an explicit interface (aka the compiler knows about the arguments' characteristics).
Whereas the procedure outside of the module will have an implicit interface (aka the compiler must make assumptions about the arguments).
Explicit interfaces help the compiler to find programming errors and are therefore favourable.
For a more indepth discussion of advantages see for example this answer.
I am not even sure if it is valid Fortran to call tester inside the program when it is defined outside of core?
The line use core should just make the module's public objects known and the tester procedure needs its own external tester line.

Are interface blocks ever required to compile Fortran?

I'm trying to teach myself Fortran, and have been messing around with linking multiple files together. Following examples, I have been writing programs in one file, functions in another, and using interface blocks in my main program to refer to the external function.
I was testing how much information was needed in the interface block and realised that I can remove it entirely.
My program:
program test
implicit none
real :: x, y, func
x = 3
y = func(x)
print *, y
end program test
And the function file:
function func(x)
implicit none
real :: x, func
func = x**3
end function func
I then compile it using gfortran -o test test.f90 func.f90 and the code works as expected. My question is, why do I not need to include an interface block in my program file? Is it simply a matter of good practice, or does defining func as a real variable serve as shorthand? I am on Windows, having installed gfortran through minGW.
As an aside/related question, if I instead use a subroutine:
subroutine func(x,y)
implicit none
real :: x,y
y = x**3
end subroutine func
And change the line y = func(x) to call func(x,y) then the code will work fine without any interface block or declaration. Why is this?
The declaration real :: func in the main program here declares func to be a function with (default) real result. This function has an interface in the main program as a result, so it is legitimate to reference that function with y = func(x).
The interface in this case is implicit. In this way, the main program knows exactly three things about func:
it is a function (with that name);
it has the external attribute;
it has real result.
The reference to the function is compatible with that knowledge. Further, how you reference the function matches precisely the properties of the function itself.
Equally, in the case of the subroutine, a call func(x,y) tells the main program exactly three things, again with the implicit interface:
it is a subroutine (with that name);
it has the external attribute;
it takes two real arguments.
Those three things again match the subroutine's definition, so things are fine.
Loosely, then, you don't need an interface block in these cases because the implicit interfaces are good enough.
There are times when an explicit interface is required and in most (nearly all) cases an explicit interface is better. As you can see in other questions and answers, there are usually better ways to provide an explicit interface than using an interface block.
Why do I not need to include an interface block in my program file?
Since Fortran 90, the recommended way to define reusable functions and subroutines is to use modules.
module func_m
contains
function func(x)
implicit none
real :: x, func
func = x**3
end function func
end module func_m
Then write use func_m in the main program, before implicit none: gfortran -c func_m.f90, gfortran -c test.f90 and gfortran -o test test.o func_m.o.
When you use modules, the compiler will check the type of the arguments of the functions. You also do not need to declare real :: func as the declarations are taken from the module.
When you compile as a "simple" object file, the compiler will simply call whatever function is named func without verification, as long as such a function is given in an object file.
The interface block is a kind of "in between". In your case, you could add one in the program file. This would force you to follow that declaration in the program. But it will not prevent linking to wrong functions at link time: there is no guarantee that the interface is right. It is mostly useful if you need to call C or FORTRAN 77 code from someone else, for which you couldn't use modules.
And change the line y = func(x) to call func(x,y) then the code will
work fine without any interface block or declaration. Why is this?
The interface issue is orthogonal to the function vs subroutine issue.
There are some cases where interface blocks are needed. For example if the called subroutine uses a pointer, allocatable or assumed shape arrays (this list is not complete, see the standard for more):
integer, pointer :: x(:,:) ! pointer attribute
integer, allocatable :: x(:,:) ! pointer attribute
integer :: a(:,:) ! assumed shape array
The pointer/allocatable have the advantage that the called subroutine can allocate it for the calling function. Assumed shape arrays automatically transfer the dimensions to the called subroutine.
If you use any of this your program will crash without explicit interface. Easiest solution is like said in the other answer: use modules to have the interface automtically correct. We use a perl script automatically extracting interfaces to have interface check without rewriting the code to modules (and avoid long compile times until all compilers reliably support Fortran 2008 submodules...)

Making multiple modules from multiple common blocks fortran 77

Currently in my program I have several common blocks spread across several subprograms and functions. I sometimes forget to change all instances of a common block as I add variables to it. I want to make these common blocks into modules so I can add and remove variables to the module in one place without worrying about updating all instances of the module across my subprograms.
Do I need to include 'use' statements in the program that initializes the variables in the module or do I include the program in the module? I normally would use common blocks for this but am trying to implement modules because I think they will help my code remain readable as complexity increases.
NOTE: Some values of the variables in the modules need to be able to change as they are passed from one program to another.
I tried to write a simplified test program to become acquainted with modules but could not get it to work. I am familiar with fortran 77 but have never used modules before. I appreciate any help or advice.
I am using gfortran 4.6.1
Main.f
program main
use Words
use Vals
double precision x,y,z
character*5 Greet
integer i
Greet = 'Hello'
x = 4.1
y = 5.2
z = 10.0
i = 3
call foo ()
end program main
subroutine foo ()
use Words
use Vals
print *, Greet
z = x + y
print *, z
print *, i
end subroutine
module Words
character*5 Greet
save
end module
module Vals
double precision x,y
integer int
save
end module
You only need one instance of a module. You make it known to any main program or procedure (subroutine or function) that uses it with a use statement. If you have a subroutine that sets values then, like any other, it has to have a use statement. If are are setting initial values you can do so in the declaration. If the module is used by the main program then it will always be in scope and the values of the variables will persist throughout the run of the program. If the module is only used by procedure, in principle the module will go out of scope when none of those procedures are in the call chain and the compiler is allowed to forget the values of the module variables. (It is doubtful that any Fortran compiler actually does this.) This can be prevented by declaring each variable with SAVE. SAVE is implicit if you declare the variable with an initial value.
Normally you have to compile the modules first before they are used so that the compiler "knows" about them when it encounters the use statement. This is done either by putting them first in the file or compiling their files first. Here is your example reordered:
module Words
character*5 Greet
save
end module
module Vals
double precision x,y
integer i
save
end module
module my_subs
contains
subroutine foo ()
use Words
use Vals
double precision :: z
print *, Greet
z = x + y
print *, z
print *, i
end subroutine
end module my_subs
program main
use Words
use Vals
use my_subs
Greet = 'Hello'
x = 4.1
y = 5.2
i = 3
call foo ()
end program main
There are a couple of reasons why your code will not compile:
You have your modules positioned after your main program, which means they will not have been compiled by the time you use them there. Either put these in separate files and compile them before the main program, or put them before the main program.
You re-declare variables from your module in the main program, which the compiler will interpret as a name conflict. All module variables with the public attribute (which is the default) will become available in the scope where you use the module; this is called "use association". In other words, use vals is enough to make x, y and int available.
Additionally, modules are more like singleton objects rather than just data containers. They can also contain procedures, listed after a contains statement, which aids grouping variables and related procedures together. An example would be grouping your two modules into one, along with subroutine foo:
module vals
implicit none
double precision :: x = 4.1, y = 5.2
integer :: i = 3
character(5) :: greet = 'Hello'
contains
subroutine foo()
double precision :: z ! New local variable
print *, Greet
z = x + y
print *, z
print *, i
end subroutine
end module
Above, I have used the "new" :: double colon operator, which allows declaring and initialising multiple variables at once. Since module variables are already save'd implicitly, this is just fine.
Alternatively, if these modules are intended to be separate, you can also have contains sections in your main program (or any subprogram) and place the subroutine there. The advantage is that procedures declared in such a way always have explicit interfaces, which greatly benefits error diagnosis by the compiler and is even required in certain newer cases. This is one of the main improvements of F90, since F77 only dealt with external subprograms and implicit interfaces.
The simplest way to do common blocks is to have one include file per common block and make all your declarations within the include file. That way, the common block is only ever declared in one place. The problem of having to convert the code to use modules then just magically disappears.
Also, if you are starting new code, prefixing the name of the common block variables with the same name as the named common block will make coding a lot easier. It is a pain initially and the prima donnas who have been coding for years will refuse to conform. The people who maintain the code will just find it so easy: no greps or groks. Just by looking at the name, you know which common block it comes from.
Keeping the same convention with modules also helps. If all routine names and variable names begin with the module name, then just by looking at the name, you know which module it comes from.

Pass kind parameter to subprogram

Is it possible in modern versions of Fortran to pass a kind parameter to a subprogram and to use this to 'cast' variables to this kind? As an example, in the following code I am trying to convert an default integer to an 16-bit integer before printing it.
program mwe
! Could use iso_fortran_env definition of int16, but I am stuck with
! old versions of ifort and gfortran.
! use, intrinsic :: iso_fortran_env, only : int16
implicit none
! 16-bit (short) integer kind.
integer, parameter :: int16 = selected_int_kind(15)
call convert_print(123, int16)
contains
subroutine convert_print(i, ikind)
implicit none
integer, intent(in) :: i
integer, intent(in) :: ikind
print*, int(i, ikind)
end subroutine convert_print
end program mwe
With this example code the Intel Fortran compiler complains that
mwe.f(24): error #6238: An integer constant expression is required in this context. [IKIND]
...
mwe.f(24): error #6683: A kind type parameter must be a compile-time constant [IKIND]
and gfortran complains
'kind' argument of 'int' intrinsic at (1) must be a constant
Using print*, int(i, int16) in place of print*, int(i, ikind) would of course work fine in this case. However, if convert_print were defined in a a module which does not define int16 then this would be useless.
Is there a way of passing a kind parameter as a constant to subprograms?
I have the same problem. I find extremely inconvenient that it is not allowed to pass the kind datatype as an argument to a procedures. In my case, I am writing write a subroutine to just read a matrix from a file and get the object in the data type that I want to. I had to write four different subroutines: ReadMatrix_int8(…), ReadMatrix_int16(…), ReadMatrix_int32(…) and ReadMatrix_int64(…) which are nothing but the same code with one single line different:
integer(kind=xxxx), allocatable, intent(out) :: matrix(:,:)
It would make sense to write only one subroutine and pass xxxx as an argument. If I find any solution I will let you know. But I am afraid that there is no better solution than writing the four subroutines and then writing an interface to create a generic procedure like:
interface ReadMatrix
module procedure ReadMatrix_int8
module procedure ReadMatrix_int16
module procedure ReadMatrix_int32
module procedure ReadMatrix_int64
end interface
As far as I can work out, what I am trying to do is expressly forbidden by the Fortran 2003 standard (PDF, 4.5 MB):
5.1.2.10 PARAMETER attribute
A named constant shall not be referenced unless it has been defined previously in the same statement, defined in a prior statement, or made accessible by use or host association.
Therefore is seems that I need to define a function for each conversion I wish to do, for example:
subroutine print_byte(i)
implicit none
integer, intent(in) :: i
print*, int(i, int8)
end subroutine print_byte
subroutine print_short(i)
implicit none
integer, intent(in) :: i
print*, int(i, int16)
end subroutine print_short
subroutine print_long(i)
implicit none
integer, intent(in) :: i
print*, int(i, int32)
end subroutine print_long
Obviously all of the above will have to be overloaded to accept different kinds of the input argument. This seems like a lot of work to get around not being able to pass a constant, so if someone has a better solution I am keen to see it.
This Intel expert gives an explanation and an elegant solution. I couldn't explain it better. A full cite follows:
"One day while I was wandering the aisles of my local grocery store, a woman beckoned me over to a table and asked if I would like to "try some imported chocolate?" Neatly arrayed on the table were packages of Lindt, Toblerone, and... Ghiradelli? I asked the woman if California had seceded from the Union, as Ghiradelli, despite its Italian name, hails from San Francisco. I suppose that from the vantage point of New Hampshire, California might as well be another country, much as depicted in that famous Saul Steinberg 1976 cover for The New Yorker, "View of the World from 9th Avenue".
(I've been warned that my blogs don't have enough arbitrary links - this should hold 'em for a while.)
Similarly, in Fortran (I'll bet you were wondering when I'd get to that), something can be so near yet seem so far away. A short time ago, I was writing a new module for Intel Visual Fortran to provide declarations for the Win32 Process Status API. This would contain declarations of types and constants as well as interface blocks for the API routines, some of which take arguments of the new type. The natural inclination is to write something like this:
MODULE psapi
TYPE sometype
some component
END TYPE sometype
INTERFACE
FUNCTION newroutine (arg)
INTEGER :: newroutine
TYPE (sometype) :: arg
END FUNCTION newroutine
END INTERFACE
END MODULE psapi
If you did and compiled it, you'd get an error that type sometype is undefined in the declaration of arg. "What? It's not undeclared, I can see it right above in the same module!" Well, yes and no. Yes, it's declared in the module and could be used anywhere in the module, except.. Except in interface blocks!
The problem is that interface blocks are a "window into the external routine" - they essentially duplicate the declarations you would see in the actual external routine, assuming that routine were written in Fortran. As such, they do not "host associate" any symbols from the enclosing scoping unit (the module in this case.)
In Fortran 90 and Fortran 95, the typical solution for this was to create a separate module, say, "psapi_types", containing all of the types and constants to be used, You'd then add a USE statement inside each function, just as you would have to in the hypothetical external routine written in Fortran. (If it were written in Fortran, the Doctor would slap your wrist with a wet punchcard and tell you to make the routine a module procedure, and then you wouldn't need to worry about this nonsense.) So you would end up with something like this:
MODULE psapi
USE psapi_types ! This is for the benefit of users of module psapi
INTERFACE
FUNCTION newroutine (arg)
USE psapi_types
INTEGER :: newroutine
TYPE (sometype) :: arg
...
Those of you who use Intel Visual Fortran know that in fact there's a giant module IFWINTY for this purpose, containing all of the types and constants for the other Win32 APIs. It's messy and inelegant, but that's what you have to do. Until now...
Fortran 2003 attempts to restore some elegance to this sorry situation, but to preserve compatibility with older sources, it couldn't just declare that interface blocks participate in host association. Instead, a new statement was created, IMPORT. IMPORT is allowed to appear in interface blocks only and it tells the compiler to import names visible in the host scope.
IMPORT is placed following any USE statements but before any IMPLICIT statements in an interface body (the FUNCTION or SUBROUTINE declaration). IMPORT can have an optional import-name-list, much like USE. Without one, all entities accessible in the host become visible inside the interface body. With a list, only the named entities are visible.
With IMPORT, my PSAPI module can look like the first example with the following change:
...
FUNCTION newroutine (arg)
IMPORT
INTEGER :: newroutine
TYPE(sometype) :: arg
...
I could, if I wanted to, use:
IMPORT :: sometype
to say that I wanted only that one name imported. Nice and neat and all in one module!
"But why are you telling me this?", you might ask, "That's a Fortran 2003 feature and Intel Fortran doesn't yet do all of Fortran 2003." True enough, but we keep adding more and more F2003 features to the compiler and IMPORT made it in back in August! So if you are keeping reasonbly current, you can now IMPORT to your heart's content and do away with the mess of a separate module for your types and constants.
If you want to know what other F2003 goodies are available to you, just check the Release Notes for each update. A full list of supported F2003 features is in each issue. Collect 'em all!"

can I declare intent variable in fortran module?

can I declare intent variable in fortran module?
I want to make common module which can be called other subroutine
module fmod
real b
integer n, i
integer, dimension(6), intent(inout) :: indata1
real, dimension(7,8), intent(inout) :: indata2
end module fmod
subroutine temp_f(indata1, indata2)
use fmod
do i=1,8
print *, indata4(i)
end do
end
No, intent is for subroutine arguments, not module variables. Module variables are normally available to any entity that "use"s them. You can declare them to be "private" which will block their visibility outside of the module. Perhaps you are thinking of a module as an include file, which copies source code lines for compilation where they are copied. That is not the concept of a module ... it is an independent source code entity.
Although it is outside of the language standard, many Fortran compilers support the use of include files via "#include" starting in the first column. With some compilers use a filetype "F90" (upper-case). With others you have to use a compiler option to run the C-style pre-processor. There is a small risk that this usage will make your code less portable.