Fortran with MPI error - fortran

I am working on Fortran code with MPI and introducing the following MPI command
call MPI_Gather(nlocal,1,MPI_INTEGER,counts,1,MPI_INTEGER,0&
&,comm_cart,ierror)
with in a particular subroutine gives following error:
This name does not have a type, and must have an explicit type. [MPI_INTEGER]
I understand that the compiler does not recognize the MPI part of this code. However, all other related variables such as nlocal, counts and comm_cart are recognized except the Fortran MPI data type MPI_INTEGER. Can someone throw light, where I am doing wrong?
Note: The compiler is Intel compiler

You must tell the compiler about the MPI stuff (mainly variables).
The modern way is introducing
use mpi
in every scope.
In the old days it was also done using
include "mpif.h"
but that has several disadvantages. Namely, because it is compatible with FORTRAN 77, it does not introduce explicit interfaces for any MPI subroutines and therefore the error checking is less thorough than with use mpi. The modern method will help you more in keeping your code correct.
On the other hand, if you use use mpi the module mpi must be compiled with the same compiler (sometimes even with the same version) which you use to compile your program.

Related

Forcing strong type checking with Fortran functions at compile time

I'm helping renovate a legacy code base in Fortran which has interface definitions for functions / subroutines.
The issue I am facing is that some of those interfaces are out of sync with the actual function definitions and the compiler (silverfrost) is not catching these at compile time. This leads to run time errors.
Ignoring the specific compiler I am using for now, does Fortran have a method for handling this without repeating the function definition? For example, in C#, Java etc. I can declare a function and call it from elsewhere in the project and the compiler makes sure the caller and target function are compatible.
Does GNU Fortran or the Intel Fortran compiler make this any less fragile?
If you put procedures in MODULEs and USE the MODULEs, the compiler will check that procedures are called with the correct arguments.

C/FORTRAN set double underflow to zero

