3

I am using f2py to compile a numerical module for use by a Python script. I have reduced my code to the minimal example below:

fd.f:

module fd
  ! Double precision real kind
  integer, parameter :: dp = selected_real_kind(15)

contains

subroutine lprsmf(th)
  implicit none
  real(dp) th
  write(*,*) 'th - fd',th
end subroutine lprsmf

end module fd

itimes.f:

subroutine itimes(th)
  use fd
  implicit none
  real(dp) th

  write(*,*) 'th - it',th
  call lprsmf(th)
end subroutine itimes

reprun.py:

import it

th = 200
it.itimes(th)

The commands used to compile and run are as follows (Note that I am using cmd under Windows):

gfortran -c fd.f
f2py.py -c -m it --compiler=mingw32 fd.o itimes.f
reprun.py

The output is:

th - it  1.50520876326836550E-163
th - fd  1.50520876326836550E-163

My first guess is that th is somehow not being passed correctly from reprun.py to subroutine itimes. However, I do not understand this behavior, as the full version of the code includes other inputs, all of which are passed correctly. I was not able to get it to do the same thing when calling itimes from Fortran, so I'm assuming it has something to do with the Python/Fortran interface. Can anyone provide any insights into why this behavior occurs?

EDIT: Replacing th = 200 in reprun.py with th = 200.0 yields the following output:

th - it  1.19472349365371216E-298
th - fd  1.19472349365371216E-298
astay13
  • 6,857
  • 10
  • 41
  • 56

1 Answers1

1

Wrap your itimes subroutine in a module as well. Here is what i did:

itimes.f90:

module itime

contains

subroutine itimes(th)
  use fd
  implicit none
  real(dp) th

  write(*,*) 'th - it',th
  call lprsmf(th)
end subroutine itimes

end module

compile & run:

gfortran -c fd.f90
c:\python27_w32\python.exe c:\python27_w32\scripts\f2py.py -c -m it --compiler=mingw32 fd.f90 itimes.f90

run reprun.py:

import it

th = 200
it.itime.itimes(th)

output:

 th - it   200.00000000000000     
 th - fd   200.00000000000000     
bananafish
  • 2,877
  • 20
  • 29
  • Playing around with it some more, I found that I don't need the module declaration in itimes.f, it seems that the critical point is passing fd.f90 instead of fd.o to f2py. Do you know why that would be? – astay13 Jun 08 '12 at 14:26
  • @astay13 ah, you may be right, I just changed that by habit. Not sure, I've only tried passing the actual Fortran source to f2py. I would also still recommend always wrapping code in modules, you avoid a lot of Fortran pitfalls that way. – bananafish Jun 09 '12 at 00:37
  • @astay13 -- You need to pass the source instead of the .o file. Basically, f2py is a fortran parser (plus a little ) which wraps your fortran code with C code and the python API. It then compiles the entire thing into a shared object (using whatever compiler it can find on your system) which can be loaded by python. If you give f2py an object file -- It's not nearly sophisticated enough to reverse engineer already compiled code and generate a python interface. – mgilson Jun 11 '12 at 01:43
  • @mgilson, I have been getting the code to compile with the Fortran object file and it has been working fine for a while before I ran into this problem. I think it has something to do with the fact that this is the first time I tried to pass a `real` argument into the main subroutine. – astay13 Jun 11 '12 at 02:32