Skip to content
Published February 18, 2022

It is possible to compile a dynamic library from a Fortran source code. The procedure differs slightly from one used to combine C++/C and Python. In fact, the numpy module provides an instrument f2py to create a library from fortran source code. This is one of the most useful resources about this subject.

Below I show an example. First, I write a function in fortran which performs a simple numerical integration using the Euler method.

function value (step)
      real*8 step
      real*8 res, value
      integer intpart
      integer n, i
      REAL*8, PARAMETER :: Pi = 3.1415927
      remainder = mod (Pi / 2.0,  step)
      n = FLOOR(Pi / 2.0 / step)
      do i = 0, n, 1
         pos = i * step
         res = res + step * cos(pos)
      enddo
      res = res + remainder * cos(Pi / 2.0)
      value = res
      return
      end

This function can be compiled using following instruction:

f2py-2.7 -c --fcompiler=gnu95 -m fun fun.f95

Further I call the library fun.so inside a Python script:

import numpy as np
import matplotlib.pyplot as plt

import fun

grid = np.linspace (0.01, 1.0, 50)

res_list = []

for i in range (0, len(grid)):
        res = fun.value(grid[i])
        res_list.append(res)

plt.plot(grid, res_list)
plt.xlabel('Numerical integration step size')
plt.ylabel('Result of integration')
plt.savefig('plot.pdf')
plt.show()

Since the tool f2py is a part of the numpy package, it is not required to properly transform types as it was the case with ctypes package.

The result of python script run is shown below.

Troubleshooting

Recently using one popular fortran code I have experienced an usual problem. I could have easily compiled the code either using ifort or fortran, but the f2py did not work returning error:

redefinition of ‘f2py_rout_fun_unknown_subroutine’

It was absolutely not clear why subroutine is unknown and where to start searching for the problem. In reality the problem is tiny and could be solved in minutes. The solution is to start from preparing a signature file:

f2py -m sig_file -h sig_file.pyf my_fotran_code.f –overwrite-signature

In this case the signature file sig_file.pyf contains a few function unknown_function() which looks extremely suspicious. Comparing successful definitions of functions with unsuccessful ones I figured out that unsuccessful definitions looked like this:

function fun1(arg1,arg2,arg3) ! tstts

While successful ones did not have any comments at the end of the line. Moving comments to the next line solved the problem completely.

If you use subroutines in fortran instead of functions it is important to declare an intent for f2py:

Cf2py intent(in) in_par

Cf2py intent(inout) out_par

The variable in_par only accept parameters from the python script while out_par also changes the variable declared in Python. More examples can be found here.