Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Converting FORTRAN 77/90 to C++

Bernard
Valued Contributor I
5,364 Views

Hi all,

I asked this question on "Code Modernization" forum, but I did not received any answer hence I created a new thread here on this forum.

The first question:

I found medium size ~10K loc of  FORTRAN 77 source code which describes  complete computational flight dynamics simulation. I would like to convert this code which exists only in printed form to C++ version in order to use it in my missile simulation open source project.

 After browsing through the sources I realized that, subroutines pass information between themselves with the help of COMMON blocks only.  I would like to ask you what will be the best approach for the code conversion?  My biggest problem is related to massive usage of COMMON blocks which will imply usage of dedicated namespace to host those global variables extracted from the COMMON blocks. The other option more secure is to put all global variables from the common block to anonymous namespace which is visible only from the single translation unit, but this approach will force me to write all classes in single file.

The second question:

This question is related to code conversion from FORTRAN 90 repository to C++.

I am thinking about 3 approaches:

1) Translation of FORTRAN 90 module to single C++ translation unit in its own namespace with FORTRAN subroutines converted to C++ global(namespace functions) and module globals which can be represented as a members of anonymous namespace.

2) Trying to create simple OOP design by for example converting FORTRAN subroutine into simple C++ class where subroutine's output argument(s)  can be represented as class member variable(s). One of the problem will be a large number of  some subroutine's arguments passed to it, additional problem will be issue of global variables representation in C++, but I think this can be handled by using named namespace solely dedicated to globals.

3) Use translation tool like f2c and manually convert from C version to C++, which btw I already did while porting NRLMSISE_00 atmosphere model to C++.

Thank you in advance.

 

 

0 Kudos
1 Solution
FortranFan
Honored Contributor II
5,365 Views

ilyapolak wrote:

.. what will be the best approach for the code conversion? ..

What is your target platform and toolsets, etc.?  If a modern Fortran compiler such as Intel Fortran is available there, my advice would be not to convert to C++, instead keep in Fortran.

If "massive usage of COMMON blocks which will imply usage of dedicated namespace to host those global variables extracted from the COMMON blocks" is truly a problem, look at Fortran facilities starting with Fortran 90, past Fortran 95, Fortran 2003, and then Fortran 2008 (and now Fortran 2015) that are being supported by Intel Fortran.

Some of the features will involve modules (for some namespace type of organization, information hiding, etc)., derived types with allocatable components (and with type-pound procedures toward OO design if that is of interest) which effectively let you design "classes" in Fortran, enhanced interoperability with C (thus C++ via "extern" C), and so forth.

Given your use case of "missile simulation open source project" which suggests heavy computations and the fact that you have an existing source code base in FORTRAN, you would be able to retain all the advantages of Fortran especially with array handling while gaining any other data management aspect you may be seeking with C++ by adopting a "code modernization" approach that moves from FORTRAN 77 to "modern" Fortran.  A literature example is https://scholar.google.com/scholar?q=http://dx.doi.org/10.1145/2532352.2532356.

You may already know about Dr Fortran blog: https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world including the footnote on Scientific Software Design: The Object-Oriented Way by Damian Rouson. 

View solution in original post

0 Kudos
11 Replies
FortranFan
Honored Contributor II
5,366 Views

ilyapolak wrote:

.. what will be the best approach for the code conversion? ..

What is your target platform and toolsets, etc.?  If a modern Fortran compiler such as Intel Fortran is available there, my advice would be not to convert to C++, instead keep in Fortran.

If "massive usage of COMMON blocks which will imply usage of dedicated namespace to host those global variables extracted from the COMMON blocks" is truly a problem, look at Fortran facilities starting with Fortran 90, past Fortran 95, Fortran 2003, and then Fortran 2008 (and now Fortran 2015) that are being supported by Intel Fortran.

Some of the features will involve modules (for some namespace type of organization, information hiding, etc)., derived types with allocatable components (and with type-pound procedures toward OO design if that is of interest) which effectively let you design "classes" in Fortran, enhanced interoperability with C (thus C++ via "extern" C), and so forth.

Given your use case of "missile simulation open source project" which suggests heavy computations and the fact that you have an existing source code base in FORTRAN, you would be able to retain all the advantages of Fortran especially with array handling while gaining any other data management aspect you may be seeking with C++ by adopting a "code modernization" approach that moves from FORTRAN 77 to "modern" Fortran.  A literature example is https://scholar.google.com/scholar?q=http://dx.doi.org/10.1145/2532352.2532356.

