How do you call a bind-C function within fortran? - fortran

I'm just beginning with Fortran, and I've got a program and a function
PROGRAM multiplication
implicit none
real :: A1
!A1 = mult(2, 3)
!write(*,1) A1
1 format(f8.8)
END PROGRAM multiplication
REAL FUNCTION mult(a, b) BIND(C, name='foomult')
real,value :: a,b
mult = a * b
END FUNCTION
I've got the function working in java through JNA, but when I try to call mult from within the fortran main program, I get a ton of compiling errors (I can provide them if you want). I have a feeling it must be something obvious but I can't find a solution anywhere. Are bound functions not intended to be called from within non-external code? Or do I just have a poor understanding of function syntax?

For the main program, the compiler doesn't "know" the properties of the function, i.e., the types of the function and its arguments. Your function uses an "advanced" argument property, value, so it is necessary to declare the properties in some way to the caller. The easiest way to make those properties known to the caller is to put the function into a module and use that module from a program or procedure that uses it:
module MyModule
contains
FUNCTION mult(a, b) BIND(C, name='foomult')
use iso_c_binding
real (c_float) ,value :: a,b
real (c_float) :: mult
mult = a * b
END FUNCTION
end module MyModule
PROGRAM multiplication
use MyModule
implicit none
real :: A1
A1 = mult(2.0, 3.0)
write(*,*) A1
END PROGRAM multiplication
I've also declared the variables in the function to be compatible with C. It happens, at least with gfortran on my computer, that those are the same as plain real, so they are compatible with the call in the main program. Compatibility could be guaranteed by writing the call as mult (2.0_c_float, 3.0_c_float).

Related

Fortran use gdb to print function name from address

Let's assume I have the following code:
module eval_mod
implicit none(type, external)
private
public :: eval
abstract interface
real pure function real_function_t(x)
real, intent(in) :: x
end function
end interface
contains
pure function eval(f, x) result(res)
procedure(real_function_t) :: f
real, intent(in) :: x
real :: res
res = f(x)
end function
end module
program main
use iso_fortran_env, only: stdout => output_unit
use eval_mod, only: eval
implicit none(type, external)
write(stdout, *) eval(double, 2.)
write(stdout, *) eval(triple, 2.)
contains
pure real function double(x)
real, intent(in) :: x
double = 2. * x
end function
pure real function triple(x)
real, intent(in) :: x
triple = 3. * x
end function
end program
and compile it with gfortran -Wall -Wextra -Werror -g -fbounds-check.
If I set a breakpoint to eval_mod::eval, I would like to see with which function argument eval was called.
What I actually see is
Breakpoint 2, eval_mod::eval (f=0x7fffffffced8, x=2) at main.F90:17
If I take the address and follow this question, I should be able to see the function name in the symbol table by doing:
info symbol 0x7fffffffced8
Unfortunately I get an error
No symbol matches 0x7fffffffced8.
How can I see the function name of a function passed as argument?
PS: I use gfortran 7.5.0 and gdb 11.1.
double and triple are internal functions (inside the main program). Passing internal functions is tricky due to the host association of the variables from the parent scope. Therefore they are often implemented using trampolines. The address you see is the address of the trampoline, in other words, a so called thunk. The trampoline than calls the actual function.
The address most likely points somewhere on the stack where the trampoline code is placed. In that code you will likely find a jump instruction with the address of the actual function.
See also this great article by Steve Lionel Doctor Fortran in “Think, Thank, Thunk”

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

Print won't work inside a fortran function

I wrote a fortran function to call a blas level 3 function sgemm. I'm passing the matrices to be multiplied to this function and returning the result. The code works and the result is also correct. But there is a print statement inside which won't print anything. Why is that happening?
function matmul(A,B) result(C)
real,dimension(:,:),allocatable::A
real,dimension(:,:),allocatable::B
real,dimension(:,:),allocatable::C
integer::m,n,k
m = size(A,1)
n = size(A,2)
k = size(B,2)
print *,"INSIDE FN"
call sgemm ('N','N',m,k,n,1.0,A,n,B,k,0.0,C,k)
end function matmul
The function name you chose, MATMUL, is a fortran intrinsic function (see section 13.7.105 of the fortran standard or here). The function you implemented tries to 'overload/shadow' this intrinsic with the same name. This is possible in Fortran, but you have to explicitly inform the compiler about it. When compiling the following code :
function matmul(A,B) result(C)
real,dimension(:,:),allocatable::A,B,C
print *,"matmul overloaded"
C=A
end function matmul
program test
real, dimension(:,:), allocatable :: A,B,C
allocate(A(1,1),B(1,1),C(1,1))
C = matmul(A,B)
end program test
The program test has no knowledge about the existence and/or interface of your own matmul subroutine. Both the program test and the subroutine matmul live in two unconnected program units, and as a consequence, the compiler will assume that the intrinsic MATMUL function is to be called.
EXTERNAL attribute: (see STDF2003::5.3.9)
As the compiler has no mechanism to access the users matmul code from the program unit test, it's interface is implicit. If you want to specify that the name matmul is the one of an external or dummy procedure, we can use the external statement :
program test
external :: matmul
real, dimension(:,:), allocatable :: A,B,C
allocate(A(1,1),B(1,1),C(1,1))
C = matmul(A,B)
end program test
INTERFACE block : (See STDF2003::12.4)
With the external attribute, you just specify that matmul is an external or dummy procedure. It does not specify the interface, which remains implicit. The interface, however, can be defined by means of an interface block as
program test
real, dimension(:,:), allocatable :: A,B,C
allocate(A(1,1),B(1,1),C(1,1))
interface
function matmul(A,B) result(C)
real,dimension(:,:),allocatable::A,B,C
end function matmul
end interface
C = matmul(A,B)
end program test
The latter is automatically achieved when placing the function matmul in a module and using that module.
note: information loosely adopted from Modern Fortran Explained, M. Metcalf, J. Reid and M. Cohen, (Oxford, 2013)

