Question

J'apprends OpenMPI sur un cluster. Voici mon premier exemple. Je me attends la sortie montrerait réponse de différents nœuds, mais ils répondent tous du même noeud node062. Je me demande pourquoi et comment je peux réellement obtenir un rapport de différents noeuds pour afficher MPI est en fait distribuer des processus différents nœuds? Merci et salutations!

ex1.c

/* test of MPI */  
#include "mpi.h"  
#include <stdio.h>  
#include <string.h>  

int main(int argc, char **argv)  
{  
char idstr[2232]; char buff[22128];  
char processor_name[MPI_MAX_PROCESSOR_NAME];  
int numprocs; int myid; int i; int namelen;  
MPI_Status stat;  

MPI_Init(&argc,&argv);  
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
MPI_Comm_rank(MPI_COMM_WORLD,&myid);  
MPI_Get_processor_name(processor_name, &namelen);  

if(myid == 0)  
{  
  printf("WE have %d processors\n", numprocs);  
  for(i=1;i<numprocs;i++)  
  {  
    sprintf(buff, "Hello %d", i);  
    MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD); }  
    for(i=1;i<numprocs;i++)  
    {  
      MPI_Recv(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD, &stat);  
      printf("%s\n", buff);  
    }  
}  
else  
{   
  MPI_Recv(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &stat);  
  sprintf(idstr, " Processor %d at node %s ", myid, processor_name);  
  strcat(buff, idstr);  
  strcat(buff, "reporting for duty\n");  
  MPI_Send(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD);  
}  
MPI_Finalize();  

}  

ex1.pbs

#!/bin/sh  
#  
#This is an example script example.sh  
#  
#These commands set up the Grid Environment for your job:  
#PBS -N ex1  
#PBS -l nodes=10:ppn=1,walltime=1:10:00  
#PBS -q dque    

# export OMP_NUM_THREADS=4  

 mpirun -np 10 /home/tim/courses/MPI/examples/ex1  

compiler et exécuter:

[tim@user1 examples]$ mpicc ./ex1.c -o ex1   
[tim@user1 examples]$ qsub ex1.pbs  
35540.mgt  
[tim@user1 examples]$ nano ex1.o35540  
----------------------------------------  
Begin PBS Prologue Sat Jan 30 21:28:03 EST 2010 1264904883  
Job ID:         35540.mgt  
Username:       tim  
Group:          Brown  
Nodes:          node062 node063 node169 node170 node171 node172 node174 node175  
node176 node177  
End PBS Prologue Sat Jan 30 21:28:03 EST 2010 1264904883  
----------------------------------------  
WE have 10 processors  
Hello 1 Processor 1 at node node062 reporting for duty  
Hello 2 Processor 2 at node node062 reporting for duty        
Hello 3 Processor 3 at node node062 reporting for duty        
Hello 4 Processor 4 at node node062 reporting for duty        
Hello 5 Processor 5 at node node062 reporting for duty        
Hello 6 Processor 6 at node node062 reporting for duty        
Hello 7 Processor 7 at node node062 reporting for duty        
Hello 8 Processor 8 at node node062 reporting for duty        
Hello 9 Processor 9 at node node062 reporting for duty  

----------------------------------------  
Begin PBS Epilogue Sat Jan 30 21:28:11 EST 2010 1264904891  
Job ID:         35540.mgt  
Username:       tim  
Group:          Brown  
Job Name:       ex1  
Session:        15533  
Limits:         neednodes=10:ppn=1,nodes=10:ppn=1,walltime=01:10:00  
Resources:      cput=00:00:00,mem=420kb,vmem=8216kb,walltime=00:00:03  
Queue:          dque  
Account:  
Nodes:  node062 node063 node169 node170 node171 node172 node174 node175 node176  
node177  
Killing leftovers...  

End PBS Epilogue Sat Jan 30 21:28:11 EST 2010 1264904891  
----------------------------------------

Mise à jour:

Je voudrais exécuter plusieurs tâches d'arrière-plan dans un seul script PBS, de sorte que les emplois peuvent fonctionner en même temps. par exemple. dans l'exemple ci-dessus, j'ai ajouté un autre appel à lancer EX1 et changer les deux pistes pour être en arrière-plan ex1.pbs

#!/bin/sh  
#  
#This is an example script example.sh  
#  
#These commands set up the Grid Environment for your job:  
#PBS -N ex1  
#PBS -l nodes=10:ppn=1,walltime=1:10:00  
#PBS -q dque 

echo "The first job starts!"  
mpirun -np 5 --machinefile /home/tim/courses/MPI/examples/machinefile /home/tim/courses/MPI/examples/ex1 &  
echo "The first job ends!"  
echo "The second job starts!"  
mpirun -np 5 --machinefile /home/tim/courses/MPI/examples/machinefile /home/tim/courses/MPI/examples/ex1 &  
echo "The second job ends!" 

(1) Le résultat est bien après qsub ce script avec ex1 précédent exécutable compilé.

The first job starts!  
The first job ends!  
The second job starts!  
The second job ends!  
WE have 5 processors  
WE have 5 processors  
Hello 1 Processor 1 at node node063 reporting for duty        
Hello 2 Processor 2 at node node169 reporting for duty        
Hello 3 Processor 3 at node node170 reporting for duty        
Hello 1 Processor 1 at node node063 reporting for duty        
Hello 4 Processor 4 at node node171 reporting for duty        
Hello 2 Processor 2 at node node169 reporting for duty        
Hello 3 Processor 3 at node node170 reporting for duty        
Hello 4 Processor 4 at node node171 reporting for duty  

(2) Cependant, je pense que le temps d'exécution de EX1 est trop rapide et probablement les deux tâches de fond n'ont pas beaucoup de temps en cours d'exécution se chevauchent, ce qui est le cas lorsque je demande la même manière à mon vrai projet. Donc, j'ai ajouté le sommeil (30) ex1.c pour prolonger la durée de EX1 de sorte que deux emplois en cours d'exécution en arrière-plan EX1 sera en cours d'exécution en même temps presque tout le temps.

/* test of MPI */  
#include "mpi.h"  
#include <stdio.h>  
#include <string.h>  
#include <unistd.h>

int main(int argc, char **argv)  
{  
char idstr[2232]; char buff[22128];  
char processor_name[MPI_MAX_PROCESSOR_NAME];  
int numprocs; int myid; int i; int namelen;  
MPI_Status stat;  

MPI_Init(&argc,&argv);  
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
MPI_Comm_rank(MPI_COMM_WORLD,&myid);  
MPI_Get_processor_name(processor_name, &namelen);  

if(myid == 0)  
{  
  printf("WE have %d processors\n", numprocs);  
  for(i=1;i<numprocs;i++)  
  {  
    sprintf(buff, "Hello %d", i);  
    MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD); }  
    for(i=1;i<numprocs;i++)  
    {  
      MPI_Recv(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD, &stat);  
      printf("%s\n", buff);  
    }  
}  
else  
{   
  MPI_Recv(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &stat);  
  sprintf(idstr, " Processor %d at node %s ", myid, processor_name);  
  strcat(buff, idstr);  
  strcat(buff, "reporting for duty\n");  
  MPI_Send(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD);  
}  

sleep(30); // new added to extend the running time
MPI_Finalize();  

}  

Mais après recompilation et QSUB encore, les résultats ne semble pas bien. Il y a des processus avortés. en ex1.o35571:

The first job starts!  
The first job ends!  
The second job starts!  
The second job ends!  
WE have 5 processors  
WE have 5 processors  
Hello 1 Processor 1 at node node063 reporting for duty  
Hello 2 Processor 2 at node node169 reporting for duty  
Hello 3 Processor 3 at node node170 reporting for duty  
Hello 4 Processor 4 at node node171 reporting for duty  
Hello 1 Processor 1 at node node063 reporting for duty  
Hello 2 Processor 2 at node node169 reporting for duty  
Hello 3 Processor 3 at node node170 reporting for duty  
Hello 4 Processor 4 at node node171 reporting for duty  
4 additional processes aborted (not shown)  
4 additional processes aborted (not shown)  

