使用openmp和python进行swig,swig -threads是否需要额外的GIL处理?

时间:2014-09-23 14:20:21

标签: python numpy openmp openblas

我的C库与swig接口。 我可以用setup.py编译它。这里是扩展部分:

surf_int_lib = Extension("_surf_int_lib",
                   ["surf_int_lib.i", "surf_int_lib.c"],
                   include_dirs=[numpy_include],
                   extra_compile_args=["-fopenmp"],
                   extra_link_args=['-lgomp'],
                   swig_opts=['-threads']
                   )

在我的库中,我使用openmp进行并行化。当我调用我的例程时,我得到了正确数量的线程,但它们都受到GIL的影响并且同时运行。我的惯例给了我正确的输出。我的印象是swig -threads在进入图书馆时会释放GIL。那么为什么我的函数不能并行化呢?

这是一个openmp例程的例子:

void gegenbauerval(double *x, int nx, double *cs, int ncs, double alpha, double *f, int nf)
{
    int j;

    #pragma omp parallel for default(shared) private(j)
    for(j=0;j<nx;++j){
        f[j] = gegenbauerval_pt(x[j],cs,ncs, alpha);
    }
}

我的界面文件不包含任何%threadsPy_BEGIN_ALLOW_THREADS个来电。我是否需要发布GIL,如果是,我该怎么做?

更新 我在virtualenv中安装了openblas的numpy,我用它来计算。它与没有virtualenv的python解释器完全相同。 如果我使用激活环境运行以下在线程序,则不会并行化。但是,如果我使用标准安装运行它,它可以工作。 所以我不再确定真正的错误是什么。

python -c "import surf_int.lib.surf_int_lib as slib;import numpy as np;a=np.random.randn(1e8);c=np.random.rand(23);x=slib.gegenbauerval(a,c,1.5); print x"

1 个答案:

答案 0 :(得分:0)

经过进一步调查,我发现这是openmp和openblas之间的问题(至少版本为0.2.8)。

在使用选项USE_OPENMP=1重新编译openblas 0.2.11之后,使用openmp使用所有cpus来使用numpy以及我自己的扩展来执行例程,使用环境变量OMP_NUM_THREADS设置的所有cpus。

问题可能与this bug report和/ openblas 0.2.9.rc2的更改日志条目有关。