Search code examples
pythonglobal-variablesfortranf2py

f2py: strange behaviour for constants in module


I found some strange behaviour for f2py when working with global constants in a Fortran module.

Let's say I have a file test.f90, which looks like

module test1
  real, parameter :: a = 12345.
end module test1

module test2
  real*8, parameter :: a = 6789.
end module test2

If I wrap this with f2py using

f2py -c -m mymod test.f90

and running

python -c "import mymod as m; print m.test1.a; print m.test2.a"

I get

12345.0
6789.0

which is pretty much you would expect. Both real and real*8 statements behave the same way.

For my actual project I need to compile my Fortran code with compiler flags, specifying explicit usage of double precision. In Fortran, this works fine. When I compile the above code as

f2py --f90flags="-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8" -c -m mymod test.f90

I get as result

python -c "import mymod as m; print m.test1.a; print m.test2.a"

0.0
6789.0

This is actually weird. The global variable is not initialized in the first case, it's value is zero. Is this a bug or is there a different way to specify explicit handling of double precision in f2py?


Solution

  • I found a workaround so far. The problem is that f2py does not recognize that it should map a fortran real to a C-type double when appropriate double precision compiler flags are provided.

    The solution is to tell f2py explicitly how to do the mapping of different data types. This can be achieved by creating a file .f2py_f2cmap which contains a python dictionary specifying the data type mapping. For details see here.

    In my case the following entry solved the problem

    {'real':{'':'double'},'integer':{'':'long'},'real*8':{'':'double'}}