带有 GSL 的 Windows 64 中的 Cython

Posted

技术标签:

【中文标题】带有 GSL 的 Windows 64 中的 Cython【英文标题】:Cython in Windows 64 with GSL 【发布时间】:2014-11-22 14:41:34 【问题描述】:

我正在尝试编译以下 pyx 代码:

#declaring external GSL functions to be used
cdef extern from "math.h":
    double sqrt(double)

cdef double Sqrt(double n):
   return sqrt(n)

cdef extern from "gsl/gsl_rng.h":
   ctypedef struct gsl_rng_type:
       pass
   ctypedef struct gsl_rng:
       pass
   gsl_rng_type *gsl_rng_mt19937
   gsl_rng *gsl_rng_alloc(gsl_rng_type * T)

cdef gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937)

cdef extern from "gsl/gsl_randist.h":
   double gamma "gsl_ran_gamma"(gsl_rng * r,double,double)
   double gaussian "gsl_ran_gaussian"(gsl_rng * r,double)

# original Cython code
def gibbs(int N=20000,int thin=500):
   cdef double x=0
   cdef double y=0
   cdef int i, j
   samples = []
   #print "Iter  x  y"
   for i in range(N):
       for j in range(thin):
           x = gamma(r,3,1.0/(y*y+4))
           y = gaussian(r,1.0/Sqrt(x+1))
       samples.append([x,y])
   return samples

smp = gibbs()

这是我的 setup.py 文件的样子:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

import numpy
import sys

if sys.platform == "win32":
    include_gsl_dir = sys.exec_prefix+"\gsl\include"
    lib_gsl_dir = sys.exec_prefix+"\gsl\lib"
else:
    include_gsl_dir = sys.exec_prefix+"\include"
    lib_gsl_dir = sys.exec_prefix+"\lib"

ext = Extension("samplers", ["samplers.pyx"],
    include_dirs=[numpy.get_include(), 
                  include_gsl_dir],
    library_dirs=[lib_gsl_dir],
    libraries=["gsl","gslcblas","m"]
)
setup(ext_modules=[ext],
    cmdclass = 'build_ext': build_ext)

GSL 文件包含在 C:\Users\MyName\Anaconda\gsl\include\gsl、C:\Users\MyName\Anaconda\gsl\lib\ 和 C:\Users\MyName\Anaconda\gsl\bin 中.因此,为什么 setup.py 文件包含对 sys.exec_prefix 的引用以获取 python 可执行文件所在的主要 Anaconda 文件夹。

我将 GSL 与 Cython 链接的方式有什么问题吗?当我跑步时:

 python setup.py build_ext --inplace

创建了一个 PYD 文件,但是当我尝试从创建 pyd 的同一文件夹中的 python 环境导入采样器时,我得到了可怕的“ImportError: DLL load failed: The specified module could not be found”。

我认为它编译错误是因为它无法与 GSL 文件通信,或者 pyx 代码有问题。我排除了后者,因为它成功编译了一个 pyd 文件而没有错误。

我也尝试与 CythonGSL 模块链接,但如果您查看 init.py,对于 win32,gsl 需要位于 c:\Program Files\GnuWin32\include 中,我更喜欢在 Anaconda 文件夹中有 gsl 库。尽管如此,将它们放在 c:\Program Files\GnuWin32\include 中仍然会给我同样的 ImportError: DLL 错误...

【问题讨论】:

如果您要在文件或文件夹路径中使用反斜杠,您需要对它们中的每一个进行反斜杠转义,或者使用 Python 原始字符串文字。例如sys.exec_prefix+"\\gsl\\include"sys.exec_prefix+r"\gsl\include"。使用 os.path 连接 (os.path.join()) 或以其他方式操作文件夹和文件路径也是一个好主意。 【参考方案1】:

CythonGSL 的当前版本使用环境变量 LIB_GSL 来识别 GSL 的位置。仅当LIB_GSL 不存在时,它才使用硬编码的c:\Program Files\GnuWin32\include。因此,只要您设置了LIB_GSL,您就可以将 GSL 安装在不同的位置。我认为您在设置LIB_GSL 时应该使用/ 而不是\

因此,您需要创建/修改两个环境变量才能使 CythonGSL 工作:LIB_GSLPATH。我认为您可以在批处理文件中使用setlocal。例如,我认为您可以执行以下操作(我在C:\lib64\gsl 安装了gsl)来临时设置它:

setlocal
SET LIB_GSL=C:/lib64/gsl
SET PATH=%PATH%;C:\lib64\gsl\bin;
Python

希望这有帮助。

【讨论】:

【参考方案2】:

我相信我找到了问题所在。

我的 PATH 变量无权访问 GSL 文件夹。在运行时,它需要访问 gsl/bin 文件夹,所以我需要将 C:\Users\MyName\Anaconda\gsl\bin 添加到系统路径变量中。我试过 setx PATH "%PATH%;C:\Users\MyName\Anaconda\gsl\bin",这确实有效。但是当我关闭 CMD 窗口并重做它时,它不再起作用。

当我使用它来分发时,是否可以通过批处理文件永久设置它?我有 conda 构建的 bld.bat 文件,但即使在那里 setx 命令也不起作用。

【讨论】:

以上是关于带有 GSL 的 Windows 64 中的 Cython的主要内容,如果未能解决你的问题,请参考以下文章

Windows系统编译GSL2.7用于C语言编程(2022.5.8)

Windows系统编译GSL2.7用于C语言编程(2022.5.8)

使用 MXE - GSL 链接在 Linux for Windows 上进行交叉编译?

gsl安装(Linux系统)

gsl_rng_default 未解决的外部错误

jchdl - 门和开关层(GSL)