Looking at some other similar questions (Cython and fortran - how to compile together without f2py), I may be going about this the wrong way, but the workflow I'd like to put in place seems so cythonic/pythonic that I would be surprised if the following isn't possible:
1) Compile a fortran_func.so with f2py from the fortran_func.f source file that contains the foo subroutine I need. Seeing as I have the .f source, I do know the correct function call syntax.
2) Magic step perhaps involving a "cdef extern" or something similar.
3) Directly call the function without having to pass by:
import fortran_func
out = fortran_func.foo(x, y)
The idea is that I have three for loops around this function call and calling the fortran function through a python import is really slow. Currently I have this:
import fortran_func
cdef np.ndarray[double, ndim=3] cy_func(double[::1] x,
double[::1] y,
double[::1] z,
int N):
cdef:
int i, j, k
np.ndarray[double, ndim=3] out
out = np.zeros((N, N, N), dtype=np.float64)
for i in range(N): # fast C loops
for j in range(N):
for k in range(N):
# extremely slow python call
out[i,j,k] = fortran_func.foo(x[i], y[j], z[k])
# would prefer a fast, direct function call
# out[i,j,k] = foo(x[i], y[j], z[k])
I would very much appreciate any help in finding out what this magic step should be!
You can call a shared fortran object as a c-function with ctypes without converting to python types. You should be able to do so with cython as well. I wrote it down here:
http://pythology.blogspot.fr/2014/03/wrapping-fortran-and-python-without-f2py.html
This is the summary:
fortran file add.f95:
subroutine add(a,b,c)
implicit none
integer a,b,c
c = a + b
end
compile with:
gfortran -shared -fPIC add.f95 -o add.so
the python code to call it (careful, 'add' becomes 'add_') is:
#!/usr/bin/env python
from ctypes import c_int, byref, cdll
a = c_int(3)
b = c_int(4)
c = c_int()
addlib = cdll.LoadLibrary('./add.so')
addlib.add_(byref(a),byref(b),byref(c))
print c