How to access private variables in fortran modules? - fortran

I know the idea of private variables is that they shouldn't be accessed, and I do want it to work this way when using the module in the rest of the program, but I need it for the purpose of checking the internal workings of the module.
Say I have the following simplified example:
module mod
implicit none
private
integer :: value
public :: set_value
contains
subroutine set_value(input)
implicit none
integer,intent(in) :: input
value=input
end subroutine
end module
And I now want to test the subroutine to see if it is actually doing what I want: I would like to write a program that uses the module, calls the routine set_value with input 8 and then checks if the internal variable value is now 8.
Can I do this? Or is it there another way to unit test initializers of private variables?

You have three approaches as I see them.
write a get function to get the value and test. You indicate in the comments that this is sub-optimal though, so..
If you have a compiler with Fortran 2003 support (e.g. any recent version of a modern Fortran compiler), declare the variable with the protected attribute instead of the private attribute. This will allow your variable to be read from any code, but not modified. This will enforce that it can only be set via your setter function but you can inspect its value directly in your unit test.
integer, protected :: value
Lastly, if all else fails, you can conditionally compile the module so that sometimes the variable is not private. For example, do this:
module mod
implicit none
private
integer :: value
public :: set_value
#ifdef UNITTESTING
public :: value
#endif
contains
...
end module
Then change the filename from .f90 to .F90 so that it will be pre-processed (at least on gfortran and ifort). When you compile it normally, value will be private, but if you instead compile with the flag -DUNITTESTING then value will be public. When you compile your test cases, you use that flag and they can now inspect the variable directly.

Related

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...)

Nested contains statement

I have a program like this
program
call one()
contains one()
some vars
contains two()
use the vars of one
define its own vars
contains three()
use the vars of both one and two
This doesn't compile because Fortran allows only the first contains statement.
I used this design to avoid passing and retyping all the variables of one() into two() and three().
How can I rewrite the program so that the variable sharing is achieved?
I cannot define all the variable before the statement call one().
The code will be to hard to manage, I need the feature :
parent subroutine cannot access internal subroutine variables.
Maybe a solution is to use pointer
call one(pointer_to_two)
then define the routine two() in its own module.
But I find this design complicate with my limited Fortran skills.
And I'm worried it will impact performance.
Should I use a common block?
I use the latest dialect of Fortran with the Intel compiler.
Below is 'compilable' example.
program nested_routines
call one()
contains
subroutine one()
integer :: var_from_one = 10
print *, 1
call b()
contains
subroutine two()
integer :: var_from_two = 20
print *, 2, var_from_one
call c()
contains
subroutine three()
print *, 3, var_from_one, var_from_two
end subroutine
end subroutine
end subroutine
end module
I recommend placing your procedures (subroutines and functions) into a module after a single "contains" and using that module from your main program. The local variables of each procedure will be hidden their callers. The way that this differs from your goals is that you have to redeclare variables. I dislike the inheritance of all variables in a subroutine contained in another because it is possible to mistakenly reuse a variable. If you have a few variables that are shared across many procedures, perhaps the appropriate design choice is to make them global. With Fortran >=90, a module variable is better method for a global variable than common blocks. If you have variables that are communicated between a limited number of procedures, it is generally better to use arguments because that makes the information flow clearer.
this might be possible if there is a separate module for each of the functions specific variables and a separate module for each function implementation
watch out for the order of the module compilation, according to the usage hierarchy necessity
also, i have no idea on the performance effect of doing this
module m1_var
implicit none
contains
end module m1_var
!========================================================================================================================
module m2_var
implicit none
contains
end module m2_var
!========================================================================================================================
module m3_var
implicit none
contains
end module m3_var
!========================================================================================================================
module m3_sub
implicit none
contains
subroutine s3()
use m2_var !to see varibles
!arguments
!local
!allocation
!implementation
end subroutine s3
end module m3_sub
!========================================================================================================================
module m2_sub
implicit none
contains
subroutine s2()
use m3_sub
use m1_var
!arguments
!local
!allocation
!implementation
call s3
end subroutine s2
end module m2_sub
!========================================================================================================================
module m1_sub
use m1_var
implicit none
contains
subroutine s1()
use m2_sub
!arguments
!local
!allocation
!implementation
! call s2
end subroutine s1
end module m1_sub
!========================================================================================================================
program nestmoduse
use m1_sub
implicit none
call s1
end program nestmoduse

Creating a simple subroutine in fortran

I am new to Fortran and I had made a program where everything did fit into one single file, which worked.
However when i tried to take out parts and put them into modules and subroutines I quickly ran into problems.
Even after removing everything and having only the bare minimum left, it still gives an error regarding the subroutine.
Currently the heavily reduced main program looks like this. It only uses the module and calls the subroutine.
program test
use mod1
call sub1(var)
end program test
and the module looks like:
Module mod1
implicit none
type A
real :: type1
end type A
contains
subroutine sub1(var)
type(A) :: var
var%type1 = 1+1
end subroutine sub1
However I seem to do something wrong here and unfortunately I can not figure out what. I get the error
||Error: Type mismatch in argument 'var' ; passed REAL(4) to TYPE(a)|
end module mod1
Can someone please explain which fundamental mistake I am making in order to prevent the most basic subroutine from working?
In your program you do not explicitly declare var. In days of yore Fortran supported implicit typing and, by default, variables whose name begin with a v will be of type real. Fortran retains this capability, though its use is now frowned upon.
I think you are thinking (as if I had a clue what you are thinking) that var in the program scope will somehow be automatically associated with, or the same as, var in the subroutine in the module. It won't be.
Do these things:
Insert implicit none on the line after use mod1 in your program.
Explicitly declare var within the program, eg type(a) :: var

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.