使用LAPACK分配基于Cython的扩展

我正在编写一个包含Cython扩展的Python模块,并使用LAPACK (和BLAS )。 我愿意使用clapacklapacke ,或者某种f2pyf2py解决scheme。 重要的是,我可以在没有Python调用开销的情况下,在紧密的循环中调用lapackblas例程。

我在这里find一个例子。 但是,这个例子取决于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']) ]) ) 

这是clapack.h ,因为在我的MacBook上, clapack.h头文件和cblas.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) 

如果我已经正确地理解了这个问题,那么可以使用SciPy的Cython包装器来处理BLAS和LAPACK例程。 这些包装文件logging在这里:

  • BLAS
  • LAPACK

正如文档所述,您负责检查传递给这些函数的任何数组是否与Fortran例程正确alignment。 您可以根据需要在.pyx文件中简单地导入和使用这些函数。 例如:

 from scipy.linalg.cython_blas cimport dnrm2 from scipy.linalg.cython_lapack cimport dgelsy 

鉴于这是在不同平台上运行的广泛使用的代码,我认为这是可靠地分发直接调用BLAS和LAPACK例程的Cython扩展的好select。


如果你不想让你的代码依赖整个SciPy,你可以在SciPy的linalg目录中find这些包装函数的许多相关文件。 一个有用的参考是这些列出源文件和头文件的setup.py行 。 请注意,Fortran编译器是必需的!

理论上讲 ,应该可以只隔离编译BLAS和LAPACK Cython包装所需的源文件,然后将它们作为独立扩展与您的模块捆绑在一起。

实践中,这是很难做到的。 linalg子模块的构build过程需要一些Python函数来帮助编译不同的平台(例如从这里 )。 Building也依赖于其他的C和Fortran源文件( 在这里 ),其path被硬编码到这些Python函数中。

很明显,很多工作已经进入确保SciPy能够在不同的操作系统和体系结构上正确编译。

我确信这是可以做到的,但是在对文件进行混洗和调整之后,我还没有find正确的方法来独立于SciPy的其余部分来构build这部分的linalg子模块。 我应该find正确的方法,我一定会更新这个答案。