Integrating using Quadpack in multiple dimensions [duplicate]

I'm trying to use routines in QUADPACK to perform numerical integration. The routines expect functions to be passed as REAL,EXTERNAL, so I don't have the liberty of using pointers or whatever else.
Is it possible to alias a function f(x,a,b,...) as being a function f(x) for the routine that expects a function of x only? Much like what one would accomplish in MATLAB with #(x)f(x,a,b,...).
You cannot make similar tricks with functions in Fortran directly. You also cannot return a closure in Fortran. Just write a wrapper.
function wrap_f(x) result(res)
...
res = f(a,b,...)
end function
It can be an internal or module function and get a and b by the host association or it can use the module containing a and b.
If you want to pass the function as an actual argument, it cannot be an internal procedure in up to Fortran 2003, but only in Fortran 2008. But it works in recent versions of gfortran and ifort. For better portability use a module.
I can show a nice solution for this problem. I am also a former MATLAB user and when switching to FORTRAN you miss function handles haha. I solved your problem in this way:
module
private
public :: f , g
real(kind=RP) :: a0,b0,c0,...
contains
function f(x,a,b,c,d,...)
implicit none
real(kind=RP) :: x,a,b,c,d,...
real(kind=RP) :: f
! Here you define your function
f = ...
end function f
function g(x)
implicit none
real(kind=RP) :: x , g
! Here you call "f" function with the frozen variables *0
g = f(x,a0,b0,c0,...)
end function g
! We said that parameters were private
! (to avoid to be modified from the outside, which can be dangerous,
! so we define functions to set their values
subroutine setValues(a,b,c,...)
implicit none
real(kind=RP) :: a,b,c,...
a0 = a
b0 = b
c0 = c
end subroutine setValues
end module

Intrinsic function as a function argument

Well, this is the issue I've today...
I'm writing a module procedure that has, as an argument, a function. This module looks something like this:
module Integ
implicit none
<variables declaration>
contains
function Integral(a,b,f) result(res)
real, intent(in) ::a, b
real ::res
interface
pure function f(x)
real, intent(in) :: x
real :: f
endfunction
endinterface
<more code of function Integral>
endfunction Integral
endmodule Integ
Well, up to here, everything is great. The issue appears when I try to use this function with a Fortran intrinsic function. I.e., in this code:
program main
use Integ
implicit none
real ::res,a,b
a=3.0; b=4.0
res=Integral(a,b,sin) !<- This line does not work
!res=Integral(a,b,sen) !<- This line does work
contains
function sen(x)
real, intent(in) :: x
real :: sen
sen=sin(x)
endfunction
endprogram
The first line does not work, giving the error message:
main.f90(17): error #6404: This name does not have a type, and must have an explicit type. [SIN]
r=Int1DMonteCarlo(0.0,1.0,sin,10000)
--------------------------^
main.f90(17): error #6637: This actual argument must be the name of an external user function or the name of an intrinsic function. [SIN]
r=Int1DMonteCarlo(0.0,1.0,sin,10000)
--------------------------^
But the second line (comented in the snipplet) does.
Those errors are quite disorienting for me, because sin is a Fortran intrinsic function (thing that contradicts error nr 2), and in consequence explicit in every scope (thing that contradicts the error nr 1).
Obviously I'm doing something wrong but I don't know what.
So I would like to ask:
It is possible to call a module procedure with an intrinsic function as an actual argument?
I'm loosing something aside from declaring the interface inside the procedure?
If you are interested this is the complete source of the module and this is the source of the main
Sorry if I'm asking a stupid question. I think I am doing things the way the books I'm reading now (Metcalf, Numerical recipes for Fortran V:II) are telling me.
Thank you for your time!
Use an intrinsic statement in the main program to declare that the actual argument sin is the intrinsic. This requirement is spelled out in the description of the intrinsic attribute in the Fortran standard.
With an eye to the future, you may be better off writing your own wrapper function around the intrinsic - create a function mysin that simply calls sin.