2

Based on this minimal example, I want to manipulate variables of a Fortran module with Python and Fortran subroutines. Please take a look at the following example:

vars.f90

module vars
implicit none
real(kind=selected_real_kind(p=15))      :: fk(10)
end module vars

sub.f90

subroutine sub
    use vars
    print *, "sub: fk(1) = ", fk(1)
    print *, "adding 1 to fk(1)"
    fk(1) = fk(1) + 1
    print *, "fk(1) = ", fk(1)
end

mytest.f90

include "vars.f90"
include "sub.f90"

The compilation is done with the following command and gfortran:

f2py -c -m mytest mytest.f90

Finally, here is the testcase to reproduce the problem in a Python 3.6.5 console:

>>> import mytest
>>> mytest.vars.fk[1]
0.0
>>> mytest.vars.fk[1]=1.5000
>>> mytest.vars.fk[1]
1.5
>>> mytest.sub()
 sub: fk(1) =   0.12500000000000000     
 adding 1 to fk(1)
 fk(1) =    1.1250000000000000     
>>> mytest.vars.fk[1]
1.890625
>>> 

From my point of view, fk(1) should be 2.5 in the end. But unfortunately Fortran reads the variable in the subroutine wrong although the direct access to the variable via python console displays the correct value. After modifying the variable the python console displays a wrong number too.

Any advice or proposal to resolve/reason this behavior? I appreciate any help! Thank you!

P.S.: First I thought it depends on the way Python and Fortran handle the arrays differently(Python starts at index 0 and Fortran at index 1), but this is not the mistake. mytest.vars.fk[0] is not modified after calling the subroutine (initial value 0.0).

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • 1
    Possible duplicate of [f2py: Specifying real precision in fortran when interfacing with python?](https://stackoverflow.com/questions/12523524/f2py-specifying-real-precision-in-fortran-when-interfacing-with-python) – Pierre de Buyl Nov 05 '18 at 09:55
  • f2py is treating `fk` as single precision. Read the link in @PierredeBuyl's comment. – Warren Weckesser Nov 05 '18 at 09:58

1 Answers1

3

There are two issues with the code:

  1. The indexing isssue, that you have noted. You still need to access fk[0] in Python to obtain the desired behaviour.

  2. The use of selected_real_kind(p=15) for the kind specification. See the FAQ of F2PY and this related SO answer.

Currently, f2py sees your varibale as a default real variable (here, 32 bit) instead of a double precision. You can fix it by creating a file .f2py_f2cmap (in the current working directory) with the content:

{'real':{'selected_real_kind(p=15)': 'double'}}

that will select "double" as the corresponding C type for your parameter. F2PY has no way of detecting modern Fortran types, unfortunately.

I flagged this as duplicate of f2py: Specifying real precision in fortran when interfacing with python? but there is also the indexing issue here. Let's see what others think.

Pierre de Buyl
  • 7,074
  • 2
  • 16
  • 22
  • Thank you for the hints @Pierre! Unfortunately, they do not solve my problem. I recompiled mytest with the .f2py_f2cmap and used the [0] index in the python console. `>>> mytest.vars.fk[0]=1.2 >>> mytest.vars.fk[0] 1.2 >>> mytest.sub2() sub2: fk(1) = 5.2718332951556110E-315 adding 1 to fk(1) fk = 1.0000000000000000 >>> mytest.vars.fk[0] 0.0` The behavior is still the same. – Napsterlicious Nov 05 '18 at 11:32
  • Did you restart the console? – Pierre de Buyl Nov 05 '18 at 11:37
  • Also, "hard coding" the type goes against the idea of using `selected_real_kind` :-) Can you provide more info on your platform? (versions of compilers, Python, NumPy). I tested the solutions I posted BTW, it worked as you intended, which is why I ask for more details. – Pierre de Buyl Nov 05 '18 at 11:38
  • Yes I restarted the console. Okay I didn't know that. I am not a native Fortran programmer and try to wrap a huge Fortran program to handle it. GNU Fortran (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0, Python 3.6.5 (Anaconda Distro) with GCC 7.2.0 and Numpy '1.14.3' – Napsterlicious Nov 05 '18 at 11:46
  • 1
    One possible issue here is a mismatch between Anaconda's compiler and your system compiler. Have you installed Anaconda's gcc and gfortran? `conda install gcc`. – Pierre de Buyl Nov 05 '18 at 12:05
  • I installed the full distribution of anaconda and gfortran manually. I didnt expect to have problems here, because F2PY uses gfortran for compiling. – Napsterlicious Nov 05 '18 at 12:14
  • From your comment, I don't understand how you installed gfortran. Can you specify the commands? (i.e. `apt-get install gfortran` or `conda install gcc`) – Pierre de Buyl Nov 05 '18 at 13:56
  • Yes I installed it via apt-get install gfortran. I removed anaconda completely and tested your proposal again. It does work now! Thank you very much! – Napsterlicious Nov 05 '18 at 14:17