带有GSL的Windows 64中的Cython

时间:2014-11-22 14:41:34

标签: python c++ cython anaconda gsl

我正在尝试编译以下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文件,但是我得到了可怕的" ImportError:DLL加载失败:找不到指定的模块"当我尝试从创建pyd的同一文件夹中的python环境导入采样器时。

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

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

2 个答案:

答案 0 :(得分:1)

CythonGSL的当前版本使用环境变量LIB_GSL来识别GSL的位置。仅当c:\Program Files\GnuWin32\include不存在时,它才会使用硬编码的LIB_GSL。因此,只要设置了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

希望这有用。

答案 1 :(得分:0)

我相信我已经找到了问题。

我的PATH变量无法访问GSL文件夹。在运行时,它需要访问gsl / bin文件夹,因此我需要将C:\ Users \ MyName \ Anaconda \ gsl \ bin添加到系统路径变量中。我已经尝试过setx PATH“%PATH%; C:\ Users \ MyName \ Anaconda \ gsl \ bin”,这样做有效。但是当我关闭CMD窗口并重做它时,它就不再有效了。

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