#1 Le 17/09/2010, à 14:52
- Wacken
[PYTHON] [RESOLU] "Dérouler" une boucle facilement ?
Salut à tous,
Je me suis récemment mis à la programmation en parallèle avec OpenMP (C++), et je cherche à faire pareil avec Python. Ma demande est basique, à savoir "dérouler" une boucle. En C++, il suffit d'ajouter :
#pragma omp parallel for
for (int i=0; i<max; i++){
tab[i] = .....
}
#pragma omp barrier
Et la boucle est automatiquement parallélisée sur le nombre de CPU disponibles. Avec Python, je n'arrive pas à faire pareil (du moins, pas aussi simplement). Pour lemoment, je fais :
def Center_of_Masses_MT(self, molecules=[0], verb=2):
import multiprocessing
mutex = multiprocessing.Lock()
ps = []
parent_1, child_1 = multiprocessing.Pipe()
parent_2, child_2 = multiprocessing.Pipe()
p = multiprocessing.Process(target = self.Center_of_Masses_MT_thread, args = (mutex, child_1, mol, 0, int(self.n_frame/2), verb))
ps.append(p)
p.start()
p = multiprocessing.Process(target = self.Center_of_Masses_MT_thread, args = (mutex, child_2, mol, int(self.n_frame/2), self.n_frame, verb))
ps.append(p)
p.start()
res_thr1 = parent_1.recv()
res_thr2 = parent_2.recv()
for x in ps:
p.join()
self.CM_x[0:int(self.n_frame/2)] = res_thr1[1][:]
self.CM_x[int(self.n_frame/2):] = res_thr2[1][:]
def Center_of_Masses_MT_thread(self, mutex, child, mol, frame_i, frame_f, verb):
for i in xrange(frame_i, frame_f, 1):
for ii in mol:
M_TOT = 0.0
for iii in xrange(self.n_atom[ii]):
self.CM_x[i,ii] += self.atomic_mass[i, ii, iii] * self.x[i, ii, iii]
child.send([self.CM_x[frame_i:frame_f]])
child.close()
En gros, si je veux paralléliser sur 2 CPU, je divise manuellement mon tableau en 2, je traite chaque partie du tableau sur un CPU, puis je remets ensemble. Bon, ça marche, mais si j'ai 4 CPU à disposition, je recode tout sur base de 4 CPU ? C'est pas super pratique...
Vous auriez une astuce ?
Merci !
Dernière modification par Wacken (Le 18/09/2010, à 14:36)
Hors ligne
#2 Le 17/09/2010, à 22:04
- Jules Petibidon
Re : [PYTHON] [RESOLU] "Dérouler" une boucle facilement ?
Suis une quiche en Python, j'apprends (et tu proposes un exo sympa ), donc désolé si je tombe à coté. Mais un truc de ce style ne conviendrait pas ? (à remettre en forme avec tes variables, j'ai pas tout copié)
longueurSousTableaux = len( leTableauAAnalyser ) / nbProcesseurs
parents = []
childs = []
ps = []
res_thr = []
for np in range( 0 , nbProcesseurs ):
pipe = multiprocessing.Pipe()
parents.append( pipe )
childs.append( pipe )
borneMin = longueurSousTableaux * np
borneMax = longueurSousTableaux * ( np + 1 )
p = multiprocessing.Process( target = '...' , arg = ( '...' , '...' , '...' , borneMin , borneMax , '...' )
ps.append( p )
p.start()
res_thr.append( parent[ np ].recv() )
Dernière modification par Jules Petibidon (Le 17/09/2010, à 22:05)
Hors ligne
#3 Le 18/09/2010, à 11:44
- Wacken
Re : [PYTHON] [RESOLU] "Dérouler" une boucle facilement ?
Suis une quiche en Python, j'apprends (et tu proposes un exo sympa ), donc désolé si je tombe à coté. Mais un truc de ce style ne conviendrait pas ? (à remettre en forme avec tes variables, j'ai pas tout copié)
longueurSousTableaux = len( leTableauAAnalyser ) / nbProcesseurs parents = [] childs = [] ps = [] res_thr = [] for np in range( 0 , nbProcesseurs ): pipe = multiprocessing.Pipe() parents.append( pipe ) childs.append( pipe ) borneMin = longueurSousTableaux * np borneMax = longueurSousTableaux * ( np + 1 ) p = multiprocessing.Process( target = '...' , arg = ( '...' , '...' , '...' , borneMin , borneMax , '...' ) ps.append( p ) p.start() res_thr.append( parent[ np ].recv() )
Pas bête d'utiliser une liste de threads ! Je teste ça lundi, et je te tiens au jus
Merci !
Hors ligne
#4 Le 18/09/2010, à 14:35
- Wacken
Re : [PYTHON] [RESOLU] "Dérouler" une boucle facilement ?
Voilà la solution, proche de ce que tu as proposé :
mutex = multiprocessing.Lock()
ps = []
len_subtable = int(self.n_frame/n_cpu) + 1
parents = []
childs = []
res_thr = []
for np in range(n_cpu):
pipe = multiprocessing.Pipe()
parents.append(" ")
childs.append(" ")
parents[np], childs[np] = pipe
min = len_subtable * np
max = len_subtable * (np+1)
if max > self.n_frame:
max = self.n_frame
p = multiprocessing.Process(target = self.Center_of_Masses_MT_thread, args = (mutex, childs[np], mol, min, max, verb))
ps.append(p)
p.start()
for np in range(n_cpu):
res_thr.append(parents[np].recv())
for x in ps:
p.join()
for np in range(n_cpu):
min = len_subtable * np
max = len_subtable * (np+1)
if max > self.n_frame:
max = self.n_frame
self.n_electrons[min:max] = res_thr[np][0][:]
self.CM_x[min:max] = res_thr[np][1][:]
self.CM_y[min:max] = res_thr[np][2][:]
self.CM_z[min:max] = res_thr[np][3][:]
Hors ligne