在Cython中并行化递归代码的最简单方法是什么

时间:2019-05-22 01:07:29

标签: python recursion parallel-processing multiprocessing cython

在Cython中考虑以下 generic 形式的递归代码:

cpdef function(list L1, list L2):
    global R
    cdef int i,n #...
    cdef list LL1,LL2 #...
    # ...
    # core of the code
    # ...
    n= #...
    for i in range(n):
        LL1= #...
        LL2= #...
        function(LL1,LL2)
  

新话语:我的相关代码只是收集果实的树木探索,所有分支都是独立的。考虑一台计算机   几个CPU,我想并行化如下:每个CPU都有一个   队列,当代码到达树的新节点时,有   几个可能的新子代,并将一个子代分配给CPU   与最小的队列。这似乎是并行化一个   树木探索。

问题:实现这种并行化的最简单方法是什么?

我尝试在代码之前加from cython.parallel import prange,然后用range(n)替换prange(n),但出现错误:

prange() can only be used without the GIL

然后我将prange(n)替换为prange(n,nogil=True),但遇到很多错误,例如:

Assignment of Python object not allowed without gil
Coercion from Python not allowed without the GIL
Indexing Python object not allowed without gil
Calling gil-requiring function not allowed without gil

以下是我要并行化的相关代码:

cpdef SmithFormIntegralPointsSuperFiltred(list L, list LL, list co, list A):
    global R,clp
    cdef int i,j,k,l,ll,p,a,c,cc,rc,m,f,b,z,zz,lp,s,la,kk,ccc,zo,jj,lM
    cdef list LB,S,P,CP,F,cco,PP,PPP,coo,V,LLP,LLPO,Mi,M
    m=10000
    l=len(L)
    ll=len(LL)
    la=len(A[0])
    z=0
    zz=0
    P=[]
    for i in range(l):
        if L[i]==-1:
            P.append(i)
    lp=len(P)
    if lp<clp:
        print([lp,L])
        clp=lp
    if lp==0:
        F=list(matrix(LL)*vector(L))
        b=0
        for f in F:
            if f<0:
                b=1
                break
        if b==0:    
            R.append(F); print(L)
    if lp>0:
        PP=[m for j in range(lp)]
        PPP=[[] for j in range(lp)]
        for i in range(ll):
            a=0
            for j in P:
                if LL[i][j]>0:
                    a+=1
                    if a==2:
                        break
            if a<=1:
                CP=list(set(range(l))-set(P))
                c=sum([LL[i][j]*L[j] for j in CP])
                if a==0 and c<0:
                    z=1
                    break
                if a==1 or (a==0 and c>=0):
                    LLPO=[LL[i][P[k]] for k in range(lp)]
                    for j in range(lp):
                        LLP=LLPO[:]
                        cc=-LLP[j]
                        if cc<>0:
                            del LLP[j]
                            if LLP==[0 for k in range(lp-1)]:
                                PPP[j].append(i)
                            zz=1
                            if cc>0:
                                rc=c/cc
                                if rc<PP[j]:
                                    PP[j]=rc
        if z==0 and zz==1:
            zo=0
            for i in range(lp):
                Mi=[]
                if PPP[i]<>[]:
                    for j in range(PP[i]+1):
                        ccc=0
                        coo=copy.deepcopy(co)
                        for k in PPP[i]:
                            s=sum([LL[k][kk]*L[kk] for kk in range(l)])+(j+1)*LL[k][P[i]]
                            V=A[k]
                            for kk in range(la):
                                if V[kk]<>0:
                                    if s>=0 and coo[kk][V[kk]]>=s:
                                        coo[kk][V[kk]]-=s
                                    else:
                                        ccc=1
                                        break
                            if ccc==1:
                                break
                        if ccc==0:
                            Mi.append(j)
                    if len(Mi)<m:
                        zo=1
                        m=len(Mi)
                        M=Mi
                        p=i
            if zo==1:
                M.reverse()
                lM=len(M)                                       
                for jj in range(lM):
                    j=M[jj]
                    cco=copy.deepcopy(co)
                    for k in PPP[p]:
                        s=sum([LL[k][kk]*L[kk] for kk in range(l)])+(j+1)*LL[k][P[p]]
                        V=A[k]
                        for kk in range(la):
                            if V[kk]<>0:
                                cco[kk][V[kk]]-=s
                    LB=L[:]
                    LB[P[p]]=j
                    SmithFormIntegralPointsSuperFiltred(LB,LL,cco,A)

全局变量R和clp不是必需的,如有必要,我可以不使用全局变量进行管理。

0 个答案:

没有答案