Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to wrap a function from a shared library using F2PY?

I'm developing a package that requires Python bindings for the dgtsv subroutine from the LAPACK Fortran library. At the moment, I'm distributing the Fortran source file, dgtsv.f, alongside my Python code, and using numpy.distutils to automatically wrap it and compile it into a shared library, _gtsv.so, that is callable from Python.

Here's what my setup.py file looks like at the moment:

from numpy.distutils.core import setup, Extension, build_ext
import os


fortran_sources = ["dgtsv.f"]
gtsv = Extension(
    name="pyfnnd._gtsv",
    sources=[os.path.join("pyfnnd", "LAPACK", ff) for ff in fortran_sources],
    extra_link_args=['-llapack']
)

setup(
    name='pyfnnd',
    py_modules=['_fnndeconv', 'demo', '_tridiag_solvers'],
    cmdclass={'build_ext': build_ext.build_ext},
    ext_modules=[gtsv],
)

Note that in order to actually use _gtsv.so, I still have to link against a pre-existing LAPACK shared library (extra_link_args=['-llapack']). Since this library should already contain the dgtsv subroutine, it seems to me that it would be cleaner to just wrap the function in the existing shared library, rather than having to distribute the actual Fortran source.

However I've never come across any examples of using F2PY to wrap functions that are part of a shared library rather than just raw Fortran source code. Is this possible?

like image 601
ali_m Avatar asked May 10 '14 16:05

ali_m


1 Answers

I think you just need ctypes, there is a complete example on calling a lapack function on this page: http://www.sagemath.org/doc/numerical_sage/ctypes.html

You get your function like this:

import ctypes
from ctypes.util import find_library
lapack = ctypes.cdll.LoadLibrary(find_library("lapack"))
dgtsv = lapack.dgtsv_
like image 62
cronos Avatar answered Oct 16 '22 22:10

cronos