什么是f2py用于构建numpy源?

时间:2014-05-14 22:16:10

标签: python numpy f2py

当我在NumPy的源代码树中列出所有Fortran文件时,我得到:

./doc/source/f2py/scalar.f
./doc/source/f2py/string.f
./doc/source/f2py/calculate.f
./doc/source/f2py/moddata.f90
./doc/source/f2py/array.f
./doc/source/f2py/allocarr.f90
./doc/source/f2py/extcallback.f
./doc/source/f2py/common.f
./doc/source/f2py/ftype.f
./doc/source/f2py/fib3.f
./doc/source/f2py/callback.f
./doc/source/f2py/fib1.f
./doc/f2py/f2python9-final/src/examples/exp1.f
./doc/f2py/simple.f
./doc/f2py/multiarray/foo.f
./doc/f2py/hello.f
./doc/f2py/ex1/bar.f
./doc/f2py/ex1/foobar-smart.f90
./doc/f2py/ex1/foo.f
./doc/f2py/ex1/arr.f
./doc/f2py/ex1/foobar.f90
./numpy/f2py/tests/src/mixed/foo_fixed.f90
./numpy/f2py/tests/src/mixed/foo_free.f90
./numpy/f2py/tests/src/mixed/foo.f
./numpy/f2py/tests/src/size/foo.f90
./numpy/f2py/tests/src/kind/foo.f90
./numpy/f2py/tests/src/assumed_shape/precision.f90
./numpy/f2py/tests/src/assumed_shape/foo_use.f90
./numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
./numpy/f2py/tests/src/assumed_shape/foo_free.f90
./numpy/f2py/tests/src/assumed_shape/foo_mod.f90
./numpy/f2py/src/test/bar.f
./numpy/f2py/src/test/foo.f
./numpy/f2py/src/test/foo90.f90
./numpy/f2py/src/test/wrap.f
./numpy/distutils/tests/f2py_ext/src/fib1.f
./numpy/distutils/tests/f2py_f90_ext/include/body.f90
./numpy/distutils/tests/f2py_f90_ext/src/foo_free.f90

所以除了f2py之外,其他人都使用Fortran。我研究了线性代数模块。对于LAPACK,有一个make_lite.py文件,它只从LAPACK源树中提取必要的子例程,并使用f2c将它们转换为C.因此,在创建NumPy的过程中,创建f2py是否方便?我错过了什么吗?

修改

事实证明,SciPy中的很多软件包都使用f2py。运行

$ find . -iname '*.f*'  | cut -d'/' -f3,4 | uniq

给了我填充Fortran文件的确切目录:

linalg/src
fftpack/src
odr/odrpack
special/cdflib
special/amos
special/mach
special/specfun
integrate/quadpack
integrate/odepack
integrate/dop
integrate/linpack_lite
integrate/mach
sparse/linalg
interpolate/fitpack
optimize/minpack2
optimize/minpack
optimize/nnls
optimize/cobyla
optimize/lbfgsb
optimize/slsqp
stats/mvndst.f
stats/futil.f
stats/statlib
_build_utils/src
lib/lapack

2 个答案:

答案 0 :(得分:3)

好的,经过一番探讨之后,我想我已经证实了我最初的一些怀疑

首先:

  

所以f2py本身只使用Fortran。

正如我在评论中提到的,OP所指的所有Fortran源文件都在/test//doc/目录中,因此我怀疑它们是用于测试和记录{{1 (和f2py,使用numpy.distutils)。浏览一些源文件似乎证实了这种印象。 f2py本身看起来像是用Python和C编写的。

  

我研究了线性代数模块。对于LAPACK,有一个make_lite.py文件,它只从LAPACK源树中提取必要的子例程,并使用f2py

将它们转换为C.

这对我来说似乎很奇怪,因为我实际上并没有f2c安装(或f2c,这是Plex似乎需要的另一个库)。我决定在make_lite.py中添加一行以显示在正常安装期间是否实际使用了main()

make_lite.py

果然,在干净的virtualenv中安装numpy后,我的... def main(): # let's see if you're actually doing anything import subprocess; subprocess.call(['touch', '/tmp/hello_from_make_lite']) ... 中没有hello_from_make_lite文件,表明/tmp/从未执行过。看看make_lite.main()

  

numpy/linalg/lapack_lite/READMEnumpy/linalg/blas_lite.c和   numpy/linalg/dlapack_lite.cnumpy/linalg/zlapack_lite.c个LAPACK例程的版本   f2c模块所需,并由LinearAlgebra包裹   模块。此目录中的脚本可用于创建这些文件   自动从LAPACK源文件目录。

所以numpy已经与这些lapack_lite C源文件一起分发 - 除非您想要更新这些文件,否则无需使用f2c来自新版LAPACK库的函数。

  

因此,在创建NumPy期间,创建make_lite.py

是否方便

据我所知,f2py在正常的numpy安装过程中并未在所有中使用。再次,我在f2py中添加了一行:

f2py2e.main()

再次,... def main(): import subprocess; subprocess.call(['touch', '/tmp/hello_from_f2py2e']) ... 在正常安装numpy之后不存在。

那么/tmp/hello_from_f2py2e实际上用于什么?查看scipy源代码树,并从其根调用

f2py

您会看到重载Fortran文件的加载和加载,包括$ find . -iname *.f* fftpackodepackarpack等。我怀疑{ {1}}主要需要将Fortran扩展包装为scipy而不是numpy。

但是,我可能错了 - 或许其中一个笨拙或狡猾的开发者会让我直截了当。

更新

实际上,我认为在正常安装scipy期间实际上并不需要fitpack!如果您查看其中一个Fortran模块的源目录,例如fftpack,您会看到它已包含f2py个文件,这些文件通常由f2py自动生成,并定义Fortran函数的接口(请参阅here )。

我认为交易是.pyf用于最初为Fortran函数生成f2py包装器,但这些f2py文件与源树的其余部分一起分发,所以在正常构建过程中不必再次运行.pyf

答案 1 :(得分:0)

这是一个老问题,但 f2py 的目的是允许 numpy 的用户包装他们自己的任意 Fortran 例程并从 Python 中调用它们。我用它来调用我拥有的一些自定义卡尔曼滤波器代码。调用 Fortran 版本比翻译成 numpy 的相同算法要快得多,这可能是由于一堆数组切片。然而,随着 numba 变得越来越好,我更倾向于用 @njit 来装饰 numpy 代码。