Print won't work inside a fortran function - fortran

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)

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”

Difference between subroutine inside module "contains" and outside module

I have a large source code where subroutines in modules are defined outside the module ... end module statement (ie. not inside a contains statement). I've included a simplified module below:
module core
implicit none
type :: disc_status
sequence
real*8 :: alpha1, alpha2, alpha3
end type disc_status
end module core
subroutine tester(input)
use core
type(disc_status), intent(in) :: input
print *, input%alpha1, input%alpha2, input%alpha3
end subroutine tester
Here's an example program using the module and subroutine:
program flyingDiscSimulator
use core
implicit none
type(disc_status) :: disc
disc%alpha1 = 1.1D0
disc%alpha2 = 1.2D0
disc%alpha3 = 1.3D0
call tester(disc)
print *, 'it works'
end program flyingDiscSimulator
Normally, I end up seeing subroutines use the contains statement within a module:
module core
implicit none
type :: disc_status
sequence
real*8 :: alpha1, alpha2, alpha3
end type disc_status
contains
subroutine tester(input)
type(disc_status), intent(in) :: input
print *, input%alpha1, input%alpha2, input%alpha3
end subroutine tester
end module core
However, the program file referenced above doesn't require any changes to use either way of including a subroutine in a module (using gfortran anyways). Thus, there appears to be no difference in the usage of the module or it's subroutine between the two solutions. Are there any "under the hood" differences between the two styles?
The versions
module m
contains
subroutine s()
end subroutine s
end module m
and
module m
end module m
subroutine s()
end subroutine s
say completely different things, but in the case of the question the end results are much the same.
The first version here creates a module procedure s with host m; the second version has an external procedure s with no host.
Although the example of the question has the external procedure using the module, there is more generally a difference: the module procedure has access to all entities in the module (except when made inaccessible through an import statement or by being obscured by local names; the external procedure using the module has access only to those public entities.
However, come the main program the effects are different. The external subroutine and its name are global entities. Going to my second version, then
program main
call s
end program
is a valid program which calls the external subroutine s. This subroutine reference is valid because the implicit interface for s in the main program suffices. If the external subroutine s were such than an explicit interface were required then main program here would not be allowed. It is acceptable, but not required, to have an external s statement in the main program to reinforce to the reader that the subroutine is an external one (with implicit interface). (implicit none external would make external s necessary.)
The example of the question is such that an explicit interface is not required.
A module procedure always has an explicit interface available when accessible. However, a module procedure is not a global entity and its name is not a global identifier.
Under the hood, there are implementation differences (stemming from the above): most notably compilers will often "name mangle" module procedures.
In summary, there are differences between the two approaches of the question, but they won't be noticed by the programmer in this case.
The procedure inside the module will have an explicit interface (aka the compiler knows about the arguments' characteristics).
Whereas the procedure outside of the module will have an implicit interface (aka the compiler must make assumptions about the arguments).
Explicit interfaces help the compiler to find programming errors and are therefore favourable.
For a more indepth discussion of advantages see for example this answer.
I am not even sure if it is valid Fortran to call tester inside the program when it is defined outside of core?
The line use core should just make the module's public objects known and the tester procedure needs its own external tester line.

How do you call a bind-C function within 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).

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.

How to print data from a module used in my fortran subroutine

Thanks for the help in advance..
Kindly I want to print data in an output file of the main FORTRAN program and these data defined in a module and I already declare using that module in the main program. but I couldn't get the write statements neither in the main program nor in the module.
MODULE model
IMPLICIT NONE
SUBROUTINE model_initialize
IMPLICIT NONE
INTEGER a,dim REAL(float) :: E,nu
REAL(float) :: lambda,mu
E=5000 lambda = E*nu/(1.d0+nu)/(1.d0-2.d0*nu)
mu = E/2.d0/(1.d0+nu)
RETURN
END SUBROUTINE model_initialize
Write (6,)'Lambda',lambda
Write (6,)'mu',mu
END MODULE model
SUBROUTINE XXXX
USE model
IMPLICIT NONE
CALL model_initialize
Write (6,)'Lambda',lambda
Write (6,)'mu',mu
END SUBROUTINE XXX
When I put the write statements in the module or in the main subroutine , I cant see them in the output.
Many thanks for the help
Msekh
Mgilson has already provided you with an example that should work, but the code you posted will not compile. This is why:
Your subroutine model_initialize is in the "specification part" of your module. It should either be external (like xxxx) or internal to the module (in which case you have to provide a contains statement).
The variables in model_initialize are local to the subroutine and will not be accessible outside it.
You cannot have executable code (like write) in the specification part of a module, only in internal procedures.
float is not a native Fortran kind, you have to use the numerical parameters (usually 4, 8, 16), define your own, or use the definitions in the iso_fortran_env module.
That said, if you only need to define some data you want to make accessible, you can simply put that directly in the module like this:
module model
use iso_fortran_env
implicit none
integer :: A, dim
real(real32) :: E, nu, lambda, mu
E = 5000
lambda = E*nu/(1.d0+nu)/(1.d0-2.d0*nu) ! <-- nu is undefined
mu = E/2.d0/(1.d0+nu)
contains
subroutine xxxx
write (6,*) 'lambda', lambda
write (6,*) 'mu', mu
end subroutine xxxx
end module model
do you mean something like:
module material
real :: stress = 6.0
save
end module material
subroutine xxx()
use material, only: stress
write(6,*) stress
end subroutine
program main
call xxx()
end program main
This will write the value of stress to the file-like object connected with unit 6 (usually this is stdout, but it might create a new file called fort.6 depending on compiler and environment settings).