2017-06-04 5 views
0

J'ai des problèmes pour exécuter ce programme dans mpi4py. Mon objectif est d'envoyer des données spécifiques à un nœud particulier (c'est pourquoi je n'utilise pas scatter). Après cela, traiter les données dans chaque nœud, et finalement rassembler tous les résultats.Envoi de données spécifiques par nœud et collecte des résultats dans MPI-Python

Apparemment, mon programme ne comprend pas comment rassembler les données de différents nœuds (peut-être parce que gather est conçu pour fonctionner avec scatter). J'ai essayé d'envoyer la date avec comm.send() et rassembler avec comm.gather(). Quand j'exécute le programme, il s'exécute pour toujours, et je ne vois aucun résultat.

Pouvez-vous m'aider à trouver comment rassembler les données des différents nœuds? Y a-t-il d'autres fonctions pour le faire? Puis-je avoir besoin d'une boucle sur les nœuds?

from mpi4py import MPI 
import numpy as np 

comm = MPI.COMM_WORLD 
size = comm.Get_size() 
rank = comm.Get_rank() 

if rank == 0: 
    data = list(np.arange(size) + 1) 
    for i in range(size): 
     comm.send(data[i], dest=i) 
else: 
    data = comm.recv(source=0) 
    data += 1 

print("rank", rank, "has data", data) 

newData = comm.gather(data, root = 0) 

if rank == 0: 

    print("master collected", newData) 
+0

Dans mon cas, il ne fonctionne pas toujours et je vois les résultats. – Shibli

Répondre

0

Vous devez utiliser Scatter. Il fait exactement ce que vous essayez de faire. Voir ici pour une illustration: http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/

+2

* "Vous devez utiliser Scatter [...] Vous ne pouvez pas rassembler sans Scatter." * Ceci est absolument faux. * "Il fait exactement ce que vous essayez de faire." * Correct. – Zulan

+0

@Zulan: Merci, ma terminologie MPI a été mélangée après avoir utilisé d'autres systèmes pendant un certain temps. :) Corrigé le texte maintenant. –

+0

Merci, les gars! Cela me clarifie certaines choses. Mais savez-vous comment je peux envoyer les éléments un par un? Mon problème est que je ne veux pas charger toutes les données et les envoyer ensuite aux nœuds (les données sont assez grandes et plus grandes que la mémoire). Idéalement, je voudrais charger les données 1, envoyer à un nœud. Ensuite, chargez les données 2, envoyez à un noeud. Etc. Enfin, rassemblez tous les résultats des nœuds. Les exemples que j'ai vus supposent que vous dispersez les données tout à la fois. @ JohnZwinck, @Zulan –

1

La raison pour laquelle cela bloque est que vous essayez d'envoyer des données du rang 0 à lui-même avant que la réception correspondante ne soit envoyée. Ceci est une impasse. Maintenant vous pouvez simplement passer l'envoi du rang 0 à lui-même - il suffit de copier les données appropriées. Ou vous pouvez utiliser une communication point à point non bloquante (isend/irecv).

Cependant, vous ne devriez pas. L'approche idiomatiques est en effet d'utiliser scatter, et il fonctionne très bien, par exemple .:

if rank == 0: 
    full_data = list(np.arange(size) + 1) 
else: 
    full_data = None 
data = comm.scatter(full_data) 
+0

En règle générale, vous pouvez utiliser 'MPI_IN_PLACE' sur le rang racine s'il ne doit pas échanger de données avec lui-même. cela étant dit, je ne sais pas si/comment 'mpi4py' gère cela –

+0

Je suis assez sûr que vous ne pouvez pas utiliser' MPI_IN_PLACE' avec les fonctions MPI décapage minuscules. – Zulan