[英]Distributing Cython based extensions using LAPACK
我正在编写一个包含Cython扩展并使用LAPACK
(和BLAS
)的Python模块。 我愿意用任何clapack
或lapacke
,或某种f2c
或f2py
解决方案,如果必要的。 重要的是我能够在没有Python调用开销的情况下在紧密循环中调用来自Cython的lapack
和blas
例程。
我在这里找到了一个例子。 但是,该示例取决于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'])
])
)
这样做是因为,在我的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)
如果我正确理解了这个问题,你可以使用SciPy的Cython包装器来实现BLAS和LAPACK例程。 这些包装器在这里记录:
正如文档所述,您负责检查传递给这些函数的任何数组是否正确对齐Fortran例程。 您可以根据需要在.pyx文件中导入和使用这些功能。 例如:
from scipy.linalg.cython_blas cimport dnrm2
from scipy.linalg.cython_lapack cimport dgelsy
鉴于这是经过充分测试的广泛使用的代码,它运行在不同的平台上,我认为它是可靠地分发直接调用BLAS和LAPACK例程的Cython扩展的一个很好的候选者。
如果你不希望你的代码有SciPy的整体上的依赖,你可以找到许多在SciPy的的这些包装功能的相关文件linalg
目录在这里 。 一个有用的参考是setup.py的这些行,它列出了源文件和头文件。 请注意,需要Fortran编译器!
理论上 ,应该可以仅隔离编译BLAS和LAPACK Cython包装器所需的源文件,然后将它们作为模块的独立扩展捆绑。
在实践中,这非常繁琐。 linalg子模块的构建过程需要一些Python函数来帮助在不同平台上进行编译(例如从这里开始 )。 构建还依赖于其他C和Fortran源文件( 此处 ),其路径被硬编码到这些Python函数中。
显然,已经做了很多工作来确保SciPy在不同的操作系统和体系结构上正确编译。
我确信它有可能做到,但是在对文件和调整路径进行混洗之后,我还没有找到正确的方法来独立于SciPy的其余部分构建linalg子模块的这一部分。 如果我找到正确的方法,我一定会更新这个答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.