ex1.e35571:

mpirun: killing job...  
mpirun noticed that job rank 0 with PID 25376 on node node062 exited on signal 15 (Terminated).  
mpirun: killing job...  
mpirun noticed that job rank 0 with PID 25377 on node node062 exited on signal 15 (Terminated).  

Je me demande pourquoi il y a des processus avorté? Comment puis-je qsub tâches de fond correctement dans un script PBS?

Était-ce utile?

La solution

deux choses: vous devez indiquer où mpi lancer des processus, en supposant que vous utilisez mpich, regardez la section d'aide mpiexec et trouver le fichier de machine ou description équivalente. À moins que le fichier de la machine est fourni, il fonctionne sur un hôte

PBS crée automatiquement le fichier nœuds. Son nom est stocké dans la variable d'environnement PBS_NODEFILE disponible dans le fichier de commande PBS. Effectuez les opérations suivantes:

mpiexec -machinefile $PBS_NODEFILE ...

si vous utilisez mpich2, vous avez deux votre démarrage d'exécution à l'aide mpi mpdboot. Je ne me rappelle pas les détails de la commande, vous devrez lire la page man. Rappelez-vous de créer un fichier secret, sinon mpdboot échouera.

Je lis votre message à nouveau, vous utiliserez mpi ouvert, vous devez toujours fournir fichier machines à mpiexec commande, mais vous ne devez pas salir avec mpdboot

Autres conseils

Par défaut PBS (Je suppose couple) alloue des noeuds en mode exclusif, de sorte que seule une tâche par noeud. Il est un peu différent si vous avez plusieurs processeurs, plus probablement un processus par CPU. PBS peut être modifiée pour affecter signe de tête en mode temps partagé, consultez la page de l'homme de l'histoire de qmgr.long courte, très probablement vous n'aurez pas des noeuds qui se chevauchent dans le fichier de noeud, depuis le fichier nœud est créé lorsque les ressources sont disponibles plutôt que au moment de la la soumission.

dans le but de PBS est le contrôle des ressources, le temps le plus souvent, l'attribution des noeuds (automatique).

commandes dans le fichier PBS sont exécutées séquentiellement. Vous pouvez mettre des processus en arrière-plan, mais peut-être vaincre objectif d'allocation des ressources, mais je ne sais pas exactement votre flux de travail. J'ai utilisé les processus d'arrière-plan dans les scripts PBS pour copier des données avant le programme principal se déroule en parallèle, en utilisant et. PBS scénario est en fait juste un script shell.

vous pouvez supposer que PBS ne sait rien au sujet de fonctionnement interne hors de votre script. Vous pouvez certainement exécuter plusieurs processus / threads dans le par vous script.if faites, c'est à vous et votre système d'exploitation pour allouer noyau / processeurs de façon équilibrée. Si vous êtes sur le programme multithread, l'approche la plus probable est d'exécuter un processus de mpi pour le noeud, puis frayer threads OpenMP.

Faites-moi savoir si vous avez besoin des éclaircissements

En tant que diagnostic, essayez d'insérer ces déclarations immédiatement après votre appel à MPI_GET_PROCESSOR_NAME.

printf("Hello, world.  I am %d of %d on %s\n", myid, numprocs, name);
fflush(stdout); 

Si tous les processus de retour le même identifiant de nœud à cela, il suggérerait à moi que vous ne comprenez pas tout à fait ce qui se passe sur le système de gestion de l'emploi et groupe - PBS est peut-être (en dépit de vous dire apparemment autrement) mettre l'ensemble des 10 processus sur un nœud (vous disposez de 10 cœurs dans un nœud?).

Si cela donne des résultats différents, qui me suggère quelque chose de mal avec votre code, mais il semble OK pour moi.

Il y a un bug dans votre code sans lien avec mpich, vous i avez réutilisé dans vos deux boucles.

for(i=1;i<numprocs;i++)  
  {  
    sprintf(buff, "Hello %d", i);  
    MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD); }  
    for(i=1;i<numprocs;i++)  

La seconde pour les choses mess volonté de la boucle vers le haut.

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