You may already know about Dr Fortran blog: https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world including the footnote on Scientific Software Design: The Object-Oriented Way by Damian Rouson. 

0 Kudos
Bernard
Valued Contributor I
5,365 Views

Hi FortranFan,

Thank you for your answer.

>>>What is your target platform and toolsets, etc.?  If a modern Fortran compiler such as Intel Fortran is available there, my advice would be not to convert to C++, instead keep in Fortran.>>>

I am using VS 2013 Community Edition with integrated Intel Parallel Studio XE  2013 so I have all the needed tools to do the job. My problem is that the Fortran source code exists only in printed form as a scans from the book (I can not find the source code online). Additional problem is an extensive usage of COMMON blocks by that code so even if I had the .f files available I would be forced to use extensively global structures (C or C++) from the calling modules which are written in C++ which is not a good solution as you know.

I must admit , that in this project I rely extensively on famous FORTRAN libraries for the high quality computation of numerical quadrature (QUADPACK), Fast Fourier Transform (FFTPACK), Ordinary Differential Equations (RKSUITE) and as for now I praise the quality of the code and interoperatibility between FORTRAN 77 and C++11. For example I pass lambdas integrands to RKSUITE subroutines and it works flawlessly. 

 >>>look at Fortran facilities starting with Fortran 90, past Fortran 95, Fortran 2003, and then Fortran 2008 (and now Fortran 2015) that are being supported by Intel Fortran.>>>

 I think about the modernization to FORTRAN 90 by removing common blocks and wrapping existing subroutines in modules with public and private variables, next step I will write simple wrappers to call those subroutines as I did with numerical code. This is the strategy to deal with legacy F77 code base which does not pass to its subroutines any arguments at all . I think that in case of FORTRAN 90 I can write C++ wrappers which will call the module subroutines and it will be enough. I will leave OOD to C++ only which will hide the lower FORTRAN layer. 

 

0 Kudos
FortranFan
Honored Contributor II
5,365 Views

iliyapolak wrote:

.. My problem is that the Fortran source code exists only in printed form as a scans from the book (I can not find the source code online). ..

Have you tried different OCR technology tools and seen if any of them are able to convert your scanned pages from the book into text form to create source code files?  Not too long ago I had used this tool - http://www.abbyy.com/finereader/about-ocr/what-is-ocr/.  It had worked quite well; I only had to make minor corrections.  Albeit the listing, which was in a thesis, was only about 5-6 pages long.

 

0 Kudos
Bernard
Valued Contributor I
5,365 Views

Hi,

Thanks for providing the pointers on how to perform OCR conversion. I will definitely give it try. Before that I tried to copy code listing from the e-book in order to create FORTRAN files, but formatting job was very tedious so I stopped doing this. Anyway I will not directly use that code in my project and only need it as a "foundation layer" of my solution.

 

0 Kudos
Bernard
Valued Contributor I
5,365 Views

Can anyone shed some light on how to effectively convert COMMON blocks to global C structures? Has anyone ever dealt with such a problem?

0 Kudos
TimP
Honored Contributor III
5,365 Views

I see several tutorials on line cribbing from each other, a majority taking the viewpoint of f2c and g77.  More modern texts explain the Fortran iso c interoperability for common blocks. 

0 Kudos
FortranFan
Honored Contributor II
5,365 Views

iliyapolak wrote:

Can anyone shed some light on how to effectively convert COMMON blocks to global C structures? Has anyone ever dealt with such a problem?

What exactly do you mean by "convert"?  Technically a COMMON block can interoperate with a C struct and the process can be portable and the reliable if each object in the COMMON is itself interoperable per Fortran standard.  So C/C++ code can call FORTRAN code (F77-like) and exchange data via global C structs.  In my mind, the "convert" aspect will be mainly to "clean up" FORTRAN code to make use of standard C interoperability facilities.  Here's a simple example, here the Fortran code is in modern free-form style, but the same would work with fixed-form too:

module m

   use, intrinsic :: iso_c_binding, only : c_int, c_double
   use, intrinsic :: iso_fortran_env, only : output_unit

   implicit none

   private

   integer(c_int) :: i
   real(c_double) :: r

   common /glbdat/ r, i
   bind(C, name="glbdat") /glbdat/

contains

   subroutine foo() bind(C, name="foo")

      write(output_unit, fmt='(*(g0))') "In foo, upon entry:"
      write(output_unit, fmt='(*(g0))') "r = ", r
      write(output_unit, fmt='(*(g0))') "i = ", i

      r = real( -999.0, kind=kind(r))
      i = int( 42, kind=kind(i))

      !..
      return

   end subroutine foo

