2017-04-20 3 views
0

Je souhaite appeler une bibliothèque qui utilise la parallélisation OpenMP à partir d'un programme qui est lui-même parallèle via MPI. Si je lance mon programme MPI en utilisant un seul processus, alors quand vient le temps d'appeler la bibliothèque OpenMP, 7 threads supplémentaires (correspondant au nombre de cœurs sur ma machine) sont générés correctement et la tâche est effectuée en parallèle . Si à la place, j'exécute mon programme MPI sur 2 processus et que chaque processus appelle le programme OpenMP, chacun d'eux engendre ses propres threads au lieu de travailler ensemble comme avant, ce qui rend le calcul beaucoup plus long.Lancement du programme OpenMP à partir du programme MPI

J'ai essayé de laisser le processus maître MPI appeler la bibliothèque OpenMP pendant que les autres processus attendent, mais ces processus (cœurs physiques) ne participent pas du tout au calcul OpenMP. Dois-je dire d'une manière ou d'une autre au programme MPI qu'il devrait maintenant lancer un programme OpenMP collectivement? Une complication supplémentaire est le fait que j'exécute le programme MPI sur un cluster avec plusieurs nœuds. Il serait acceptable de lancer uniquement le programme OpenMP sur le nœud contenant le processus maître MPI. Pour être précis, mon programme MPI est écrit en Cython et utilise mpi4py. J'utilise MPICH comme implémentation MPI, mais j'espère que ce n'est pas important. Le programme OpenMP est écrit en C et je l'appelle via un wrapper Cython.

+3

Votre question est source de confusion. Le titre mentionne "programme OpenMP", mais à partir du texte, il semblerait que vous appelez des fonctions de bibliothèque qui utilisent OpenMP. S'il vous plaît clarifier car les deux sont des choses très différentes. –

+0

Votre choix de MPI est important, car les choix les plus largement utilisés de MPI (au moins sur linux) fournissent des moyens automatiques pour épingler les threads OpenMP pour séparer les cœurs. Sinon, vos processus OpenMP doivent probablement fonctionner sur des nœuds séparés, à moins que vous n'ayez à écrire des scripts pour définir des affinités et utiliser un OpenMP qui supporte l'affinité. – tim18

+0

@HristoIliev Je suppose que j'utilise une bibliothèque qui utilise OpenMP alors. –

Répondre

0

J'ai trouvé la solution.

L'appel à la bibliothèque OpenMP ne doit être effectué que par un seul processus MPI. Il n'est pas bon d'insérer une barrière MPI standard après cet appel, car une telle barrière prend 100% du temps CPU sur les processus esclaves, ne laissant aucune force de travail supplémentaire disponible à la bibliothèque OpenMP. Au lieu de cela, nous devons écrire notre propre fonction de barrière qui pique périodiquement le processus maître pour demander si l'appel OpenMP est encore terminé. Entre deux tels pings, les processus esclaves dorment pendant un intervalle de temps donné, ce qui signifie qu'ils sont libres de participer au calcul OpenMP.

Un exemple de cette logique est implémenté en Python comme suit, avec des significations évidentes de noms de variables.

def sleeping_barrier(sleep_time=0.1): 
    if master: 
     # Signal slaves to continue 
     for slave in range(1, nprocs): 
      isend(True, dest=slave) 
    else: 
     # Wait for master 
     while True: 
      sleep(sleep_time) 
      if iprobe(): 
       recv() # Remember to receive the message 
       break 

# Do OpenMP library call 
if master: 
    call_openmp_lib() 
sleeping_barrier()