Question

Je veux effectuer facilement des communications collectives indepandently sur chaque machine de mon groupe. Disons que j'ai 4 machines avec 8 cœurs sur chacun, mon programme de FDGPD exécuter 32 tâches MPI. Ce que je voudrais est, pour une fonction donnée:

  • sur chaque hôte, une seule tâche effectuer un calcul, d'autres tâches ne font rien pendant ce calcul. Dans mon exemple, 4 tâches MPI fera le calcul, 28 autres attendent.
  • une fois que le calcul est effectué, chaque tâche MPI sur chaque effectuera une communication collective uniquement à des tâches locales (tâches en cours d'exécution sur le même hôte).

Conceptuellement, je comprends que je dois créer un communicateur pour chaque hôte. Je cherchai autour, et n'a rien trouvé à faire explicitement que. Je ne suis pas vraiment à l'aise avec les groupes MPI et des communicateurs. Voici mes deux questions:

  • est MPI_Get_processor_name est assez unique pour le comportement d'un tel?
  • plus généralement, avez-vous un morceau de code le faire?
Était-ce utile?

La solution

La spécification dit que les rendements MPI_Get_processor_name « Un spécificateur unique pour le noeud réel (par opposition au virtuel) », donc je pense que vous seriez ok avec ça. Je suppose que vous feriez un rassembler pour assembler tous les noms d'hôte et puis attribuez-lui des groupes de processeurs pour aller au large et faire leurs communicateurs; ou dup MPI_COMM_WORLD, tourner les noms dans les hachages entiers, et utiliser mpi_comm_split pour partitionner l'ensemble.

Vous pouvez également prendre l'approche et de l'utilisation janneb suggère des options spécifiques de mise en œuvre à mpirun veiller à ce que la mise en œuvre de MPI assigne des tâches de cette façon; OpenMPI utilise --byslot pour générer cet ordre; avec mpich2 vous pouvez utiliser -print-rang-carte pour la mise en correspondance.

Mais est-ce vraiment ce que vous voulez faire? Si les autres processus sont assis au ralenti tandis qu'un processeur fonctionne, comment est-ce mieux que tout le monde fait le calcul redondant? (Ou est-ce très mémoire ou E / S intensives, et vous êtes inquiet au sujet discorde?) Si vous allez faire beaucoup de cela - le traitement sur le noeud parallélisation très différent de hors-nœud parallélisation - puis vous voudrez peut-être penser à des modèles de programmation hybrides -. en cours d'exécution d'une tâche MPI par nœud et MPI_spawning ou à l'aide de sous-tâches OpenMP pour les communications sur le noeud, à la fois comme suggéré par HPM

Autres conseils

Je ne pense pas que (la pensée instruite, non définitive) que vous serez en mesure de faire ce que vous voulez entièrement à partir de votre programme MPI.

dépend du système La réponse du système à un appel à MPI_Get_processor_name; sur votre système, il pourrait revenir node00, node01, node02, node03 le cas échéant, ou il pourrait revenir my_big_computer pour quelque processeur que vous êtes réellement en cours d'exécution sur. Le premier est plus probable, mais ce n'est pas garanti.

Une stratégie serait de commencer 32 processus et, si vous pouvez déterminer quel nœud chacun est en cours d'exécution sur, partitionner votre communicateur en 4 groupes, l'un sur chaque nœud. De cette façon, vous pouvez gérer inter et intra-vous des communications que vous le souhaitez.

Une autre stratégie serait de commencer 4 processus et les épingler sur différents nœuds. Comment vous épinglez processus aux nœuds (ou processeurs) dépendra de votre exécution MPI et tout système de gestion de l'emploi que vous pourriez avoir, par exemple Grid Engine. Cela impliquera probablement la définition des variables d'environnement - mais vous ne nous dites pas quoi que ce soit sur votre système d'exécution pour que nous ne pouvons pas deviner ce qu'ils pourraient être. On pourrait alors chacun des 4 processus dynamique rogue 7 autres processus (ou 8) et la broche à ceux du même noeud que le processus initial. Pour ce faire, lire sur le sujet de la intercommunicators et la documentation de votre système d'exécution en temps.

Une troisième stratégie, maintenant il devient un peu fou, serait de commencer à 4 programmes distincts MPI (8 processus chacun), un sur chaque nœud de cluster, et de les rejoindre comme ils exécutent. Lisez à propos MPI_Comm_connect et MPI_Open_port pour plus de détails.

Enfin, pour le programme de fun, vous pourriez envisager hybridant votre programme, en cours d'exécution d'un processus MPI sur chaque nœud, et que chacun de ces processus exécuter une OpenMP-mémoire partagée (sous-).

En général votre environnement d'exécution MPI peut être contrôlé par exemple par des variables d'environnement comment les tâches sont réparties sur les nœuds. La valeur par défaut a tendance à être l'allocation séquentielle, qui est, pour votre exemple, vous auriez avec 32 tâches réparties sur 4 machines 8-core

  • machine 1: MPI classe 0-7
  • machine 2: MPI classe 8-15
  • machine 3: MPI classe 16-23
  • machine 4: MPI classe 24-31

Et oui, MPI_Get_processor_name vous devriez obtenir le nom d'hôte de sorte que vous pouvez savoir où les frontières entre les hôtes sont.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top