How "expensive" is it to call Fortran from C++? - c++

I'm writting a program in C++ that calls some functions I had written in Fortran. I was going to test a very basic example in which I call a function called toRadians from the C++ code:
real function toRadian(degree)
implicit none
real, intent(in) :: degree
real :: radians
radians = (degree*PI)/180
return
end function toRadian
And so I wonder, is this "worth it"? When I finish the whole thing that function will be called within Fortran where the bulk of the computations will be done, but doing this basic example got me thinking about if, for a simple computation like this, is calling the Fortran function more expensive than just having that function in C++?
Sorry for my ignorance I'm not very sure about how the linking between these compiled codes works. (I'm also very new with Fortran so if you want to make any remark about the previous function please go ahead).
Thanks for your time and have a nice day.

Calling a Fortran function is as cheap as calling another C++ function. Usually.
The problem is the compatibility between the two languages. The best way to start this in Fortran is to use iso_c_binding so that the function has a C calling convention.
Then the other issue is that both languages require their own runtime libraries, and there are no linker flag to use both. So the usual practice is to create a shared library for the Fortran code and link it against the C++ application (and vice-versa when it's calling C++ from Fortran).

Related

Is there any way to do argument-checking in an elemental function?

Example
Suppose I want to write an elemental function that checks its arguments, as in the following toy example:
elemental real function square_root( x )
real, intent(IN) :: x
if (x<0) then
print *, "Error in square_root(): the variable x must be non-negative."
stop 1
endif
square_root = sqrt(x)
end function square_root
Motivation
Marking a procedure as elemental allows a flexible syntax: I can call it with a scalar or with a multi-dimensional array with no change in calling syntax. This is awesome.
Checking argument values is generally a good practice and has helped me greatly in the past.
Difficulty
This example would not compile because elemental procedures must also be pure procedures, and neither I/O nor program terminations are permitted in pure procedures.
It appears that I can do either one of the following, but not both:
Make a function check its inputs and throw some kind of error/exception
Mark a function as elemental
Question
Is there any way to get the flexible syntax provided by elemental while also checking argument values?
I'm happy to use features of newer Fortran standards and/or invoke polymorphism (e.g. via an interface) if necessary/possible, though I hope there's an easier way!
If you wish to avoid signalling errors or exceptional situations in the arguments (for a subroutine) or function result (for a function)1 then there are options:
from Fortran 2008 elemental procedures need not be pure;
from Fortran 2018 error termination prompted by an error stop statement may commence in a pure subprogram2.
An elemental function which is not pure may be specified with the impure prefix:
impure elemental function can_io_stdout(x)
..
print *, "Hello!"
end function
For Fortran 2018 (to be published):
elemental function can_terminate(x)
..
error stop "Termination from a pure function"
end function
1 For example, one may choose to return a NaN in the case of the square root of a real.
2 As IanH notes, error termination may come about in pure procedures by means other than error stop even in earlier language revisions.

Is It Necessary to declare the Type of User-Defined Functions in ANY Calling Routine?

I use the Intel Visual Fortran. According to Chapmann's book, declaration of function type in the routine that calls it, is NECESSARY. But look at this piece of code,
module mod
implicit none
contains
function fcn ( i )
implicit none
integer :: fcn
integer, intent (in) :: i
fcn = i + 1
end function
end module
program prog
use mod
implicit none
print *, fcn ( 3 )
end program
It runs without that declaration in the calling routine (here prog) and actually when I define its type (I mean function type) in the program prog or any other unit, it bears this error,
error #6401: The attributes of this name conflict with those made accessible by a USE statement. [FCN] Source1.f90 15
What is my fault? or if I am right, How can it be justified?
You must be working with a very old copy of Chapman's book, or possibly misinterpreting what it says. Certainly a calling routine must know the type of a called function, and in Fortran-before-90 it was the programmer's responsibility to ensure that the calling function had that information.
However, since the 90 standard and the introduction of modules there are other, and better, ways to provide information about the called function to the calling routine. One of those ways is to put the called functions into a module and to use-associate the module. When your program follows this approach the compiler takes care of matters. This is precisely what your code has done and it is not only correct, it is a good approach, in line with modern Fortran practice.
association is Fortran-standard-speak for the way(s) in which names (such as fcn) become associated with entities, such as the function called fcn. use-association is the way implemented by writing use module in a program unit, thereby making all the names in module available to the unit which uses module. A simple use statement makes all the entities in the module known under their module-defined names. The use statement can be modified by an only clause, which means that only some module entities are made available. Individual module entities can be renamed in a use statement, thereby associating a different name with the module entity.
The error message you get if you include a (re-)declaration of the called function's type in the calling routine arises because the compiler will only permit one declaration of the called function's type.

Pass complex numbers to and from a DLL in LabVIEW

I am trying to interface this C++ code -- which implements functions necessary to calculate a Voigt line shape -- with LabVIEW (I'm currently running LV2009). I successfully compiled the code into a DLL, and I set up the Call Library Function Node to point to the DLL. However, the function expects a vector of type complex double and returns a vector of type complex double. Complex double is not, however, one of my choices for data type when setting up the function prototype.
Unfortunately, I do not speak C/C++, so I don't have any idea how I would go about modifying the code to get and return real doubles only. I have compiled the code into a MEX file to use with MATLAB, and pass complex numbers in and out with no problem, so I know the code works.
Is there a way to trick LabVIEW 2009 into passing complex numbers in and out of DLL functions? If not, will I gain this ability if I upgrade to the newest release? If not, is there a good basic guide to C++ that will teach me how to modify the function to accept and return the real and imaginary parts as separate vectors?
LabVIEW doesn't allow interfacing with C++ code, only C (or if it's C++, it has to have the extern "C" declaration and use Plain Old Types).
I see that your library has C wrappers, but they use the new C99 complex type, which LabVIEW doesn't understand.
However LabVIEW can pass complex data type to a function, to see how it's done open the example named "Call DLL.vi" and select complex data-type to see function prototype and VI. Your chance might be that the C99 complex has the same binary representation than the LabVIEW one. I didn't dig for the info, but it might be very possible.
If it's the case, go to church and be grateful to your Lord, and use the C wrapper to interface to it.
If it's not, find a tutorial about making a DLL for your compiler, it's not difficult, just takes time. The DLL will take two double for each complex, and make the appropriate call to the real function.

Passing an internal procedure as argument

I want to solve a differential equation lots of times for different parameters. It is more complicated than this, but for the sake of clarity let's say the ODE is y'(x) = (y+a)*x with y(0) = 0 and I want y(1). I picked the dverk algorithm from netlib for solving the ODE and it expects the function on the right hand side to be of a certain form. Now what I did with the Intel Fortran compiler is the following (simplified):
subroutine f(x,a,ans)
implicite none
double precision f,a,ans,y,tol,c(24),w(9)
...
call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)
...
contains
subroutine faux(n,xx,yy,yprime)
implicite none
integer n
double precision xx,yy(n),yprime(n)
yprime(1) = (yy(1)+a)*xx
end subroutine faux
end subroutine f
This works just fine with ifort, the sub-subroutine faux sees the parameter a and everything works as expected. But I'd like the code to be compatible with gfortran, and with this compiler I get the following error message:
Error: Internal procedure 'faux' is not allowed as an actual argument at (1)
I need to have the faux routine inside f, or else I don't know how to tell it the value of a, because I can't change the list of parameters, since this is what the dverk routine expects.
I would like to keep the dverk routine and understand how to solve this specific problem without a workaround, since I feel it will become important again when I need to integrate a parameterized function with different integrators.
You could put this all in a module, and make a a global module variable. Make faux a module procedure. That way, it has access to a.
module ode_module
double precision::a
contains
subroutine f(x,a,ans)
implicit none
double precision f,ans,y,tol,c(24),w(9)
call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)
end subroutine
subroutine faux(n,xx,yy,yprime)
implicite none
integer n
double precision xx,yy(n),yprime(n)
yprime(1) = (yy(1)+a)*xx
end subroutine faux
end module
You can check here which compilers support this F2008 feature:
http://fortranwiki.org/fortran/show/Fortran+2008+status
On that page, search for "Internal procedure as an actual argument" .
Passing an internal procedure is allowed by Fortran 2008. That means that your code is correct Fortran and just a more recent compiler is needed.
At the time when this question was posted the support for that in existing compilers was patchy. Some did support it, some did not. This changed considerably and at the time of writing this revision of the answer one can normally use it without needing to think about compiler support any more.
You are not limited to sharing the data in a module. You just have to make sure, that the containing procedure is still running. It is not possible to save the pointer and make a so called 'closure' known from LISP and many modern languages. In languages like Fortran or C the enclosing environment for future calls is not saved and pointers to internal functions become invalid.
The advantage of internal procedure over module procedure is that you can share the data without sharing it in the whole module.
It works well will reasonably old versions of GCC (gfortran), Intel Fortran and Cray Fortran (personally tested) and possibly others. I remember not being able to compile by PGI and Oracle Fortran. As shown by Daniel, it can be checked at http://fortranwiki.org/fortran/show/Fortran+2008+status (search Internal procedure as an actual argument). The most recent version of this table is periodically published in ACM SIGPLAN Fortran Forum.
There is some interesting info in this article https://stevelionel.com/drfortran/2009/09/02/doctor-fortran-in-think-thank-thunk/
Be aware that the implementation of this feature normally requires executable stack due to the use of trampolines. One does not normally think about that but if the OS forbids executable stack, the executable might fail (there were issues in initial versions of Windows Subsystem for Linux, for example).

Use function inside subroutine in FORTRAN77

I am updating legacy code and I need to use a simple mathematical function inside a subroutine. I cannot figure out how to do this. I have a function that works when called from a test program. What do I need to do differently for a subroutine?
example:
subroutine foo(i,j,k)
i = bar(j,k)
stuff = otherstuff
return
end
other info:
bar is an erf approximation.
I am using the PGF90 compiler.
I am new to FORTRAN from C.
thanks!
Basically, calling from a program or a subroutine shouldn't differ. Does the code really look like this, without any declarations? This means all variables will have implicit types: variables with names starting with the letters i-n will be integer, all others real; this also holds for function return values. The code you show, tries to assign a real (bar()) to an integer (i).
If you're writing new code, always start programs and procedures with IMPLICIT NONE. This forces you to explicitly include type declarations for all variables and function return values, greatly reducing errors.