繁体   English   中英

使用LAPACK分发基于Cython的扩展

[英]Distributing Cython based extensions using LAPACK

我正在编写一个包含Cython扩展并使用LAPACK (和BLAS )的Python模块。 我愿意用任何clapacklapacke ,或某种f2cf2py解决方案,如果必要的。 重要的是我能够在没有Python调用开销的情况下在紧密循环中调用来自Cython的lapackblas例程。

我在这里找到了一个例子。 但是,该示例取决于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM