PETSC header #include'd in a module - module

I have a module which holds global variables. To declare some global variables, I need to use HDF5. I am also using a library, so I also need to include a header file. So the preamble of global_variable.F90 looks like this.
module global_variables
use HDF5
#include "finclude/petscsys.h"
#include "finclude/petscvec.h"
integer(HID_T) id_file
integer(HID_T) id_plist
Vec M, C, K
...
end module
Vec is a data type defined in the header file and HID_T is a data type defined in HDF5 module.
Now, I have a file which holds subroutines for I/O. This file also uses HDF5 and the same library used in global_variables.F90. So IO.F90 looks like this.
module io
use global_varibles
contains
subroutine read_input_file( vector )
Vec vector
integer HDF5err
call H5open_f( HDF5err )
...
end subroutine
end module
Question 1: compiler returns error when compiling IO.F90, saying that Vec is undefined data type. But it does not complain about HID_T. I thought global_variables module already contains both HDF5 modules and header files, using global_variables module in IO.F90 will handle every data type declaration but it seems not. Could you please help me understand what I am understanding wrong?
Question 2: Is there a way to restrict the effect of #include to the module where it is declared?
PS. If I include #include "finclude/petscvec.h" in IO.F90, which declares Vec, then it compiles well.

The syntax
Vec vector
is completely alien to Fortran. It works only because Vec is a C pre-processor (CPP) macro defined in the header file "finclude/petscvec.h" as
#define Vec PetscFortranAddr
That means that you must include the header file in every Fortran file in which you use the above syntax with Vec. The macro cannot be inherited using the Fortran use because it is not a part of Fortran.
The PetscFortranAddr is in the end defined in "finclude/petscdef.h" as an integer with 4 or 8 bytes depending on your system.
There is probably nothing you can do except reverse engineering what it in the end the pre-processor makes to be, but I wouldn't go that way, it may be unportable.

Related

Fortran link modules for precision and global variable types

I am new to Fortran and trying to understand if the following is possible. My idea to structure the program is to declare the precision and variable types in one module. Then make use of those variables without declaring again the type in other modules or the main program.
module pre
implicit none
INTEGER, PARAMETER :: sp=SELECTED_REAL_KIND(6,37)
INTEGER, PARAMETER :: dp=SELECTED_REAL_KIND(15,307)
INTEGER, PARAMETER :: qp=SELECTED_REAL_KIND(33,4931)
REAL(dp), PARAMETER :: pi = 4.*ATAN(1.)
REAL(dp) :: H
REAL(dp) :: M
REAL(dp) :: KR
end module pre
Now I want to make use of all the variables in another module that contains one or more functions, such as:
module hon
use pre
implicit none
contains
function KE(H,M) result(KR)
KR = 2*PI/H/M
end function KE
end module hon
Then I use gfortran in this order:
gfortran -c mod_pre.f90
gfortran -c mod_hon.f90
Since 'module pre' is part of 'module hon' I compile in order, but gfortran shows an error.
With the code above I understand the variable types and parameters should have been included by USE; But the message I get from gfortran is that none of my variables have IMPLICIT type when I try to compile 'module hon'.
Could somebody clarify the problem or suggest a solution? I would like to avoid having my variables scattered in multiple modules.
Thanks!
In the function statement, the result(kr) says that the function result has name kr. This function result is not the same thing as the module variable kr. In particular, this function result makes inaccessible the module variable.
The function result is specific to the function itself and its properties must be declared within the function subprogram.
Similarly, the dummy arguments of the function, H and M, are distinct from the module variables and need to be declared in the function subprogram.
Beyond that, you perhaps have similar concerns to this other question.
To be clear, it isn't possible to say something like "all function results called kr and all dummy arguments called H or M have these characteristics". Each individual object must be given the properties.
However, although I don't recommend this, this is a situation where literal text inclusion (using a preprocessor or include file) could help you:
function ke(H, M) result (kr)
include 'resdummydecls'
...
end function
where the file has the declarations.

OCaml module types and separate compilation

