Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Implicit declaration of 'USE MODULE_NAME' statement 2

Status
Not open for further replies.

billgray1234

Programmer
Mar 14, 2011
39
Hi all

I'm new to this forum. I have a problem in Fortran 90. It is described below.

The line 'IMPLICIT NONE' makes it impossible to implicitly declare VARIABLES. I'd like to know if there is a similar line (or way of declaring) that makes it impossible to implicitly declare STATEMENTS -- in particular, the statement 'USE MODULE_NAME' (where MODULE_NAME is the name of a module being USEd). The reason is that, to my understanding, it is possible to 'implicitly' have the line 'USE MODULE_NAME'. An example of how this is done is given below.

Consider 3 files (in Fortran 90):
1. module_set_precision.f90
2. module_peter.f90
3. main_program.f90

They are described briefly below.


1. set the level of precision of numerical calculations.

module_set_precision.f90
------------------------
MODULE set_precision
INTEGER, PARAMETER :: P_REAL = SELECTED_REAL_KIND(P=15)
END MODULE set_precision


2. a module that contains a subroutine. the important line in the subroutine is 'USE set_precision'.

module_peter.f90
----------------
MODULE peter
USE set_precision
IMPLICIT NONE
CONTAINS
SUBROUTINE bill(input,output)
...
REAL(KIND=P_REAL),INTENT(IN) :: input
REAL(KIND=P_REAL),INTENT(OUT) :: output
...
END SUBROUTINE bill
END MODULE peter


3. the main program, that uses both MODULE set_precision and MODULE peter. if written 'correctly', this main program looks something like this:

main_program.f90
----------------
IMPLICIT NONE
USE set_precision
USE peter
...
REAL(KIND=P_REAL) :: steve
REAL(KIND=P_REAL) :: daniel
...
CALL bill(steve, daniel)
...
END


4. the problem
In the above file main_program.f90, included explicitly is the line

IMPLICIT NONE

which means that all VARIABLES must be declared explicitly. but, in the same main program, it is possible to 'accidentally' forget to include the line

USE set_precision

(in order to USE MODULE set_precision), and yet this line is still 'implicitly' declared (in the main program) because of the line

USE peter

(which USEs MODULE peter), because MODULE peter 'explicitly' has the line 'USE set_precision'. the resulting 'incorrect' main program would look like this:


main_program.f90
----------------
IMPLICIT NONE
USE peter
...
REAL(KIND=P_REAL) :: steve
REAL(KIND=P_REAL) :: daniel
...
CALL bill(steve, daniel)
...
END



this is not good programming.

i've read about the words PRIVATE, PUBLIC. but i'm not sure if they are the solution to this problem.

i've also read that the position of the line 'USE set_precision' (in MODULE peter) could be causing this problem. currently, it is positioned BELOW the line 'MODULE peter' (thereby giving the whole content of MODULE peter access to it). maybe, it should instead be positioned BELOW the line 'SUBROUTINE bill (input,output)', so that only 'SUBROUTINE bill' has access to it. the resulting module/subroutine would look like this:

module_peter.f90
----------------
MODULE peter
IMPLICIT NONE
CONTAINS
SUBROUTINE bill(input,output)
USE set_precision
...
REAL(KIND=P_REAL),INTENT(IN) :: input
REAL(KIND=P_REAL),INTENT(OUT) :: output
...
END SUBROUTINE bill
END MODULE peter


but again, i'm not sure if that is the solution to this problem.

can anyone offer any suggestions to this problem?
any help would be appreciated.


cheers
bill g
billgray1234@hotmail.com
 
I don't know about PRIVATE and PUBLIC, but "USE set_precision" is not implicitly declared by saying "USE peter" even though "peter" uses "set_precision"

I would say that the stuff of module "set_precision" only exists within "peter" and not everywhere where you use "peter"

Doesn't it give an error if you leave out the "USE set_precision" in the main program?
 

I disagree GerritGroot

This is typically managed by the keywords PRIVATE and PUBLIC. If these keywords are not used in the module "peter", then all public variables of the module "set_precision" (which is used by peter) become automatically public symbols of the module "peter". Then a simple "use peter" is enough to load in the same time "set_precision".

The feature is frequently used to group together several USE statements inside a unique module. Then one has just to use that module to load everything.

If you don't want that feature, then include a global PRIVATE statement in the module "peter" and precise explicitly what variables are PUBLIC (including possibly variables belonging to set_precision").

Notice also that IMPLICIT NONE must be put AFTER all USE statements.

François Jacq
 
That's new to me, thanks for clearing that up!

Well, it's going to be hard to keep up with it all if you have a bunch of nested modules, I'd rather use PRIVATE everywhere then, so I know what I'm doing, if not you have to look back to the whole chain of modules to know what's included and what's not...

PRIVATE is F95 right? No wonder I didn't know. :)

So it all comes down to the default that's PUBLIC, while I thought the default was PRIVATE (would make more sense in my opinion).

...The more I learn, the more I know I don't know... ..it's frustrating.
 
