jcr*_*udy 67 python numpy cython blas lapack
我正在编写一个包含Cython扩展和使用LAPACK
(和BLAS
)的Python模块.我打开使用两种clapack
或lapacke
,或某种f2c
或f2py
解决方案,如果必要的.最重要的是,我能够调用lapack
并blas
从用Cython在紧密循环不Python的调用开销例程.
我在这里找到了一个例子.但是,该示例取决于SAGE.我希望我的模块可以在不安装SAGE的情况下进行安装,因为我的用户不太可能想要或不需要SAGE.我的用户很可能安装了numpy,scipy,pandas和scikit的软件包,所以这些都是合理的依赖.使用的接口的最佳组合是什么,以及最小的setup.py文件看起来可以获取必要的信息(来自numpy,scipy等)以进行编译?
编辑: 这是我最终做的.它适用于我的macbook,但我不知道它是多么便携.当然有更好的方法.
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy
from Cython.Build import cythonize
from numpy.distutils.system_info import get_info
# TODO: This cannot be the right way
blas_include = get_info('blas_opt')['extra_compile_args'][1][2:]
includes = [blas_include,numpy.get_include()]
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = cythonize([Extension("cylapack", ["cylapack.pyx"],
include_dirs = includes,
libraries=['blas','lapack'])
])
)
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为在我的macbook上,clapack.h
头文件与...相同cblas.h
.然后我可以在我的pyx文件中执行此操作:
ctypedef np.int32_t integer
cdef extern from "cblas.h":
double cblas_dnrm2(int N,double *X, int incX)
cdef extern from "clapack.h":
integer dgelsy_(integer *m, integer *n, integer *nrhs,
double *a, integer *lda, double *b, integer *ldb, integer *
jpvt, double *rcond, integer *rank, double *work, integer *
lwork, integer *info)
Run Code Online (Sandbox Code Playgroud)
如果我正确理解了这个问题,你可以使用SciPy的Cython包装器来实现BLAS和LAPACK例程.这些包装器在这里记录:
正如文档所述,您负责检查传递给这些函数的任何数组是否正确对齐Fortran例程.您可以根据需要在.pyx文件中导入和使用这些功能.例如:
from scipy.linalg.cython_blas cimport dnrm2
from scipy.linalg.cython_lapack cimport dgelsy
Run Code Online (Sandbox Code Playgroud)
鉴于这是经过充分测试的广泛使用的代码,它运行在不同的平台上,我认为它是可靠地分发直接调用BLAS和LAPACK例程的Cython扩展的一个很好的候选者.
如果您不希望代码依赖于整个SciPy,可以在SciPy的linalg
目录中找到这些包装函数的许多相关文件.一个有用的参考是setup.py的这些行,它列出了源文件和头文件.请注意,需要Fortran编译器!
在理论上应该可以只隔离这里的源文件需要编译BLAS和LAPACK用Cython包装,然后捆扎在一起,与你的模块的独立分机.
在实践中,这非常繁琐.linalg子模块的构建过程需要一些Python函数来帮助在不同平台上进行编译(例如从这里开始).构建还依赖于其他C和Fortran源文件(此处),其路径被硬编码到这些Python函数中.
显然,已经做了很多工作来确保SciPy在不同的操作系统和体系结构上正确编译.
我确信它有可能做到,但是在对文件和调整路径进行混洗之后,我还没有找到正确的方法来独立于SciPy的其余部分构建linalg子模块的这一部分.如果我找到正确的方法,我一定会更新这个答案.