I am reading through OCaml lead designer's 1994 paper on modules, types, and separate compilation. (kindly pointed to me by Norman Ramsey in another question ). I understand that the paper discusses the origins of OCaml's present module type / signature system. It it, the author proposes opaque interpretation of type declarations in signatures (to allow separate compilation) together with manifest type declarations (for expressiveness). Attempting to put together some examples of my own to demonstrate the kind of problems the OCaml module signature notation is trying to tackle I wrote the following code in two files:
In file ordering.ml (or .mli — I've tried both) (file A):
module type ORDERING = sig
type t
val isLess : t -> t -> bool
end
and in file useOrdering.ml (file B):
open Ordering
module StringOrdering : ORDERING
let main () =
Printf.printf "%b" StringOrdering.isLess "a" "b"
main ()
The idea being to expect the compiler to complain (when compiling the second file) that not enough type information is available on module StringOrdering to typecheck the StringOrdering.isLess application (and thus motivate the need for the with type syntax).
However, although file A compiles as expected, file B causes the 3.11.2 ocamlc to complain for a syntax error. I understood that signatures were meant to allow someone to write code based on the module signature, without access to the implementation (the module structure).
I confess that I am not sure about the syntax: module A : B which I encountered in this rather old paper on separate compilation but it makes me wonder whether such or similar syntax exists (without involving functors) to allow someone to write code based only on the module type, with the actual module structure provided at linking time, similar to how one can use *.h and *.c files in C/C++. Without such an ability it would seem to be that module types / signatures are basically for sealing / hiding the internals of modules or more explicit type checking / annotations but not for separate / independent compilation.
Actually, looking at the OCaml manual section on modules and separate compilation it seems that my analogy with C compilation units is broken because the OCaml manual defines the OCaml compilation unit to be the A.ml and A.mli duo, whereas in C/C++ the .h files are pasted to the compilation unit of any importing .c file.
The right way to do such a thing is to do the following:
In ordering.mli write:
(* This define the signature *)
module type ORDERING = sig
type t
val isLess : t -> t -> bool
end
(* This define a module having ORDERING as signature *)
module StringOrdering : ORDERING
Compile the file: ocamlc -c ordering.mli
In another file, refer to the compiled signature:
open Ordering
let main () =
Printf.printf "%b" (StringOrdering.isLess "a" "b")
let () = main ()
When you compile the file, you get the expected type error (ie. string is not compatible with Ordering.StringOrdering.t). If you want to remove the type error, you should add the with type t = string constraint to the definition of StringOrdering in ordering.mli.
So answer to you second question: yes, in bytecode mode the compiler just needs to know about the interfaces your are depending on, and you can choose which implementation to use at link time. By default, that's not true for native code compilation (because of inter-module optimizations) but you can disable it.
You are probably just confused by the relation between explicit module and signature definitions, and the implicit definition of modules through .ml/.mli files.
Basically, if you have a file a.ml and use it inside some other file, then it is as if you had written
module A =
struct
(* content of file a.ml *)
end
If you also have a.mli, then it is as if you had written
module A :
sig
(* content of file a.mli *)
end =
struct
(* content of file a.ml *)
end
Note that this only defines a module named A, not a module type. A's signature cannot be given a name through this mechanism.
Another file using A can be compiled against a.mli alone, without providing a.ml at all. However, you want to make sure that all type information is made transparent where needed. For example, suppose you are to define a map over integers:
(* intMap.mli *)
type key = int
type 'a map
val empty : 'a map
val add : key -> 'a -> 'a map -> 'a map
val lookup : key -> 'a map -> 'a option
...
Here, key is made transparent, because any client code (of the module IntMap that this signature describes) needs to know what it is to be able to add something to the map. The map type itself, however, can (and should) be kept abstract, because a client shouldn't mess with its implementation details.
The relation to C header files is that those basically only allow transparent types. In Ocaml, you have the choice.
module StringOrdering : ORDERING is a module declaration. You can use this in a signature, to say that the signature contains a module field called StringOrdering and having the signature ORDERING. It doesn't make sense in a module.
You need to define a module somewhere that implements the operations you need. The module definition can be something like
module StringOrderingImplementation = struct
type t = string
let isLess x y = x <= y
end
If you want to hide the definition of the type t, you need to make a different module where the definition is abstract. The operation to make a new module out of an old one is called sealing, and is expressed through the : operator.
module StringOrderingAbstract = (StringOrdering : ORDERING)
Then StringOrderingImplementation.isLess "a" "b" is well-typed, whereas StringOrderingAbstract.isLess "a" "b" cannot be typed since StringOrderingAbstract.t is an abstract type, which is not compatible with string or any other preexisting type. In fact, it's impossible to build a value of type StringOrderingAbstract.t, since the module does not include any constructor.
When you have a compilation unit foo.ml, it is a module Foo, and the signature of this module is given by the interface file foo.mli. That is, the files foo.ml and foo.mli are equivalent to the module definition
module Foo = (struct (*…contents of foo.ml…*) end :
sig (*…contents of foo.mli…*) end)
When compiling a module that uses Foo, the compiler only looks at foo.mli (or rather the result of its compilation: foo.cmi), not at foo.ml¹. This is how interfaces and separate compilation fit together. C needs #include <foo.h> because it lacks any form of namespace; in OCaml, Foo.bar automatically refers to a bar defined in the compilation unit foo if there is no other module called Foo in scope.
¹ Actually, the native code compiler looks at the implementation of Foo to perform optimizations (inlining). The type checker never looks at anything but what is in the interface.

Can we export a function made available through a static library

I have a static library say "A.lib" which contains a function int foo(). I have another dll say "B.dll" which consumes A.lib and uses the function foo() and also exports some other functions. Is it possible to export the function int foo() (imported from A.lib) from B.dll so that it can be consumed in a third dll say "C.dll".
I want to know whether it is possible or not, I dont want workarounds like making A.lib available to the C.dll. Also, I am not concerned if this is a bad design or not.
Thanks very much for your patience to read this through.
I had the same requirement - just found a different solution:
Assuming that A.lib has an A.h (that is consumed by source files used to build B.dll e.g. assuming that A.h contains prototypes for functions contained in A.lib), just add the following in A.h:
#pragma comment(linker, "/export:_foo")
This will instruct the linker to export foo() when building B.dll. Note the leading underscore - it is there because that's the true name of the symbol for foo() contained in A.lib (use dumpbin /symbols A.lib | findstr foo to see it). In my example foo() was using the __cdecl calling convention, but if you use __stdcall() or compile as C++, you'll get different name decoration, so you'll have to adjust the #pragma statement above as a result.
It doesn't matter if A.h gets included by many source files in B.dll - the linker doesn't complain if the exact same definition is made multiple times.
One "advantage" to this approach is that you don't even have to use the __declspec(dllexport) specifier on foo() in A.lib ...
Yes, it's possible but any code example is language dependent.
(for example in C you may simply export a function with the same name and C.dll will see it)

why do omp functions not work when constants are declared in a module?

i have a module 'gvars' defined for my global variable declarations. when i define
integer :: nthreads, max_threads, tid, omp_get_max_threads, omp_get_num_threads, omp_get_thread_num inside of my gvars module, the call maxthreads = omp_get_max_threads() in my main routine gives me the following error upon compilation:
maxthreads = omp_get_max_threads()
1
Error: Unclassifiable statement at (1)
but when i include the integer :: definitions above inside my main routine, it compiles just fine and gives me the desired results. if i even go as far as to define nthreads = -1 inside my gvars module, i am able to print out the correct value in my main routine so i know it is being included and defined correctly, it's just that for some reason i cannot have it as a return value from openmp functions.
why would this be?
is there any other way to keep these values as global variables and still define them in my main routine instead of a module?
if it matters, i am using gfortran to compile
The problem is not with the declaration of maxthreads, but with the declaration, on the same line, of omp_get_max_threads. As haraldkl showed, you need to use omp_lib instead, to automatically get access to the declarations of these functions.
(If for some reason you really don't want to do it that way, you can also add the statement external :: omp_get_max_threads, ... to the module.)
Not really an answer, but I do not know how else to put the code in here. Sorry...
module gvars
integer :: maxthreads
end module gvars
program test
use gvars
use omp_lib
implicit none
maxthreads = omp_get_max_threads()
end program test
compiled with:
gfortran -fopenmp test.f90
Where gfotran -v gives:
gcc version 4.4.5 (GCC)

Including a module more than once

Suppose I have a module which defines some basic constants such as
integer, parameter :: i8 = selected_int_kind(8)
If I include this in my main program and I also include a module which does some other things (call this module functions) but functions also uses constants, then am I essentially including constants twice in my main program?
If so, is this bad? Can it be dangerous at all to include a module too many times in a program?
No, it is fine to do this. All you are doing with the use statement is providing access to the variables and functions defined in your module via use association. It is not like declaring variables each time they are use'd (they are in fact redeclared however).
The only thing to be wary of are circular dependencies, where module A uses module B and module B uses module A. This is not allowed.
Edit: From Metcalf et al. Fortran 95/2003 explained, pg. 72:
A module may contain use statements that access other modules. It must not access itself directly or indirectly through a chain of use statements, for example a accessing b and b accessing a.
Whilst this quote doesn't directly answer your question, it reiterates that really the only thing you can't do is have a circular dependency. So the following is perfectly valid:
module one_def
implicit none
integer, parameter :: one=1
end module one_def
module two_def
use one_def, only : one
implicit none
integer, parameter :: two=one+one
end module two_def
program test
use one_def, only : one
use two_def, only : two
implicit none
print*, two == one+one ! This prints .True.
end program