Access subroutine inside a module using a linked library - fortran

I would like to use a subroutine written inside a static library (written in Fortran) inside a different Fortran executables.
This is my working example:
subroutine my(a,b,c)
implicit none
real*8, intent(in) :: a,b
real*8, intent(out) :: c
!
c = a + b
!
end subroutine
That generates a XXX.lib file that I am pointing at with this main:
program main
implicit none
!
real*8 :: var1, var2
real*8 :: out1
!
var1 = 15.0
var2 = 10.0
call mysum(var1,var2,out1)
!
write(*,*) out1
!
end program
Everything is working, but the problem arise when I want to have my subroutine defined inside a module, like this:
module mymodule
contains
!
subroutine mysum(a,b,c)
implicit none
real*8, intent(in) :: a,b
real*8, intent(out) :: c
!
c = a + b
!
end subroutine
end module
At this point the "main" compiler fails in finding the subroutine. Is there a way to let the compiler "see" the subroutine declared inside the module?
Thank you

Simply, if you have a subroutine (or anything else) defined in a module that you want to be made accessible somewhere else you need to "use" that module:
program main
use mymodule
implicit none
....
end program
When you don't have that use mymodule which allows the compiler to see that the subroutine mysum is actually a module subroutine, the compiler is going to treat mysum still as an external subroutine.
Previously, mysum was an external subroutine, but that external subroutine was defined in the library object. It no longer is in the same way: there will likely be various bits of name mangling. It's your linker complaining.

Related

subroutine using module but is outside module and also used in module through an interface

