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.
Related
Our current solution is a mixed C++ Fortran application in Visual Studio 2013, with approximately 40 projects of each.
Although we can build the solution just fine, we are getting about 6000 warnings - a vast majority of which are LNK4006 warnings, where a function is being "duplicated":
warning LNK4006: _XXXXXXXXXXX#8 already defined in project1.lib(module1.obj); second definition ignored project2.lib(module1.obj)
The common thread is that the functions that are being duplicated are defined in Fortran modules - many of which are just interfaces to C++ functions:
MODULE mINTERFACES
USE ISO_C_BINDING
INTERFACE
INTEGER(4) FUNCTION GetLastErrorCode [C, ALIAS: '_GetLastErrorCode'] (index)
USE ISO_C_BINDING
INTEGER(C_SIZE_T), INTENT(IN) :: index
END FUNCTION GetLastErrorCode
END INTERFACE
END
Since these modules are used across many Fortran projects, each project has an independent version of the interface function - hence the duplication.
This all makes perfect sense, but my question is: can I just ignore the warnings (i.e. exclude them in the project configuration)? I can't see any obvious way to restructure our code to remove the warnings, and I was under the impression that putting these interfaces in a module was good practice...
My thanks to all those who've commented constructively in this thread - but also to #IanH and Steve Lionel who have helped in the Intel forum thread at https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/628995.
In Short
(And this is my own judgement and nobody else's) In this particular case the warnings were superfluous BUT if you disable them you would miss any new warnings which could be important. IMHO this means that you shouldn't disable the warning.
The Long Answer
The warnings were coming from two sources:
A convention had grown up to use a module to contain "global" data, but to access this through "accessor functions" which were defined in the same files as the modules. This meant that when the modules were included in many different projects, the accessor functions were compiled multiple times.
Several of these modules contained C interface blocks (which is good practice), but for functions which returned strings, the paradigm was used as described in Creating a FORTRAN interface to a C function that returns a char*. Although the interface blocks themselves didn't raise a duplication warning, the secondary functions which converted the C pointer to a Fortran string did.
A solution could have been to extract all of these accessor functions and secondary interface routines into separate files and only compile them once BUT this would have taken weeks.
Thanks to #IanH, he pointed out that you could obviate this by defining all of the modules in a separate project, and then (in Visual Studio) just sett all of the projects to to depend on this new "shared modules" project (using Build Dependencies-->Project Dependencies). This now compiles without the warnings; VS's "Entire Solution" search now only finds each routine once; and it probably compiles a lot faster! All in all, a win.
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.
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.
I'm trying to make a Fortran 77 wrapper for C++ code. I have not found information about it.
The idea is to use from functions from a lib that is written in C++ in a Fortran 77 progran.
Does anyone know how to do it?
Thanks!
Lawrence Livermore National Laboratory developed a tool called Babel for integrating software written in multiple languages into a single, cohesive application. If your needs are simple you can probably just put C wrapper on your C++ code and call that from Fortran. However, if your needs are more advanced, it might be worth giving Babel a look.
Calling Fortran from C is easy, C from Fortran potentially tricky, C++ from Fortran may potentially become ... challenging.
I have some notes elsewhere. Those are quite old, but nothing changes very rapidly in this sort of area, so there may still be some useful pointers there.
Unfortunately, there's no really standard way of doing this, and different compilers may do it slightly different ways. Having said that, it's only when passing strings that you're likely to run into major headaches. The resource above points to a library called CNF which aims to help here, mostly by providing C macros to sugar the bookkeeping.
The short version, however is this:
Floats and integers are generally easy -- an integer is an integer, more or less.
Strings are hard (because Fortrans quite often store these as structures, and very rarely as C-style null-terminated arrays).
C is call-by-value, Fortran call-by-reference, which means that Fortran functions are always pointer-to-value, from C's point of view.
You have to care about how your compiler generates symbols: compilers often turn C/Fortran symbol foo into _foo or foo_ or some other variant (see the compiler docs).
C tends not to have much of a runtime, C++ and Fortran do, and so you have to remember to link that in somehow, at link time.
That's the majority of what you need to know. The rest is annoying detail, and making friends with your compiler and linker docs. You'll end up knowing more about linkers than you probably wanted to.
I have some numeric code that I need to convert to C or C++. I tried using f2c, but it won't work on the Fortran code. f2c complains because the code uses C style preprocessor directives (#include).
The code's readme states that it is Fortran77, that works with the fort77 linker, that would expand those includes.
Does anyone know how to successfully convert this code?
My last resort is to write a simple preprocessor to expand those includes and then feed the code to f2c.
Note: I´m working in a Windows/Visual C++ environment here, so any gcc shenanigans would probably be more trouble than they are worth...
I worked in an engineering research group for many years. We never had good luck doing automated conversions from Fortran to C. The code was not particularly understandable and it was hard to maintain. Our best luck was using the Fortran code as a template for the algorithm and doing a re-implementation for anything that we expected to continue using. Alternatively, you could update the Fortran to use more modern Fortran constructs and get a lot of the same value that you would get from moving to C/C++. We also had some success calling Fortran routines from C, although the calling convention differences sometimes made things difficult.
This might be is going out a bit on a limb, but have you considered that since perhaps you're using C-style includes, you could actually run the C preprocessor on the file in order to include those files? Then, you could take that output and run it through f2c.
(I am not an expert on the matter. Please downvote this if appropriate.)
You might get away with manually converting the
#include "whatsit.f90"
to
INCLUDE 'whatsit.f90'
and then attempting the f2c conversion again.
Have you no C pre-processor? On Unix, there might be a separate program, cpp, that would take the Fortran with #include directives and convert that into Fortran without #include directives. Alternatively, you could rename the source from xyz.f77 (xyz.f) to xyz.c, then run the C compiler in 'pre-processor only' mode and capture the output as the new input to the f2c program. You might have to worry about the options that eliminate #line directives in the output, etc, or you might be better off running the output through a simple filter (sed or perl spring to mind).