Private, Save attributes for variables in Fortran 90 modules - module

I am trying to add access restrictions to some of the variables (using private attribute) in a module but I need to use those variables in subsequent invocations of routines within that module:
module MyMod
private
integer,allocatable :: A(:)
public :: init,calc
contains
subroutine init()
! allocating and initializing A
end subroutine init
subroutine calc()
! Using A
end subroutine
end module
Questions:
Is this true that the private variable will not be in the scope of the program which uses this module.
If the answer to 1 is yes, then I would think that I can use save attribute for this variable. Please correct me if I am wrong?
Is this the proper way to perform this task?

Yes, if you put a private statement into your module without any further specification, you set the default accessibility to private.
For the first question, the Fortran 2008 Standard (Cl. 4.5.2.2 §3) states that:
If a type definition is private, then the type name, and thus the structure constructor (4.5.10) for the type, are accessible only within the module containing the definition, and within its descendants.
So A will not be accessible from anywhere outside the module or submodule (descendant).
For the second question, yes - you can use save here. (This is not related to the accessibility attribute). In fact, starting with Fortran 2008, this is implied for module variables, see for the Fortran 2008 Standard (Cl. 5.3.16 §4) [thanks #francescalus]:
A variable, common block, or procedure pointer declared in the scoping unit of a main program, module, or submodule implicitly has the SAVE attribute, which may be confirmed by explicit specification [...]
If I understood your third question correctly, it is related to the initialization. You could realize this with a function/subroutine to which you pass an array for initialization:
module MyMod
! ...
contains
! ...
subroutine init( A_in )
implicit none
integer, intent(in) :: A_in(:)
! allocating and initializing A
allocate( A(size(A_in)) )
A = A_in
end subroutine
end module
Inside init() you create a copy of A_in which is only accessible within the module. As long as calc() is part of the module (or a submodule thereof), it has full access to A.

To add to the answer by Alexander Vogt an implication of the save attribute.
This attribute gives precisely the effect you seem to be after (from F2008 5.3.16):
The SAVE attribute specifies that a local variable of a program unit or subprogram retains its association status, allocation status, definition status, and value after execution of a RETURN or END statement unless [something not applicable here]
In your example, A is a local variable of the module (and so a program unit) MyMod.
This means that, after the call to init which, presumably, allocates A and sets values that status is retained after the subroutine returns. Those values are then available come the call to calc. Both init and calc, of course, refer to the same A through host association.
You mention Fortran 90, so there is a subtle change (again as mentioned in that other answer). Before Fortran 2008 module variables would require the save attribute explicitly giving in some circumstances for this effect to come about. There's no harm in giving the save attribute explicitly if you aren't sure how your compiler treats the code (and some would say it's good practice, anyway).

This is another way of accomplishing what you want to do while avoiding the 'save'.
module MyMod
private
public :: myType, init
type myType
private
integer, allocatable :: A(:)
end type myType
contains
subroutine init(obj, n)
type(myType), intent(inout) :: obj
integer, intent(in) :: n
allocate(obj%A(n), source=-9999999)
end subroutine init
end module MyMod
program test
use MyMod, only: myType, init
type(myType) :: m ! m is an opaque object
call init(m, 10)
end program test
In this example, m is an opaque object - I can create the object, pass it around, but not access its contents (the array A in this case). This way, I am hiding my data. As long as my object m is in scope, I can operate on the data hidden in the object through routines contained in the module myMod.
If you have access to a modern compiler that supports Fortran 2003, you can rewrite the module as
module MyMod
private
public :: myType
type myType
private
integer, allocatable :: A(:)
contains
procedure, public :: init
end type myType
contains
subroutine init(obj, n)
class(myType), intent(inout) :: obj
integer, intent(in) :: n
allocate(obj%A(n), source=-9999999)
end subroutine init
end module MyMod
program test
use MyMod, only: myType
type(myType) :: m ! m is an opaque object
call m%init(10)
end program test

Related

Passing an object from one module into a subroutine of another module

I have two module files mod1.f95 and mod2.f95. Mod1 has mathematical functions such as rk4 and interpolation methods, and I have been trying to keep it general so that I can reuse the module for other projects. Mod2 has a class structure defined within it, Obj1, and is meant to be specific to this project. The issue is that a subroutine defined in mod1 now needs an object definition passed something along the lines as
subroutine driver(x1, x2, func, this)
real(kind=8) :: x1, x2
external :: func, this ! this is the Object
! ...
end subroutine driver
The error I get from this is
Type mismatch in argument 'this' at (1); passed TYPE(Obj1) to UNKOWN
I had a feeling this would happen, since the external keyword is meant for functions and subroutines, but I would like to pass an Object to the subroutine without having to hard code my mod2 into mod1 (i.e. using use mod2)
I tired this change
subroutine driver(x1, x2, func, this)
real(kind=8) :: x1, x2
class(Object) :: this
external :: func
! ...
end subroutine driver
but got Derived type 'object' at (1) is being used before it is defined.
I also tried type(Object) :: this with the same error produced.
To reiterate, I would like to see if there is a way to initialize an Object in a "general" sense so that other modules and files I create can just be linked this mod1 without having to change the code inside. Any advice would be appreciated!

How to use types in submodules Fortran

I have a base module that defines some subroutines (sub1, sub2, sub3). Then, I want to override these subroutines in a series of child modules.
I know how to do that with separate modules and deferred types, but I decided to give it a try with submodules. Unfortunately, I don't understand the usage of them.
This is what I have so far:
BaseModule:
module BaseModule
implicit none
interface
subroutine sub1(idx)
implicit none
integer, intent(in) :: idx
end subroutine sub1
subroutine sub2(idx)
implicit none
integer, intent(in) :: idx
end subroutine sub2
subroutine sub3(idx)
implicit none
integer, intent(in) :: idx
end subroutine sub3
end interface
end module BaseModule
ChildModule1:
submodule (BaseModule) ChildModule1
implicit none
type :: Child1
contains
module procedure :: sub1
module procedure :: sub2
end type
contains
module subroutine sub1
print*, "Child 1 - execute 'sub1' - idx = ", idx
end subroutine sub1
module subroutine sub2
print*, "Child 1 - execute 'sub2' - idx = ", idx
end subroutine sub2
end submodule ChildModule1
ChildModule2:
submodule (BaseModule) ChildModule2
implicit none
type :: Child2
contains
module procedure :: sub1
module procedure :: sub2
module procedure :: sub3
end type
contains
module subroutine sub1
print*, "Child 2 - execute 'sub1' - idx = ", idx
end subroutine sub1
module subroutine sub2
print*, "Child 2 - execute 'sub2' - idx = ", idx
end subroutine sub2
module subroutine sub3
print*, "Child 2 - execute 'sub3' - idx = ", idx
end subroutine sub3
end submodule ChildModule2
test:
program test
use ChildModule1
use Childmodule2
implicit none
integer :: idx
type(Child1) :: c1
type(Child2) :: c2
do idx = 1, 10
!! Child1 outputs
call c1%sub1(idx)
call c1%sub2(idx)
!! Child2 outputs
call c1%sub1(idx)
call c2%sub2(idx)
call c1%sub3(idx)
end do
end program test
The idea I get of submodules is that I don't have to declare all the inouts again, but what if I want to use the same subroutine (e.g. sub1) within more submodules where I declare different types? Right now I get the compile error:
Error: MODULE PROCEDURE at (1) must be in a generic module interface
I will try to clear some misconceptions I think you have about the submodules mechanism in Fortran.
Then, I want to override these subroutines in a series of child modules.
You don't override procedures with submodules, you implement them.
The idea I get of submodules is that I don't have to declare all the inouts again,
If by inouts you mean procedure's declarations and signatures (interfaces), then yes, you don't need to (but could) repeat them in submodules, but no, this is not the purpose of submodules.
but what if I want to use the same subroutine (e.g. sub1) within more submodules where I declare different types?
Well, maybe I have to briefly explain what submodules are and what they are not. For more details, please refer to this good article written by #SteveLionel, or to this entry on Fortran wiki, or your compiler's reference (whatever it is), or even to your favorite book on Modern Fortran.
As I said in another question, submodules are a feature added to the language to address one specific question: separation of interface and implementation. The main motivation was the compile cascades generated when you needed to change just a implementation detail in a module.
A submodule has access to entities on the parent module by host association, but the parent module doesn't know about the existence of this submodules. When you declare the type Child1 inside submodule ChildModule1, it is only accessible inside this submodule itself, but not in the parent module BaseModule.
Furthermore, ChildModule1 is not a module, and cannot be used, like you are tying to do, in the main program or any other program unit. The only role of a submodules is to implement module procedures that are missing implementation in its parent module.
Summing up: lay out your source files and program units in a modularized, sensible fashion, and use submodules if it makes sense to have the implementations of your procedures independent of their declarations (something akin c header and source files... but take this comparison with a grain of salt).
Edit:
It occurs me that you may be thinking module and submodule in Fortran are related to classes and subclasses in other languages. They don't! Maybe this is a common misconception, I don't know.
Fortran has user-defined types. They can bind methods, constructors and destructors, they can encapsulate data, they can be extended, they can be dynamically dispatched, they can be declared abstract, they can defer and override members. This is equivalent to classes in other languages. You can (and it is good practice) separate each type and related stuff into its correspondent modules. Likewise, you can have a module for each extend type, if you want.
But, again, submodules have nothing to do with this.
In order to sum it all up I have decided to give a working example from what I was trying to do. Thanks again to #Rodrigo Rodrigues for clarifying what submodules really are. I'm not sure if this approach is the right way of doing but it works for me.
The Task
define a type with a subroutine sub which is defined in a Base Class
define several child-types where sub gets overridden according to the needs
The Base Module
module BaseClass
implicit none
type, abstract :: Base ! <-- the base class with subroutine "sub"
contains
procedure(sub_interface), nopass, deferred :: sub
end type
interface
subroutine sub_interface(i) ! <-- the interface is defined here
implicit none
integer, intent(in) :: i
end subroutine sub_interface
end interface
end module BaseClass
The Child Module
module ChildClass
implicit none
type, extends(Base) :: Child ! <-- we extend the Base Class
contains
procedure, nopass :: sub
end type
interface
module subroutine sub(i) ! <-- the interface for the submodule (unfortunately we have to declare the entire thing again)
implicit none
integer, intent(in) :: i
end subroutine sub
end interface
end module ChildClass
The Sub Module
submodule (ChildClass) ChildSub
contains
module procedure sub ! <-- we finally get to define the subroutine
print*, "The answer is :", i
end procedure
end submodule
The Program
program test
use ChildClass
implicit none
type(Child) :: c
integer :: i
do i=1, 10
call c%sub(i)
end do
end program test
We now could have multiple Child Classes which all extend the Base Class and call sub accordingly. What I personally don't like so much is that we have to declare sub twice, once in the iterface of the base class and then again in the interface of the child class in order to use a submodule. This is code repitition but maybe this could be done better.

How to handle Fortran global allocatable variables in a module across subroutines

I have the following module with an allocatable variable which is defined in the module, allocated in a subroutine, and then also used in a second subroutine called by the first subroutine. In this situation do I have to pass the variable to the second subroutine and declare INTENT(inout)? Or since it's a global variable it doesn't need to be passed as an argument?
MODULE test
IMPLICIT NONE
SAVE
REAL,ALLOCATABLE,DIMENSION(:,:,:) :: total
CONTAINS
!--- 1st subroutine
SUBROUTINE my_subr1(n,m,z)
IMPLICIT NONE
INTEGER,INTENT(in) :: n,m,z
ALLOCATE(total (n,m,z))
total=.9
CALL my_subr2(n)
END SUBROUTINE my_subr1
!-- 2nd subroutine
SUBROUTINE my_subr2(n)
IMPLICIT NONE
INTEGER,INTENT(in) :: n
total(n,:,:)=total(n-1,:,:)
END SUBROUTINE my_subr2
END MODULE test
do I have to pass the variable to the second subroutine and declare INTENT(inout)?
No, you don't. Any variable decalred in the body of the module has the save attribute by default. You must, though, ensure that the second subroutine is only called after the first was executed, or else the program will fail because total would not be initialized yet.
All functions and subroutines declared in the module will have access to total by host association.
By the way, there are some issues you should address in your code, as mentioned by #PierredeBuyl in the comments:
Variables declared in the module body are saved by default; you should remove the SAVE statement.
Procedures declared in a module inherit the IMPLICIT directive from the module scope, there is no need to redeclare it in the subroutine if you won't change it.
You are missing the declaration of the arguments in my_subr1.

Defining and invoking a constructor in Fortran

I can't figure out how I define a simple constructor for a class. What I want to do is allocate an array in mytype and later populate it in the main program.
What I have is this:
module types
implicit none
type mytype
real, allocatable :: someArray(:)
end type mytype
interface
module procedure :: init
end interface
contains
subroutine init(this)
class(mytype), intent(inout) :: this
allocate( this%someArray(5) )
end subroutine init
end module types
program test
use types
implicit none
type(mytype) :: array
call array%init
do i=1, 5
array%someArray(i) = real(i)
print *, array%someArray(i)
end do
end program test
When I compile I get the error
Error: MODULE PROCEDURE at (1) must be in a generic module interface
What does that mean? How can I define a generic module interface?
Thanks!
The language's model for a user provided constructor is a generic function with the same identifier as the type, that simply returns an object of the type. Beyond the ability to have a generic with the same name as a type, this is nothing special.
module types
implicit none
type mytype
real, allocatable :: someArray(:)
end type mytype
interface mytype
module procedure :: init
end interface
! init would typically be private.
contains
function init()
type(mytype) :: this
allocate( this%someArray(5) )
! Non-pointer function result must be defined.
this%someArray = 0
end function init
end module types
program test
use types
implicit none
type(mytype) :: x
x = mytype()
do i=1, 5
x%someArray(i) = real(i)
print *, x%someArray(i)
end do
end program test
(The example is somewhat pointless given other aspects of the language, such as parameterized types, array constructors, automatic allocation or even the out-of-the-box capability of the built-in structure constructors.)
The error message from the compiler perhaps means to reference a generic interface, as a procedure statement is only permitted in an interface block for a generic.
Specific type bound procedure references - things with the syntax object % binding - are generally used when you have a parent type that has a method with a particular signature (set of dummy arguments, bar the passed argument), and you want to override that method in extensions - i.e. invoke a different procedure that has the same signature. Constructors don't fit this - typically the information that needs to be passed to a constructor (i.e. the signature of the call) is type specific.

Fortran tips in large modules

I have a module that consists of many small subroutines and one main subroutine, which is the only one that is public. The rest of the subroutines are private and called by the main subroutine or within them. The main subroutine has to take all the necessary arguments to perform its work, but often when it delivers a task to a private subroutine, it has to pass again some of the arguments. I would like to avoid this when dealing with arrays. With scalar numbers I can simply define a module wide variable and assign it the corresponding value in the main subroutine:
module test
integer, private :: m, n
private :: foo
public :: main
contains
subroutine main(matrixA, m0, n0)
integer, intent(in) :: m0, n0
real, intent(inout) :: matrixA(m0,n0)
!assign values to module variables m & n
m = m0
n = n0
...
!no need to pass m0 & n0
call foo(matrixA)
end subroutine
subroutine foo(matrixA)
real, intent(inout) :: matrixA(m,n)
...
end subroutine
end module
I would like to also not need to pass matrixA at all. What is the best way to do this? By best, I mean giving the best performance.
I can't comment on the "best" way, but there are some things to say. And now the question has been edited to point "best" in the direction of performance I'll add something else.
The question appears to be made under the premise that arrays cannot be module variables. They can be, even allocatable/pointer (deferred-shape) ones.
In the examples that follow I'll make the assumption that the array dummy argument in main will be assumed-shape. This is just to make things simpler in the form; changing to explicit-shape is a simple extension.
First, just like we set m and n in the question, we can set a module array variable.
module test
private ! Have this as default
public main ! But we do want a way in
integer m, n
real, allocatable :: matrixA(:,:)
contains
! In this subroutine we're making an assumption that the person asking isn't
! wholly correct in not wanting to assume shape. But we can change that if
! required. It's just a more natural thing if one can.
subroutine main(matrix) ! Note, not passing m, n
real, intent(inout) :: matrix(:,:) ! It's assumed shape
m = SIZE(matrix,1)
n = SIZE(matrix,2)
matrixA = matrix ! Copy in to the module's matrixA
call foo()
! .... etc.
matrix = matrixA ! Copy back out to the dummy
end subroutine main
subroutine foo
! Here we have access to the module's matrixA
! And we do our stuff
end subroutine foo
end module test
Note the use of the assumed-shape dummy argument and the discussion above. To avoid copying in this example, one could think about whether using a pointer is a suitable thing.
With the copy, that's not going to be good performance (assuming the array is biiig). So:
module test
implicit none
private
integer m, n ! If we want these we'll have to set them somehow
real, allocatable, public :: matrixA(:,:)
public main
contains
subroutine main()
! Stuff with matrixA host-associated
end subroutine main
end module test
program hello
use test, only : matrixA, main
implicit none
matrixA = ... ! Set this: it's matrixA from the module
call main
end program hello
As we care about "performance" rather than "encapsulation" that seems like a reasonable thing. However, having encapsulation, performance and reduced-argument passing, we could consider, rather than using a module variable for matrixA, having the work subroutines internal to main.
module test
contains
subroutine main(matrixA)
real, intent(inout) :: matrixA(:,:)
call foo
contains
subroutine foo
! Here we have access to matrixA under host association
end subroutine foo
end subroutine main
end module test
In many circumstances I prefer this last, but wouldn't say it's best, or even preferred under all circumstances. Note, in particular, that if foo already has an internal subprogram we'll start to wonder about life.
I feel the first is rather extreme just to avoid passing as an argument.