【问题标题】:Extending Python with parallelized C programs (under OMP)使用并行 C 程序扩展 Python(在 OMP 下)
【发布时间】:2012-12-12 12:02:57
【问题描述】:

所以,我正在考虑对我拥有的 python 组件进行 C 扩展。然后,我想使用 OMP 尽可能多地利用机器,这些机器最终将运行 Python+C 的组合解决方案。

有没有人尝试过类似的东西?是否有任何特殊的、不利的细节会导致这样的解决方案失败?

提前致谢!

【问题讨论】:

    标签: python c parallel-processing openmp


    【解决方案1】:

    我已经成功地完成了射电天文学中的大型数据挖掘任务。示例见https://github.com/ewanbarr/sigpyproc.git

    需要注意的是,我在这些情况下构建的 C 库是通过 ctypes 访问的,而不是作为原生 Python 扩展。

    所以,例如:

    Python:test.py

    import ctypes as C
    import numpy as np
    from numpy.ctypeslib import as_ctypes
    lib = C.CDLL("libmytest.so")
    
    def set_N_threads(nthreads):
        self.lib.omp_set_num_threads(nthreads)
    
    def do_some_task(input_array):
        input_array = input_array.astype("float32")
        output_array = np.empty_like(input_array)
        lib.do_some_omp_task(as_ctypes(input_array),
                             as_ctypes(output_array),
                             C.c_size_t(input_array.size))
        return output_array
    

    C: test.c

    #include <omp.h>
    
    void do_some_omp_task(float* input_array,
                          float* output_array,
                          size_t size)
    {
       int ii;
    #pragma omp parallel for default(shared) private(ii)
       for (ii=0;ii<size;ii++)
           do something using ii and the arrays
    }
    

    编译:

    gcc -O3 -lm -fopenmp -fPIC -c test.c -o test.o
    gcc -shared -lgomp -o libmytest.so test.o
    

    为了回答您的问题,我对这种设置没有任何问题,并且可实现的速度改进令人印象深刻(尽管上述示例不会真正受益于 OMP)

    【讨论】:

    • 非常有前途!非常感谢你!我特别关心函数调用的线程安全以及它如何影响 python 方面的事情。但是从我在您的示例中看到的情况来看,从线程级别的角度来看,接口并没有为出错留下太多空间。我现在就调查一下!再次感谢。
    • 使用ctypes时,只要不使用PyDLL调用库,就会释放全局解释器锁,因此C函数及其线程独立于Python。
    【解决方案2】:

    Cythonparallel.prange()example

    要手动执行此操作,请在扩展模块初始化时调用 PyEval_InitThreads。在派生非 python 线程时释放 GIL,例如,通过将 OMP 并行部分包装在 Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS 中。如果您需要使用 state = PyGILState_Ensure()/PyGILState_Release(state) 访问 python 对象,请获取/释放 GIL。 Here's an example(令人费解以在关闭时触发线程模块中的错误)。为避免任何问题,请在模块初始化时导入 threading

    【讨论】:

    • @ebarr 的解决方案非常方便,所以我采用了这种方法。然而,这似乎也是最有用的。由于我喜欢以各种方式做事,所以我会牢记这一点!非常感谢您的宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    相关资源
    最近更新 更多