在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不是必需的,如有必要,我可以不使用全局变量进行管理。