使用LAPACK分发基于Cython的扩展

2024-06-02 01:12:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个Python模块,它包含Cython扩展并使用LAPACK(和BLAS)。我愿意使用clapacklapacke,或者某种f2c或{}解决方案。重要的是,我能够在紧凑的循环中从Cython调用lapack和{}例程,而不需要Python调用开销。在

我发现了一个例子here。然而,这个例子取决于SAGE。我希望我的模块可以在不安装SAGE的情况下安装,因为我的用户不太可能想要或需要SAGE来做其他事情。我的用户可能已经安装了诸如numpy、scipy、pandas和scikit learn之类的软件包,因此这些都是合理的依赖关系。什么是最好的接口组合,什么是最小的设置.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文件中执行以下操作:

^{pr2}$

Tags: 模块fromimportbuildinfonumpygetinclude
1条回答
网友
1楼 · 发布于 2024-06-02 01:12:33

如果我正确地理解了这个问题,您可以使用SciPy的Cython包装器来执行BLAS和LAPACK例程。这些包装器记录如下:

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

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

考虑到这是一个经过良好测试、广泛使用、运行在不同平台上的代码,我认为它是可靠分发Cython扩展(直接调用BLAS和LAPACK例程)的一个很好的候选者。在


如果不希望代码依赖于整个SciPy,可以在SciPy的linalg目录here中找到这些包装器函数的许多相关文件。一个有用的参考是these lines of setup.py,它列出了源文件和头文件。请注意,需要一个Fortran编译器!在

理论中,应该可以只隔离编译BLAS和LAPACK Cython包装器所需的源文件,然后将它们作为独立的扩展绑定到模块中。在

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

显然,为了确保SciPy能够在不同的操作系统和体系结构上进行正确的编译,我们做了大量的工作。在

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

相关问题 更多 >