• 16Jul
    Categories: development Comments: 2

    Hi there!

    “Wow” you may think. Are people still using the Fortran programming language?? I know, I was shocked too. But, apparently, Fortran is very much used within large mathematical problems / scientific work, and can therefor be seen within HPC communities. As I’m currently an IT-consultant which is working within this kind of environment, I’ve got some hands-on experience with C and Fortran.

    One of the applications I’m working on is a mix of Fortran and some C. Since I’m a software developer at heart and I have almost never ever touched Fortran, I prefer C code over Fortran. However, rewriting all the Fortran code is not an option as it is very time consuming, and that one should respect the saying “if it works, don’t change it”. But, one of my tasks is to try to optimize the code, and running the whole application through the GNU gprof tools reveals some bad code. I’m not going to dive into exactly what it was, but to solve it I wanted to use C instead of Fortran. So, then I discovered that I could simply reimplement the subroutine (basically just a function in C terms) in C and append a “_” at the end of the function name.

    This fortran program for example calls the C function “my_c_func”:

    program testme
        implicit none
        integer*4 dx, dy, direction, i, j
        !real*4 dimension(:,:), allocateable :: data
        real*4 data(5,5)
        dx = 5
        dy = 5
        direction = 1
     
        do i = 1, dy
          do j = 1, dx
              data(i,j) = (i+j)**2
          end do
        end do
     
        ! call our C library function
        call my_func(dx, dy, data, direction)
     
        write (*,*) "Hello world!"
    end program testme

    And then this is the C function “my_c_func”:

    #include <stdlib.h>
    #include <stdio.h>
     
    void my_func_(int *dx, int *dy, float *data, int *direction)
    {
      int i,j;
     
      printf("You are now inside the C function.\nAwesome, right?\n\n");
      printf("dx=%d, dy=%d, direction=%d\n", *dx, *dy, *direction);
     
      printf("Lets go through our data matrix..\n");
     
      for(i=0;i<(*dy);i++)
      {
          for(j=0;j<(*dx);j++)
          {
              printf("data[%d][%d] = %.2f\n", i+1, j+1, data[(*dy)*i+j]);
          }
      }
    }

    Lets call the fortran file for test.f90 and the C file for c_lib.c, and lets create a Scons file instead of a Makefile to compile this example. Also, I have only tested this with the “gfortran v4.2″ compiler, and gcc v4.3.3.

    import os
    env = Environment( env = os.environ )
     
    env.Program( target = "program1", source = ["for.f90", "c_lib.c"])

    And now for the grand finally. Type scons, and the compilation should run. There should now be a binary named “program1″. Run it, and have a closer look at the info.

    So, to summarize, the only requirement for Fortran files to call C functions is that the respective C function has a underscore right after its function name. Also, before the fortran compilation, the C file containing the function needs to be compiled into a object file and be reachable.