Is it possible to load built-in functions with a USE statement? - fortran

I'm currently toying around with passing functions as arguments.
In the program below I use the built-in function EXP as an argument for
the integral function. My compiler gives me the following error:
integrate1.f90:22.26:
r = integral(-1.0,1.0,EXP,1000);
1
Error: Expected a procedure for argument 'f' at (1)
If I uncomment the usage of EXP on the declaration of the variable r I don't get this error.
So it seems that if I don't use a built-in function I cannot use it as an argument
which is kind of weird, cause "built-in" kind of suggests the function is loaded no matter what.
How can I prevent this error without explicitly using the EXP function? Do I need to use the USE statement to load built-in's? If there is no other way around this, I would be interested to know if this is due to the Fortran specification or a compiler issue?
I am using GNU Fortran (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3.
Example:
MODULE MINTEGRATE
CONTAINS
FUNCTION integral(from,to,f,n)
INTERFACE
FUNCTION f(y); REAL, INTENT(IN) :: y; END FUNCTION
END INTERFACE
REAL :: from,to,integral,width;
INTEGER :: n;
width=ABS(to-from)/n;
integral = 0.0;
DO i=0,n
integral = integral+f(from+width*i)*width;
END DO
END
END
PROGRAM INTEGRATE
USE MINTEGRATE;
!PROCEDURE(EXP), POINTER :: f => EXP; ! using the variable f below works without error
REAL :: r!=EXP(0.0);
r = integral(-1.0,1.0,EXP,1000);
WRITE(*,*) r;
END

"When an intrinsic function is passed as an actual argument to a procedure, its specific name must be used, and when called, its arguments must be scalar. Not all specific intrinsic functions can appear as actual arguments. (For more information, see Intrinsic Functions Not Allowed as Actual Arguments)." From Intel Fortran manual.
You were lucky, because the specific name of the generic exp for single precision real is also exp, but otherwise be careful and pass the right specific function, or write own wrapper calling the generic name. For example, if you wanted default real logarithm, you would have to use alog.
You can inform the compiler that you mean the intrisic function exp by:
intrinsic exp
placed among the declarations in the main program.

Related

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

Scoping rules for variable and functions in contained subroutines

I have a problem understanding why a variable (i) declared in a subroutine is seen in a contained subroutine, but that this is not true for a function (fie) which results in a compilation error. I searched for an answer and also tried to see if I could find something in the Fortran 95 standard but in vain.
I wrote a small example program:
program pgm
call a
end
subroutine a
implicit none
integer :: i
double precision :: fie
i = 7
call b
!write(*,*) fie(9)
contains
subroutine b
double precision :: x
!double precision :: fie
x = i
x = x + fie(i)
write(*,*) x
end subroutine
end subroutine
double precision function fie(ii)
implicit none
integer, intent(in) :: ii
fie = ii
end function
When compiling this with gfortran under cygwin (gfortran 5.4.0) I get the following error message:
$ gfortran aa.f90
aa.f90:20:15:
x = x + fie(i)
1
Error: ‘fie’ at (1) is not a function
When enabling either of the commented lines the program compiles and runs correctly.
I saw a similar error message when using the Intel compiler (Intel Fortran 12.1.7.367, indeed quite old).
It looks like fie has to be made available either in the contained routine or has to be used in the encompassing subroutine, but as said I could not find an answer on the net or in the Fortran 95 standard (or maybe I didn't look for the right words).
Any explanation?
The simplest fix is to use
double precision, external :: fie
the external attribute (also can be specified by the external statement) says: this is a procedure, I am not declaring a local variable.
For the declaration without the external to be interpreted as a function declaration the function reference must be present within the function body. Internal functions don't count. And therefore the compiler created a local double precision variable called fie.
Thank's to IanH for the relevant standard rule (from Fortran 2008 (16.5.1.4p5), but Fortran 95 will have an equivalent):
If an external or dummy procedure with an implicit interface is
accessed via host association, then it shall have the EXTERNAL
attribute in the host scoping unit; if it is invoked as a function in
the inner scoping unit, its type and type parameters shall be
established in the host scoping unit. The type and type parameters of
a function with the EXTERNAL attribute are established in a scoping
unit if that scoping unit explicitly declares them, invokes the
function, accesses the function from a module, or accesses the
function from its host where its type and type parameters are
established.
Of course explicit interfaces (best using modules) are much better than external functions.

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.

Pass kind parameter to subprogram

Is it possible in modern versions of Fortran to pass a kind parameter to a subprogram and to use this to 'cast' variables to this kind? As an example, in the following code I am trying to convert an default integer to an 16-bit integer before printing it.
program mwe
! Could use iso_fortran_env definition of int16, but I am stuck with
! old versions of ifort and gfortran.
! use, intrinsic :: iso_fortran_env, only : int16
implicit none
! 16-bit (short) integer kind.
integer, parameter :: int16 = selected_int_kind(15)
call convert_print(123, int16)
contains
subroutine convert_print(i, ikind)
implicit none
integer, intent(in) :: i
integer, intent(in) :: ikind
print*, int(i, ikind)
end subroutine convert_print
end program mwe
With this example code the Intel Fortran compiler complains that
mwe.f(24): error #6238: An integer constant expression is required in this context. [IKIND]
...
mwe.f(24): error #6683: A kind type parameter must be a compile-time constant [IKIND]
and gfortran complains
'kind' argument of 'int' intrinsic at (1) must be a constant
Using print*, int(i, int16) in place of print*, int(i, ikind) would of course work fine in this case. However, if convert_print were defined in a a module which does not define int16 then this would be useless.
Is there a way of passing a kind parameter as a constant to subprograms?
I have the same problem. I find extremely inconvenient that it is not allowed to pass the kind datatype as an argument to a procedures. In my case, I am writing write a subroutine to just read a matrix from a file and get the object in the data type that I want to. I had to write four different subroutines: ReadMatrix_int8(…), ReadMatrix_int16(…), ReadMatrix_int32(…) and ReadMatrix_int64(…) which are nothing but the same code with one single line different:
integer(kind=xxxx), allocatable, intent(out) :: matrix(:,:)
It would make sense to write only one subroutine and pass xxxx as an argument. If I find any solution I will let you know. But I am afraid that there is no better solution than writing the four subroutines and then writing an interface to create a generic procedure like:
interface ReadMatrix
module procedure ReadMatrix_int8
module procedure ReadMatrix_int16
module procedure ReadMatrix_int32
module procedure ReadMatrix_int64
end interface
As far as I can work out, what I am trying to do is expressly forbidden by the Fortran 2003 standard (PDF, 4.5 MB):
5.1.2.10 PARAMETER attribute
A named constant shall not be referenced unless it has been defined previously in the same statement, defined in a prior statement, or made accessible by use or host association.
Therefore is seems that I need to define a function for each conversion I wish to do, for example:
subroutine print_byte(i)
implicit none
integer, intent(in) :: i
print*, int(i, int8)
end subroutine print_byte
subroutine print_short(i)
implicit none
integer, intent(in) :: i
print*, int(i, int16)
end subroutine print_short
subroutine print_long(i)
implicit none
integer, intent(in) :: i
print*, int(i, int32)
end subroutine print_long
Obviously all of the above will have to be overloaded to accept different kinds of the input argument. This seems like a lot of work to get around not being able to pass a constant, so if someone has a better solution I am keen to see it.
This Intel expert gives an explanation and an elegant solution. I couldn't explain it better. A full cite follows:
"One day while I was wandering the aisles of my local grocery store, a woman beckoned me over to a table and asked if I would like to "try some imported chocolate?" Neatly arrayed on the table were packages of Lindt, Toblerone, and... Ghiradelli? I asked the woman if California had seceded from the Union, as Ghiradelli, despite its Italian name, hails from San Francisco. I suppose that from the vantage point of New Hampshire, California might as well be another country, much as depicted in that famous Saul Steinberg 1976 cover for The New Yorker, "View of the World from 9th Avenue".
(I've been warned that my blogs don't have enough arbitrary links - this should hold 'em for a while.)
Similarly, in Fortran (I'll bet you were wondering when I'd get to that), something can be so near yet seem so far away. A short time ago, I was writing a new module for Intel Visual Fortran to provide declarations for the Win32 Process Status API. This would contain declarations of types and constants as well as interface blocks for the API routines, some of which take arguments of the new type. The natural inclination is to write something like this:
MODULE psapi
TYPE sometype
some component
END TYPE sometype
INTERFACE
FUNCTION newroutine (arg)
INTEGER :: newroutine
TYPE (sometype) :: arg
END FUNCTION newroutine
END INTERFACE
END MODULE psapi
If you did and compiled it, you'd get an error that type sometype is undefined in the declaration of arg. "What? It's not undeclared, I can see it right above in the same module!" Well, yes and no. Yes, it's declared in the module and could be used anywhere in the module, except.. Except in interface blocks!
The problem is that interface blocks are a "window into the external routine" - they essentially duplicate the declarations you would see in the actual external routine, assuming that routine were written in Fortran. As such, they do not "host associate" any symbols from the enclosing scoping unit (the module in this case.)
In Fortran 90 and Fortran 95, the typical solution for this was to create a separate module, say, "psapi_types", containing all of the types and constants to be used, You'd then add a USE statement inside each function, just as you would have to in the hypothetical external routine written in Fortran. (If it were written in Fortran, the Doctor would slap your wrist with a wet punchcard and tell you to make the routine a module procedure, and then you wouldn't need to worry about this nonsense.) So you would end up with something like this:
MODULE psapi
USE psapi_types ! This is for the benefit of users of module psapi
INTERFACE
FUNCTION newroutine (arg)
USE psapi_types
INTEGER :: newroutine
TYPE (sometype) :: arg
...
Those of you who use Intel Visual Fortran know that in fact there's a giant module IFWINTY for this purpose, containing all of the types and constants for the other Win32 APIs. It's messy and inelegant, but that's what you have to do. Until now...
Fortran 2003 attempts to restore some elegance to this sorry situation, but to preserve compatibility with older sources, it couldn't just declare that interface blocks participate in host association. Instead, a new statement was created, IMPORT. IMPORT is allowed to appear in interface blocks only and it tells the compiler to import names visible in the host scope.
IMPORT is placed following any USE statements but before any IMPLICIT statements in an interface body (the FUNCTION or SUBROUTINE declaration). IMPORT can have an optional import-name-list, much like USE. Without one, all entities accessible in the host become visible inside the interface body. With a list, only the named entities are visible.
With IMPORT, my PSAPI module can look like the first example with the following change:
...
FUNCTION newroutine (arg)
IMPORT
INTEGER :: newroutine
TYPE(sometype) :: arg
...
I could, if I wanted to, use:
IMPORT :: sometype
to say that I wanted only that one name imported. Nice and neat and all in one module!
"But why are you telling me this?", you might ask, "That's a Fortran 2003 feature and Intel Fortran doesn't yet do all of Fortran 2003." True enough, but we keep adding more and more F2003 features to the compiler and IMPORT made it in back in August! So if you are keeping reasonbly current, you can now IMPORT to your heart's content and do away with the mess of a separate module for your types and constants.
If you want to know what other F2003 goodies are available to you, just check the Release Notes for each update. A full list of supported F2003 features is in each issue. Collect 'em all!"