I have a legacy FORTRAN project with some very intense computations. I want this math code to be accessed by C/C++ code, so I built a FORTRAN dll, imported it in C/C++ and started to receive floating-point underflows from my FORTRAN dll.
At the same time, the FORTRAN dll code executes fine if I call it from a FORTRAN application.
Finally, I found out that the compiler I use (it's an FTN 95 integrated into VS2013) has an option (/UNDERFLOW). If this flag is not specified, all underflows are converted to zeroes by default. That happens in the FORTRAN app. When I use C code to execute methods from this dll, I receive underflows.
So, the question is: is there any way to force VC++ compiler to convert underflows to zeroes?
P.S.: yes, I understand that it is stupid to rely on a code that throws floating-point exceptions all the way. However, this code is old and at this point it is impossible to completely rewrite it using up-to-date techniques.
So, problem was with FTN95 compiler. The mentioned above flag (/UNDERFLOW) seems to be useful only when one build an application. The effect of this flag is neglected when the target output is DLL. Instead of this I found a compiler directive that is accessed through call to MASK_UNDERFLOW#() subroutine. After inserting an explicit call to this subroutine in the FORTRAN function that was throwing underflows and recompiling the DLL, I've managed to successfully launch a C program and perform necessary computations using functions from FORTRAN dlls. Also, an fp:/except- VC++ compiler flag was used to ensure that no other underflows will affect execution of C program.

Difference in output when f77 code compiled with ifort & gfortran

I need some pointers to solve a problem that I can describe only in a limited way. I got a code written in f77 from a senior scientist. I can't give the code on a public forum for ownership issues. It's not big (750 lines) but given implicit declarations and gotos statements, it is very unreadable. Hence I am having trouble finding out the source of error. Here is the problem:
When I compile the code with ifort, it runs fine and gives me sensible numbers but when I compile it with gfortran, it compiles fine but does not give me the right answer. The code is a numerical root finder for a complex plasma physics problem. The ifort compiled version finds the root but the gfortran compiled version fails to find the root.
Any ideas on how to proceed looking for a solution? I will update the question to reflect the actual problem when I find one.
Some things to investigate, not necessarily in the order I would try them:
Use your compiler(s) to check everything that your compiler(s) are capable of checking including and especially array-bounds (for run-time confidence) and subroutine argument matching.
Use of uninitialised variables.
The kinds of real, complex and integer variables; the compilers (or your compilation options) may default to different kinds.
Common blocks, equivalences, entry, ... other now deprecated or obsolete features.
Finally, perhaps not a matter for immediate investigation but something you ought to do sooner (right choice) or later (wrong choice), make the effort to declare IMPLICIT NONE in all scopes and to write explicit declarations for all entities.

interface for fortran 77 in 95 program

I am quite new to fortran, and only write in fortran 95 and 2003. Now I have a program that is mainly written in 95, but it is completely in fortran 77 syntax and also contains some 77 functins.
Now I need the functionality in another program, but don't want to rewrite the whole program. My idea was to replace
program my_prog
with
module my_mod
subroutine my_prog()
The replacement does not seem to work. The compiler states, that the syntax from
subroutine my_prog()
is wrong. Does anyone have some experiance with the topic, or knows if it is even possible to implement the code without rewriting it?
The correct syntax for a module subroutine sub is
module name_of_the_module
use whatever
implicit none
!some variables and interfaces
contains
subroutine sub
!here is the code of your subroutine
end subroutine sub
end module name_of_the_module
Otherwise, it should be noted, that you can call the code in FORTRAN 77 from a newer code. It is (with some exceptions) still a valid Fortran 2008 code, just in an old style. The only exception is you cannot mix free and fixed source format in one source file. That may also be your problem.
The best thing to do is to make the old functions and subroutines to conform also to the free source format (see "intersection format" here) and place them into a module as I showed above.
Merely packaging a subroutine into a module may work in some cases but it may not work in others.
There are some features of Fortran 77 that have been declared obsolete now. You have several options.
Compiler switches: Many compilers provide compile time switches to compile legacy code. This depends on compiler to compiler and may change in the future
Use tools: There are tools that people have written that allow you to convert f77 code into f90/95. For this see:
http://www.atmos.illinois.edu/courses/atms391-sp11/Fortran-converters.html
Update source manually: Some people have used floating point variables in do-loops. This may be hard using automatic tools discussed above. In such cases where legacy statements like (goto) are present you may have to work manually. For this see the following link:
http://www.cisl.ucar.edu/zine/96/fall/articles/3.f90.conversion.html
http://iprc.soest.hawaii.edu/users/furue/improve-fortran.html
In the long run it will pay that you go through the code manually line-by-line and make the changes yourself. This is the most portable solution.

What is a handy way to make a novel Fortran library callable from C

I'm working on a small Fortran library (novel code) which is being called from several C/C++ applications. The library is of such kind when almost every subroutine could be separately called from application. So I need to provide C interface for those subroutines.
I can use modules, which are very comfortable by itself. But then I need either to decode manually module name mangling (which isn't very hard for gfortran, but looks bad) or use bind(C,name="some_name") clause. The last one leads to compiler warnings like subroutine parameter wasn't explicitly made interoperable (so compiler wants me to replace double precision with real(kind=C_DOUBLE), for example). And I should in this case to replace almost every variable in a library with such ugly declarations, which results to bad-reading code.
I can use subroutines, when every file in a library consists of several subroutines (this is the way that I do now). Explicitly interfaces are fed between them with interface ... include "otherfile_h.f90" ... end interface which isn't very comfortable. Name mangling is rather simple in this case, and library subroutines could be easily directly called from C.
The approach that I use (bullet #2) requires more typing and it is error prone because of duplicating definitions in source/header files. Is there a better way to keep sources clear and readable with smart C interface?
The modern way to mix Fortran and C is to use Fortran's ISO C Binding. This will make your code portable since the ISO C Binding is part of the language standard. Manually figuring out the name mangling is compiler specific and might not work on another compiler. "Double precision" is not considered a best practice declaration for modern Fortran (see, e.g., Extended double precision and http://fortranwiki.org/fortran/show/Modernizing+Old+Fortran). The modern way is to use "real (kind=XYZ)". The concept of the language is that typically the programmer uses SELECTED_REAL_KIND intrinsic function to define an constant (e.g., MyDouble) for the precision that they need. If the precision that you need is C_DOUBLE, then it is very appropriate Fortran to use that kind value. This is not an ugly declaration. (I don't understand your bullet #2.)