Declaring symbols PRIVATE by default is indeed what I advise. But the opposite strategy is correct as well.

In fact, by experience, the main thing to do consists in using systematically the keyword ONLY in each USE statement, just to list what one uses from each module. This is very convenient for the reader. In addition, group all USE statements at the top of modules and not in the procedures contained by the module (again much easier for the reader)

Now, the notion of PUBLIC by default is very similar to the #include statements in C and C++, an include file being able to include other include files. But the USE statement has several advantages compared to #include :
- no need to insure a unique USE (a same module may be used several times in fact, directly or through the use of a module using it, and this without conflict). In C it is needed to use the #ifdef technique to warrant that an include file is loaded only once.
- modules cannot be recursive. If A use B, B cannot use A. This could seem to be a strong restriction, but in fact, this warrants a clear programming organization. Look into C, C++ or JAVA which have not this restriction : the risk of getting a very complex software is huge !

PRIVATE and PUBLIC statements are already defined in the F90 standard. The keyword PROTECTED is added in F2003.



François Jacq
 
Yes, I always use ONLY, though I'm not sure whether it influences something more than only the debug moment let's say. I wonder whether it influences the memory use or so.

Apart from that, having "ONLY:" and then an incredibly long list, nearly comes down to what was done in F77 with unbelievably long headers in subroutines, passing a hell of a lot of variables.
 
Coming back to the first example, it's still unclear to me.

If you don't want to inherit anything from the module "set_precision" anywhere where you say, "USE Peter", how should this be done?

This is still unclear to me because with:
Code:
MODULE set_precision
INTEGER, PARAMETER, [b]PRIVATE[/b] :: P_REAL = SELECTED_REAL_KIND(P=15)
END MODULE set_precision
As far as I understood, you make P_REAL only available within the module set_precison, so even if you say "USE set_precision" somewhere else P_REAL would still be unavailable, RIGHT???

Actually what the original question was about, was to have something in the module "Peter" like:
Code:
MODULE peter
USE, [b]PRIVATE[/b] set_precision
IMPLICIT NONE
CONTAINS
   SUBROUTINE bill(input,output)
   ...
   REAL(KIND=P_REAL),INTENT(IN) :: input
   REAL(KIND=P_REAL),INTENT(OUT) :: output
   ...
   END SUBROUTINE bill
END MODULE peter

In order not to inherit the stuff from "set_precisoon" when calling "USE peter"

But you can't say that, can you? I didn't check, but I suppose this will give an error, didn't see any example like that.
 
The work must be done in the module PETER, not in the module SET_PRECISION:

Code:
module peter
  use set_precision,only : p_real
  implicit none
  private ! all is private by default, including p_real
  public :: bill ! on declare publc symbols here : variables, subroutines ...
  contains
  ...
end module

As summary, each module is responsible to declare the symbols it wants to publish

François Jacq
 
Apart from that, having "ONLY:" and then an incredibly long list, nearly comes down to what was done in F77 with unbelievably long headers in subroutines, passing a hell of a lot of variables.

Again I disagree !

The lists you have to precise after the keywords ONLY and PUBLIC ARE the documentation of your module. They are usually optional only, except when two used modules declare the same symbol (rare situation). Thanks to them, there is no need to write a huge header of comments at the top of each module. I am never confident in theses comment headers which always contain mistakes or oversights : they are not checked by the compiler !

If a module proposes a lot of services and you want to use many of them in another module, then I suggest to apply nomenclature rules.

For instance I have developed a material data base associated to a library of tools. This library is summarized by a module mdb.f90. In that module, all public symbols starts by the three letters [bold]mdb[/bold].

When a module uses mdb, there is no need to list all the used symbols if the reader knows that all symbols starting by "mdb" are coming from that module. To clarify that, I replace the ONLY list by a simple comment :

Code:
module test
  use mdb ! all symbols starting by mdb
  ...
end module



François Jacq
 
Yes, I always use ONLY, though I'm not sure whether it influences something more than only the debug moment let's say. I wonder whether it influences the memory use or so.

No : these keywords are used by the compiler only and have no influence (as far as I know) neither on the memory used nor on the cpu time consumption of the executable program when running.

From my point of few, they represent the reliable part of the code documentation because verified at each compilation.

Ditto for the keyword INTENT, even if this one may have consequences in the same time on performances and on the behavior of the code. For instance, an INTENT(out) may involve an automatic initialization phase.


François Jacq
 
Ok, thanks, so if I understood you well, the only way to prevent inheritance of the stuff from "set_precison" when calling "USE peter" is making everything in "peter" PRIVATE by default, since the statement, "USE, PRIVATE MyModule" doesn't exist. (then you will be forced to declare all the rest within "peter" public explicitly as you do, which becomes quite cumbersome if the module "peter" happens to be large).
 
to declare all the rest within "peter" public explicitly as you do, which becomes quite cumbersome if the module "peter" happens to be large)

Again I disagree ! This is not "quite cumbersome" : this is just good programming practice.

