Рассмотрим рекурсивный код в Cython следующей универсальной формы:
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)
Новое замечание : мой соответствующий код - просто исследование деревасобирая фрукты, все ветви независимы.Рассмотрим компьютер с несколькими ЦП. Я хотел бы распараллелить его следующим образом: каждый ЦП имеет свою очередь, когда код поступает на новый узел дерева, появляется несколько возможных новых дочерних элементов, и дочерний элемент выделяется ЦП с помощьюнаименьшая очередь.Кажется, это общий способ распараллеливания исследования дерева.
Вопрос : Какой самый простой способ реализовать такое распараллеливание?
Я пытался предшествовать моему коду 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 не важны, я могу управлятьбез глобальной переменной, если необходимо.