When I have a subroutine outside a module but is used by means of a "pointer assignment" and the subroutine is defined by means of an interface but the real subroutine is in a separate file and used module I get compiler errors.
So when I have the following Fortran code:
module test_mod_a
save
type test_type_a
integer :: scl_a = 0
contains
procedure :: my_subr => test_subr_a
end type test_type_a
interface
subroutine test_subr_a(this)
import test_type_a
implicit none
class(test_type_a) :: this
end subroutine test_subr_a
end interface
end module test_mod_a
and
subroutine test_subr_a(this)
use test_mod_a
implicit none
class(test_type_a) :: this
end subroutine test_subr_a
When I give the commands (gfortran version 9.3.0):
gfortran -c test_a.f90
gfortran -c test_a_subr.f90
I get the compiler error:
test_a_subr.f90:3:6:
3 | use test_mod_a
| 1
Error: ‘test_subr_a’ of module ‘test_mod_a’, imported at (1), is also the name of the current program unit
There are a few ways to overcome this problem:
replace !use test_mod_a by !use test_mod_a, only : test_type_a
include the subroutine in the module (and discarding in the subroutine the use statement and in the module the interface
all a bit cumbersome for a large project.
Is there another way?
As well as the use of only (not including the name of the procedure), there are the two other techniques for avoiding identifier re-use:
private test_subr_a in the module
Use renaming in the subroutine with use test_mod_a, self_iface => test_subr_a
However, from the look of the structure it seems the intention really is for test_subr_a to be like a module subroutine but isn't for one of two reasons:
there's been incremental development of an old program and the external subroutine now wants to be used in a "modern" way
the implementation of the subroutine is split out for reasons of file size, avoiding compilation cascades, secrecy of implementation
With the luxury of changing the code in a significant way one can handle these.
For the first reason, one could go ahead and move the subroutine into the module and take the pain of having to update other references where it was an external subroutine. As mentioned in the question.
For the second reason, submodules could be considered:
module test_mod_a
implicit none
type test_type_a
integer :: scl_a = 0
contains
procedure :: my_subr => test_subr_a
end type test_type_a
interface
module subroutine test_subr_a(this)
class(test_type_a) :: this
end subroutine test_subr_a
end interface
end module test_mod_a
submodule(test_mod_a) implementation_a
implicit none
contains
module subroutine test_subr_a(this)
class(test_type_a) :: this
end subroutine test_subr_a
end submodule implementation_a
Again, test_subr_a is no longer an external subroutine, so other references may need fixing.

passing allocated array from subroutine to the main program in fortran; use or module? interface?

I want to allocate an array in a subroutine, and then use this array in the main program and pass it to some other subroutine. In the past (F77?) the passing could be done in a common block, but nowadays the favored procedure seems to be to use a module. When I try this, as in the code example, the compiler tells me
Rank mismatch in argument ‘f’ at (1) (scalar and rank-1)
Apparently, the main program thinks that 'f' is a scalar: but, I read this code to mean that I've declared it as a one-dimensional array, both inside the subroutine and in the main program. What am I missing?
I've tried variations, such as declaring the variables as part of the module, but nothing I could think of made the compilation error-free (and some produced many more errors ;-( ). Any insight is most appreciated.
module subs
contains
subroutine makef(f)
end subroutine makef
end module subs
c-----------------------------------------------------------------------
program work
use subs
implicit none
real, allocatable :: f(:)
call makef(f)
write (*,*) f
stop
end
c---------------------------------------------------------------------
subroutine makef(f)
implicit none
real, allocatable, intent(out) :: f(:)
integer :: i
integer :: is
is=10
allocate(f(-is:is))
do i=-is,is
f(i)=i
end do
return
end subroutine makef
Modules in Fortran are not like header files in other languages which merely provide information about things defined elsewhere. There is the concept of "deferred definition" (submodules) but in this case the module should say everything about the subroutine, not simply attempt to point to its existence.
In the example of the question, we have: the main program; a module subs with module procedure makef; an external subroutine makef.
The main program uses the module subs, and its procedure makef, so reference in the main program to makef is to that module procedure not the external subroutine makef.
The module subroutine makef has the argument f which has no declaration statements, making it an implicitly declared scalar/external function. This is the compiler's message. Use implicit none in modules, just as it's in the main program and external subroutine here.
The entire definition of the subroutine should be placed in the module:
module subs
implicit none
contains
subroutine makef(f)
real, allocatable, intent(out) :: f(:)
integer :: i
integer :: is
is=10
allocate(f(-is:is))
do i=-is,is
f(i)=i
end do
end subroutine makef
end module subs
Alternatively, if one does want to refer to the later implementation of an external procedure an interface block can feature in the module without declaring the subroutine itself. In this case it will still be necessary to specify the complete interface:
module subs
implicit none
! An interface block to give an explicit interface to the external subroutine makef
interface
subroutine makef(f)
implicit none
real, allocatable, intent(out) :: f(:)
end subroutine makef
end interface
end module subs
In this case, don't prefer the interface block.
You only placed the copy of the first and the last line into the module. That can't work. You must move the whole subroutine into the module.

How do you specify a module variable as a part of dummy argument declaration inside an interface block?

I have a subroutine sub_x defined as
subroutine sub_x(n, a)
use, intrinsic :: iso_c_binding
use mod_a, only : m
implicit none
integer(c_long), intent(in) :: n
real(c_double), intent(in) :: a(1:m)
.
.
.
rest of the codes
.
.
That is, sub_x depends on a module variable m as an extent of its array argument. Now, in a separate file, the interface block of sub_x goes as follows
module mod_x
use, intrinsic :: iso_c_binding
interface
subroutine sub_x(n, a)
import :: c_long, c_double, m
integer(c_long), intent(in) :: n
real(c_double), intent(in) :: a(1:m)
end
end interface
end module mod_x
And any procedure calling sub_x will have a use mod_x statement. When trying to compile the file containing module mod_x, file_x.f90 with ifort -c file_x.f90 I got error saying "IMPORT-name must be the name of an entity in the host scoping unit. [m]" showing that the compiler was not able to resolve m. It may be able to resolve c_long and c_double because of the presence of use, intrinsic :: iso_c_binding in mod_x definition, but I may be wrong. Adding use mod_a, only : m in mod_x definition may solve the issue, but that means mod_x will depend on mod_a and I try to avoid dependency between modules.
One way that seems to work is to move the interface block to a plain text file, say interface_x.f90, and add an include "interface_x.f90" line in any procedure calling sub_x. But I try to avoid using this method because I have tens of external subroutines and it's better to have the interfaces of all of them in a single file. If I were to use this, just about any procedure having an include "interface_x.f90" will have to have use mod_a, only : m even though it doesn't need m. What's the solution?
It is not necessary to use an import statement to make an entity accessible in an interface block. It is one way, and in some cases the only way. This is not one of those cases.
The import statement controls accessibility of entities from the host scope of a scoping block (such as an interface block). In the (simplified) case of the question
module mod_x
use, intrinsic :: iso_c_binding
interface
subroutine sub_x()
import :: c_long
end
end interface
end module mod_x
the import statement makes the entity c_long from the module scope accessible in the interface specification of sub_x. That entity is itself available in the module scope because it is use associated from the module iso_c_binding.
Exactly the same entity is made accessible in the interface specification by
module mod_x
interface
subroutine sub_x()
use, intrinsic :: iso_c_binding, only : c_long
end
end interface
end module mod_x
This is much as in the actual subroutine specification of sub_x. m can be made accessible in the same way:
module mod_x
interface
subroutine sub_x(n, a)
use, intrinsic :: iso_c_binding, only : c_long, c_double
use mod_a, only : m
integer(c_long), intent(in) :: n
real(c_double), intent(in) :: a(1:m)
end
end interface
end module mod_x
(Or equivalently by combining an import with use mod_a in the module scope.)
Note that this is a module dependency whichever way you write it: mod_x depends on mod_a because the interface specified in mod_x has a characteristic determined by an entity in mod_a.

Subroutine ignores type declaration above in module

I created a type, model, in a module, and then declared a variable, md, having that type. In the subroutine contained in the module, the declaration of md above is ignored, I have to declare it explicitly again.
In the main program I don't need to declare the type of md, the use statement appears to work. Can anyone explain why the subroutine ignores the type declaration of md?
Here is the code. I am using gfortran compiler on Linux.
program main
use struc_model
call mod_gen(md)
do i=1, md%ndof
write(*,*) 'row =', i
write(*,*) 'm=', md%m(i,:)
end do
end
module struc_model
type model
integer :: ndof
real*8, allocatable, dimension(:,:) :: m
end type
type (model) :: md
contains
subroutine mod_gen(md)
! for some reason have to declare type of md again
! declaration above is ignored
type (model) :: md
md%ndof=4
allocate(md%m(md%ndof,md%ndof))
md%m=0.d0
do i=1, md%ndof
md%m(i,i)=1.d0
end do
end subroutine
end module
There are three terms of interest here: use association, host association and argument association. You can read about those in full detail with other resources, but I'll use them here in explanation.
Look first at the module. For the sake of clarity I'm going to take your variables to be of type integer. Here's a simple program
module mod
implicit none
integer i
end module mod
program prog
use mod
implicit none
print *, i ! i is use associated
end program prog
Here, we aren't saying that the type of i is known from the declaration through the module, we're saying that i is the variable from the module (and its type follows from that).
Now look at a simplified module:
module mod
implicit none
integer i
contains
subroutine sub(i)
integer i
end subroutine
end module mod
So, why do I need that integer i declaration in the subroutine sub? That's because i in that subroutine, appearing as it does in the argument list, is a dummy argument. A dummy argument needs its type specifying in its scope, the subroutine. Within the subroutine a reference to i is to the dummy argument and not to the module variable: the module variable is made inaccessible.
If my program then looks like
use mod
call sub(i)
end program
what I'm doing is passing the module variable i---which has been use associated---to the subroutine sub as its dummy argument (through argument association).
Now, if I wanted to modify the module variable in the module's subroutine I could instead use host association
module mod
implicit none
integer i
contains
subroutine sub() ! No dummy argument i, references in here are to the module's i
end subroutine
end module mod
program prog
use mod
implicit none
call sub ! No argument for the module's own variable
end program prog
Within that module subroutine i refers to the module variable.
But what I suspect you mean to do is have a variable in the program's scope which is passed to the subroutine. Going back to your terminology:
module struc_model
type model
integer :: ndof
real*8, allocatable, dimension(:,:) :: m
end type
contains
subroutine mod_gen(md)
type (model) :: md
md%ndof=4
allocate(md%m(md%ndof,md%ndof))
md%m=0.d0
do i=1, md%ndof
md%m(i,i)=1.d0
end do
end subroutine
end module
program main
use struc_model
type (model) :: md ! A variable within the program's scope
call mod_gen(md) ! Argument associated with the subroutine's dummy
do i=1, md%ndof
write(*,*) 'row =', i
write(*,*) 'm=', md%m(i,:)
end do
end
In summary
module struc_model
type model
integer :: ndof
real*8, allocatable, dimension(:,:) :: m
end type
type (model) :: md
end module
declares a module variable md and doesn't state that all variables called md are of type(model).

How to pack fortran interface as a standalone module

I want to package the fortran interface as a standalone library, something similar head file in c/c++. Here is my code. The problem is that i want to call the "hello" subroutine to run the "hello" subroutine. can anyone help me out?
I want to put Interface and set_callback,invoke_callback as a standalone module file.
MODULE DEMO
INTERFACE
SUBROUTINE callback_prototype(callbackID)
CHARACTER(*) :: callbackID
END SUBROUTINE callback_prototype
END INTERFACE
PROCEDURE( callback_prototype ), POINTER :: f_ptr => NULL()
CONTAINS
SUBROUTINE set_callback(func)
IMPLICIT NONE
EXTERNAL :: func
f_ptr => func
call HELLO
END SUBROUTINE
SUBROUTINE invoke_callback(callbackID)
CHARACTER(*) :: callbackID
if (associated(f_ptr)) call f_ptr(callbackID)
END SUBROUTINE
SUBROUTINE HELLO
IMPLICIT NONE
Dosomething
END SUBROUTINE
END MODULE
This would be easily possible with submodules, unfortunately they are not widely available. Thus, I guess the current solution would be to use "hello" as an external function with an implicit interface and putting it into a different file.
Update: Some example based on your code.
subroutine HELLO
implicit none
write(*,*) 'HELLO'
end subroutine HELLO
module demo
implicit none
interface
subroutine callback_prototype(callbackID)
character(*) :: callbackID
end subroutine callback_prototype
end interface
procedure(callback_prototype), pointer :: f_ptr => NULL()
contains
subroutine set_callback(func)
procedure(callback_prototype) :: func
external :: HELLO
f_ptr => func
call HELLO()
end subroutine set_callback
subroutine invoke_callback(callbackID)
character(*) :: callbackID
if (associated(f_ptr)) call f_ptr(callbackID)
end subroutine invoke_callback
end module demo
program test_demo
use demo
implicit none
write(*,*) 'small program'
end program test_demo
Putting this into a file test.f90, and running "gfortran test.f90" produces an executable. Of course, if you want to have that stuff separated you would rather put each part in separate files. You then have to ensure, that the object file containing "hello" is included during link time. And as pointed out by Vladimir_F, you can use an interface declaration to equip the routine with an explicit interface, where you are calling it.
2nd update:
If you put these into three different files
hello.f90
demo.f90
test.f90
You should be able to compile an executable out of them like this:
gfortran -c demo.f90 hello.f90 test.f90
gfortran *.o
The first line creates the object files, while the second links them together. Note, that order is important, the module information for demo.f90 needs to be available before compiling test.f90.