If the module "peter" happens to be large,then you have to cut it in smaller parts, these parts (modules) having to use adequately PRIVATE and PUBLIC keywords. The module "peter" may reduce to a collection of USE statements, with or without ONLY clauses (usually without because one wants to make public all public symbols of these modules). The reader, in that case will look into these submodules to get more pieces of information.

François Jacq
 
Alternative way if one does not want to use a global PRIVATE statement

Code:
module peter
  use set_precision,only : p_real
  implicit none
  private :: p_real
  ... ! possible other public of private declarations
  contains
  ...
end module

François Jacq
 
Thanks for those replies! They have been very informative and helpful.

Mentioned in one of the above replies was the idea of 'using' several modules from one particular module. I'd like to make two comments, to further explain and support that idea. Sorry if it's a bit long.

Comment 1: Portability of related modules/subroutines
-----------------------------------------------------
Suppose you have several subroutines, each of which are related by a common 'theme'. Let this 'theme' be Matrix Manipulation (MM). Let each subroutine be stored in it's own separate module (more about this below). For example, a subroutine that adds one matrix to another might be written as


MODULE MM_add_matrix_to_another_matrix
CONTAINS
SUBROUTINE add_matrix_to_another_matrix
...
END SUBROUTINE add_matrix_to_another_matrix
END MODULE MM_add_matrix_to_another_matrix


Excuse the lack of important 'detail' in the above code (such as inclusion of the line IMPLICIT NONE, and possible dummy arguments).
Anyway, say there are 6 such modules/subroutines in total, such that they are called


MODULE MM_add_matrix_to_another_matrix
MODULE MM_add_vector_to_another_vector
MODULE MM_multiply_matrix_by_another_matrix
MODULE MM_multiply_matrix_by_a_vector
MODULE MM_initialise_matrix
MODULE MM_initialise_vector

Let there be one 'main' program, which needs access to each of the above modules. One 'tedious' way to achieve this is to have the code written as


PROGRAM Matrix_calculations
USE MM_add_matrix_to_another_matrix
USE MM_add_vector_to_another_vector
USE MM_multiply_matrix_by_another_matrix
USE MM_multiply_matrix_by_a_vector
USE MM_initialise_matrix
USE MM_initialise_vector
...
END


Alternatively, doing what was described in one of the above replies, you could instead 'use' all of the modules from one particular module. To do this, you could have the code written as


PROGRAM Matrix_calculations
USE MM
...
END


where the module MM is written such that

MODULE MM
USE MM_add_matrix_to_another_matrix
USE MM_add_vector_to_another_vector
USE MM_multiply_matrix_by_another_matrix
USE MM_multiply_matrix_by_a_vector
USE MM_initialise_matrix
USE MM_initialise_vector
END MODULE MM



In the above, module MM (which 'uses' all of the modules) is sometimes referred to as a 'portability' module. To use all the modules that it uses (and, therefore, the subroutines that the modules contain), you simply need to have the line

USE MM

in the main program.

As mentioned in one of the above replies, one obvious advantage of using a 'portability' module is convenience -- in that you only need to have the single line

USE MM

in the main 'calling' program, instead of having the several lines

USE MM_add_matrix_to_another_matrix
USE MM_add_vector_to_another_vector
USE MM_multiply_matrix_by_another_matrix
USE MM_multiply_matrix_by_a_vector
USE MM_initialise_matrix
USE MM_initialise_vector


Comment 2: Containment of related modules/subroutines
-----------------------------------------------------
In the above example, all of the subroutines were related by a common 'theme' (i.e. they all involved some kind of Matrix Manipulation [MM]). In such circumstances, some people might instead prefer to contain all such subroutines in a single module. For example, you might instead have


MODULE Contain_all_MM_subroutines
CONTAINS
-------------------------------------------
SUBROUTINE add_matrix_to_another_matrix
...
END SUBROUTINE add_matrix_to_another_matrix
-------------------------------------------
SUBROUTINE add_vector_to_another_vector
...
END SUBROUTINE add_vector_to_another_vector
-------------------------------------------
...
...
-------------------------------------------
SUBROUTINE initialise_vector
...
END SUBROUTINE initialise_vector
-------------------------------------------
END MODULE Contain_all_MM_subroutines


One advantage of this is that all of the related subroutines are contained (stored) in the same (single) module.

But, two disadvantages of this are:

1) you might not be able to see 'from a distance' which subroutines are contained in that single module -- and there might be literally dozens of subroutines. for example, in the above example, if another user (who is not familiar with module Contain_all_MM_subroutines) then comes along and wants to use module Contain_all_MM_subroutines, then he will need to 'scroll down' through the entire module to see what subroutines it contains.

in contrast, you don't necessarily have such a problem with the above 'portability' module (i.e. module MM) -- you just have to look at module MM to see which subroutines (modules) it uses.

2) since, when using the 'portability' module option, each subroutine is contained (stored) in it's own individual module, it follows that all subroutines are effectively 'independent' of each other (and, therefore, it might be easier to manage them as a whole).

Anyway, it all comes down to personal preference and what best suits each program. The above are simply options for you to choose from.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top