基本上我有一个问题,几乎embrassing并行,我想我已经达到了多快,我可以使用普通python &多处理的限制,所以我现在试图通过Cython把它带到一个较低的水平和希望打开MP。如何在Cython中使用诸如openMP之类的东西?
所以总之我想知道如何在Cython中使用openMP,或者如果我必须包装一些原始C代码并通过Cython加载/绑定到它?
或者我可以将Cython编译为C代码,然后修改C代码以在openMP编译指令中添加,然后编译为库并将其加载到Python中?
基本上我有一个问题,几乎embrassing并行,我想我已经达到了多快,我可以使用普通python &多处理的限制,所以我现在试图通过Cython把它带到一个较低的水平和希望打开MP。如何在Cython中使用诸如openMP之类的东西?
所以总之我想知道如何在Cython中使用openMP,或者如果我必须包装一些原始C代码并通过Cython加载/绑定到它?
或者我可以将Cython编译为C代码,然后修改C代码以在openMP编译指令中添加,然后编译为库并将其加载到Python中?
按照cython wiki,开发商已经想过了多种选择,但我不相信他们已经实施了任何东西。
如果您的问题是并行尴尬,并且您已经拥有多处理解决方案,为什么不让每个工作进程调用一些cython代码而不是python代码?
如果有人跌倒了这样一个问题:
现在,有在通过cython.parallel模块用Cython为OpenMP的直接支持,看到 http://docs.cython.org/src/userguide/parallelism.html
这个问题是从3年前和现在用Cython有支持OpenMP后端的可用功能。例如参见the documentation here。一个非常方便的功能是prange
。这是如何使用prange
可以实现一个(相当天真的)功能的一个例子。
不要忘记编译通过"/opemmp"
参数传递给C编译器。
import numpy as np
cimport numpy as np
import cython
from cython.parallel import prange
ctypedef np.double_t cDOUBLE
DOUBLE = np.float64
def mydot(np.ndarray[cDOUBLE, ndim=2] a, np.ndarray[cDOUBLE, ndim=2] b):
cdef np.ndarray[cDOUBLE, ndim=2] c
cdef int i, M, N, K
c = np.zeros((a.shape[0], b.shape[1]), dtype=DOUBLE)
M = a.shape[0]
N = a.shape[1]
K = b.shape[1]
for i in prange(M, nogil=True):
multiply(&a[i,0], &b[0,0], &c[i,0], N, K)
return c
@cython.wraparound(False)
@cython.boundscheck(False)
@cython.nonecheck(False)
cdef void multiply(double *a, double *b, double *c, int N, int K) nogil:
cdef int j, k
for j in range(N):
for k in range(K):
c[k] += a[j]*b[k+j*K]
这就是我以前做的,它的工作原理,但我运行到每个进程的大内存消耗复制数据...然后我做了:http://stackoverflow.com/questions/4750141/lock-free-read-only-list-in-python通过共享内存lockfree改善了事情,但它仍然慢。所以我相信C的时间。 – Pharaun 2011-01-30 17:58:16
在这种情况下,您可能最好使用支持OpenMP的C(或Fortran)代码。我发现http://crashtestastronomer.wordpress.com/2009/07/30/using-a-multithreaded-fortran-module-in-python-using-f2py/上的说明对fortran来说工作得很好,你可以做在C中有类似的东西,然后用cython方便地包装它。我比C更喜欢Fortran 90,因为您可以像使用numpy在Python中一样编写数组操作。 – DaveP 2011-01-31 06:45:49