python - 使用 LAPACK 分发基于 Cython 的扩展

标签 python numpy cython lapack blas

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

我找到了一个例子 here .但是,该示例取决于 SAGE。我希望我的模块可以在不安装 SAGE 的情况下安装,因为我的用户不太可能想要或不需要 SAGE 做其他任何事情。我的用户可能安装了 numpy、scipy、pandas 和 scikit learn 等软件包,因此这些都是合理的依赖项。要使用的最佳接口(interface)组合是什么,最小的 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 目录 here 中找到这些包装函数的许多相关文件.一个有用的引用是these lines of setup.py其中列出了源文件和头文件。请注意,需要 Fortran 编译器!

theory 中,应该可以仅在此处隔离编译 BLAS 和 LAPACK Cython 包装器所需的源文件,然后将它们作为独立扩展与您的模块捆绑在一起。

实践中这是非常繁琐的。 linalg 子模块的构建过程需要一些 Python 函数来帮助在不同平台上进行编译(例如来自 here )。构建还依赖于其他 C 和 Fortran 源文件 (here),其路径被硬编码到这些 Python 函数中。

显然,为了确保 SciPy 在不同的操作系统和架构上正确编译,我们做了很多工作。

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

关于python - 使用 LAPACK 分发基于 Cython 的扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14864895/

相关文章:

windows-7 - cython:mingw 的内存 View 构建错误

python - 在 Mac 上安装加密时的 pycrypto massup

python - plot.ly 烛台图通过 matplotlib

python - 试图在二叉树中查找节点

python - 在 Cython 中创建不等长的 numpy.ndarray 列表

python - numpy python 类调用错误的 __setitem__

python - Cython C++ 模板

python - P4Python p4.temp_client 坏了?

python - 如何使用三角矩阵使 np.where 更高效?

python - 为什么 Cython 期望 0 维?