2011-01-26 37 views
4

基本上我有一个问题,几乎embrassing并行,我想我已经达到了多快,我可以使用普通python &多处理的限制,所以我现在试图通过Cython把它带到一个较低的水平和希望打开MP。如何在Cython中使用诸如openMP之类的东西?

所以总之我想知道如何在Cython中使用openMP,或者如果我必须包装一些原始C代码并通过Cython加载/绑定到它?

或者我可以将Cython编译为C代码,然后修改C代码以在openMP编译指令中添加,然后编译为库并将其加载到Python中?

回答

1

按照cython wiki,开发商已经想过了多种选择,但我不相信他们已经实施了任何东西。

如果您的问题是并行尴尬,并且您已经拥有多处理解决方案,为什么不让每个工作进程调用一些cython代码而不是python代码?

+0

这就是我以前做的,它的工作原理,但我运行到每个进程的大内存消耗复制数据...然后我做了:http://stackoverflow.com/questions/4750141/lock-free-read-only-list-in-python通过共享内存lockfree改善了事情,但它仍然慢。所以我相信C的时间。 – Pharaun 2011-01-30 17:58:16

+0

在这种情况下,您可能最好使用支持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

0

我已经使用OpenMP没有经验,但你可能有试图zeromq运气(Python绑定包括):

easy_install pyzmq

+0

我听说过zeromq好事,应该把它放在我的事情清单上做:)不过我的问题是我想避免的进程间通信,因为这增加了开销,它爆炸的内存使用情况。这就是为什么我想要移动到打开MP/pthreads,所以我可以有一个numpy数组的共享数据阵列(只读) – Pharaun 2011-01-30 03:14:18

7

这个问题是从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] 
相关问题