I just wrapped a Fortran 90 subroutine to python using F2PY. The subtlety here is that the Fortran subroutine aslo takes a python call-back function as one of its arguments:
SUBROUTINE f90foo(pyfunc, a)
real(kind=8),intent(in) :: a
!f2py intent(callback) pyfunc
external pyfunc
!f2py real*8 y,x
!f2py y = pyfunc(x)
!*** debug begins***
print *, 'Start Loop'
do i=1,1000
p = pyfunc(a)
end do
total = etime(elapsed)
print *, 'End: total=', total, ' user=', elapsed(1), ' system=', elapsed(2)
stop
!*** debug ends ***
The pyfunc
is a python function defined elsewhere in my python code. The wrapper works fine, but running the wrapped version above, I got an elapsed time about factor of 5 times longer than what I can get using pure python as follows,
def pythonfoo(k):
""" k: scalar
returns: scalar
"""
print('Pure Python: Start Loop')
start = time.time()
for i in xrange(1000):
p = pyfunc(k)
elapsed = (time.time() - start)
print('End: total=%20f'% elapsed)
So, the question is, what is the overhead coming from? I really want to leave pyfunc
as is because it is extremely time-consuming to re-code it into pure fortran function, so is there any way to improve the speed of the wrapper module?
pyfunc
is mostly taking scalar arguments inside Fortran although it is designed in python to be able to take either nparrays or scalars. – Preconscious