使用并行化C程序扩展Python(在OMP下)

时间:2012-12-12 12:02:57

标签: python c parallel-processing openmp

所以,我正在考虑对我得到的python组件进行C扩展。然后,我想到使用OMP从最终运行Python + C组合解决方案的机器中获取尽可能多的优势。

有没有人尝试类似的东西?是否有任何特定的,不合理的细节,而不是使这样的解决方案失败?

提前致谢!

2 个答案:

答案 0 :(得分:3)

Cythonparallel.prange()example

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

答案 1 :(得分:2)

我已成功完成了射电天文学中的大型数据挖掘任务。有关示例,请参阅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)