当我在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
答案 0 :(得分:3)
好的,经过一番探讨之后,我想我已经证实了我最初的一些怀疑
首先:
所以
f2py
本身只使用Fortran。
正如我在评论中提到的,OP所指的所有Fortran源文件都在/test/
或/doc/
目录中,因此我怀疑它们是用于测试和记录{{1 (和f2py
,使用numpy.distutils
)。浏览一些源文件似乎证实了这种印象。 f2py
本身看起来像是用Python和C编写的。
我研究了线性代数模块。对于LAPACK,有一个make_lite.py文件,它只从LAPACK源树中提取必要的子例程,并使用
将它们转换为C.f2py
这对我来说似乎很奇怪,因为我实际上并没有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/README
,numpy/linalg/blas_lite.c
和numpy/linalg/dlapack_lite.c
是numpy/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*
,fftpack
,odepack
,arpack
等。我怀疑{ {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 代码。