end module m
#include <stdio.h>

extern void foo( void );

typedef struct {
   double r;
   int i;
} str_c;

str_c glbdat;

int main() {

   glbdat.r = 0.0;
   glbdat.i = 0;

   foo();

   printf("foo returns:\n r=%f\n i=%d\n", glbdat.r, glbdat.i);

   return 0;

}

Upon execution,

In foo, upon entry:
r = 0.0000000000000000
i = 0
foo returns:
 r=-999.000000
 i=42

Going by above, one can take legacy FORTRAN code, "touch it up" at a high level to introduce standard C interoperability features (data types of C_DOUBLE, BIND attributes, etc.) and keep the important stuff i.e., computational algorithms, etc. pretty much as-is, and have all the code interoperate with C/C++ applications.  This is what I would mean by "convert" - is that what you're asking?

0 Kudos
Bernard
Valued Contributor I
5,365 Views

@Fortran Fan,

Thank you for your post. That is exactly what I wanted to ask, btw I started to learn FORTRAN recently mainly FORTRAN 77.

By using word "convert" I meant "translation" from COMMON block to C structure. Usually up to now I did not have an opportunity to "deal" directly with COMMON blocks because they were used internally to pass data between the subroutines. 

>>>Going by above, one can take legacy FORTRAN code, "touch it up" at a high level to introduce standard C interoperability features (data types of C_DOUBLE, BIND attributes, etc.) and keep the important stuff i.e., computational algorithms,>>>

 That is usually what I am doing when I rely on FORTRAN algorithms to do the job. Only sometimes for educational purpose I would translate few algorithms to C++ (mainly those from LAPACK). Only in one case that one which I described in my earlier post I think that I will port FORTRAN code or put it better I will build my own solution  upon the FORTRAN source.

 >>>Technically a COMMON block can interoperate with a C struct and the process can be portable.>>>

 I did not look at assembly level representation of COMMON block, but I am pretty sure that it is probably laid out as C structure, so technically there is interoperability between those language constructs.

 

 

0 Kudos
Bernard
Valued Contributor I
5,365 Views

@Tim,

Yes I did the search on the Internet, but there were simple examples and in my case I have large COMMON blocks  with up to 14-15  1D and 2D arrays(flight dynamics code) so I wanted to ask my question here on IDZ first.

I will use f2c at some point.

0 Kudos
FortranFan
Honored Contributor II
5,365 Views

iliyapolak wrote:

.. btw I started to learn FORTRAN recently mainly FORTRAN 77 ..

Making "recently" the operative word, I suggest reviewing "modern Fortran" first, say starting with Modern Fortran Explained in the Dr Fortran blog https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world and moving on to other titles.  There is some "free" stuff available online also such as

http://www.egr.unlv.edu/~ed/fortran (find a downloadable PDF file here) 

and 

http://fortranwiki.org/fortran/show/Tutorials 

and 

videos on YouTube e.g., https://youtu.be/gSJhfnhs598 (there are many more videos, just search for modern Fortran) 

Once you have a good understanding of "modern Fortran" (which you will gain very quickly, in a matter of less than a few hours given your expertise in languages such as C++), you can then try to pick up just enough FORTRAN 77 simply to be able to navigate through or "work with" legacy code.  I would advice against starting with FORTRAN 77 in today's age since I have seen it adversely bias the reader's opinion and views on Fortran, on what's possible, and if at all any coding is pursued, the coding styles and idioms that are followed.

As mentioned earlier, Intel Fortran supports all of Fortran 2003 standard revision (other than perhaps standard support for international character sets? not sure), a large fraction of Fortran 2008, and a significant amount of Fortran 2015 i.e., all the features toward enhanced support for interoperability with C which will be of interest to you.

0 Kudos
Bernard
Valued Contributor I
5,365 Views

 I started my learning process of FORTRAN from the version "77" mainly because of netlib repository which has a large code base written in FORTRAN 77. Actually I have two books one for FORTRAN 77 and second for FORTRAN 90 so I quite often use them as a reference material.

Your advise seems very rational to me and I think that starting from modern versions of FORTRAN shall be no to so complicated mainly because of knowledge of C++.

 Thank you for your help. I really appreciate it.

P.s  

  Regarding that project where source code was in printed form I have recently found better repository called " Digital Datcom"  with the source code available as a .f files so I will built my solution the proper way by wrapping C++ around lower level FORTRAN funcrionality.

0 Kudos
Reply