Frage

Ich lerne OpenMPI auf einem Cluster. Hier ist mein erstes Beispiel. Ich erwarte, dass der Ausgang würde Antwort von verschiedenen Knoten zeigen, aber sie alle, die es von dem gleichen Knoten node062. Ich frage mich nur, warum und wie kann ich eigentlich Bericht von verschiedenen Knoten bekommen zu zeigen, MPI tatsächlich Prozesse zu verschiedenen Knoten verteilt? Danke und Grüße!

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  

kompilieren und ausführen:

[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  
----------------------------------------

UPDATE:

Ich möchte mehrere Hintergrundjobs in einem einzigen PBS Skript ausgeführt werden soll, so dass die Arbeitsplätze in der gleichen Zeit ausgeführt werden können. z.B. in dem obigen Beispiel habe ich einen weiteren Anruf EX1 und ändern beide Läufe laufen Hintergrund in ex1.pbs sein

#!/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) Das Ergebnis ist in Ordnung, nachdem qsub dieses Skript mit früheren kompilierte ausführbarer Datei EX1.

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) Aber ich denke, die Laufzeit der EX1 zu schnell ist und wahrscheinlich die beiden Hintergrundjobs haben nicht viel Laufzeit überlappen, was nicht der Fall ist, wenn ich den gleichen Weg zu meinem realen Projekt anzuwenden. Also ich Schlaf (30) zu ex1.c hinzugefügt, um die Laufzeit der EX1 zu erweitern, so dass zwei Jobs EX1 laufen im Hintergrund laufen werden gleichzeitig fast die ganze Zeit.

/* 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();  

}  

Aber nach Neuübersetzung und qsub wieder, scheinen die Ergebnisse nicht in Ordnung. Es gibt Prozesse abgebrochen. in 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)  

in 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).  

Ich frage mich, warum es Prozesse abgebrochen? Wie kann ich qsub Hintergrundjobs korrekt in einem PBS-Skript?

War es hilfreich?

Lösung

Paar Dinge: Sie müssen mpi wo man Start-Prozesse sagen, vorausgesetzt, Sie mpich, Blick auf mpiexec Hilfe-Bereich verwenden und Maschinendatei oder eine gleichwertige Beschreibung. Es sei denn, Maschinen Datei zur Verfügung gestellt wird, wird es auf einem Host laufen

PBS erstellt automatisch Knoten Datei. Sein Name ist in PBS_NODEFILE Umgebungsvariable in PBS Befehlsdatei gespeichert. Versuchen Sie Folgendes:

mpiexec -machinefile $PBS_NODEFILE ...

Wenn Sie mpich2 verwenden, haben Sie zwei Boote Ihrer mpi Laufzeit mit mpdboot. Ich erinnere mich nicht die Details Befehl, müssen Sie Manpage zu lesen. Denken Sie daran, erstellen geheime Datei sonst mpdboot wird fehlschlagen.

Ich lese Ihre Post wieder, Sie öffnen mpi verwenden, müssen Sie noch Maschinen Datei mpiexec Befehl liefern, aber Sie müssen sich nicht mit mpdboot

Andere Tipps

Mit dem Standard-PBS (Ich gehe davon aus Drehmoment) zuordnet Knoten im exklusiven Modus, so dass nur ein Job pro Knoten. Es ist ein bisschen anders, wenn Sie mehrere Prozessoren, höchstwahrscheinlich ein Prozess pro CPU haben. PBS geändert werden kann Nicken in Time-Sharing-Modus zuzuweisen, Blick auf Mann Seite der Geschichte kurz qmgr.long, wahrscheinlich werden Sie nicht überlappenden Knoten in der Knotendatei haben, da der Knoten-Datei erstellt wird, wenn die Ressourcen verfügbar sind und nicht zum Zeitpunkt der Unterwerfung.

Der Zweck PBS ist Ressourcensteuerung, am üblichsten Zeit Knotenzuweisung (automatisch).

Befehle in PBS-Datei werden nacheinander ausgeführt. Sie können Prozesse im Hintergrund setzen, aber das könnte Zweck der Ressourcenallokation zu besiegen, aber ich weiß nicht, Ihre genaue Workflow. Ich verwenden, um die Hintergrundprozesse in PBS-Skripten Daten vor Hauptprogramm läuft parallel zu kopieren, mit &. PBS-Skript ist eigentlich nur ein Shell-Skript.

Sie können davon ausgehen, dass PBS weiß nichts über Innenleben aus Ihrem Skript. Sie können natürlich auch mehrere Prozesse / Threads in der über laufen script.if Sie tun so, dass Sie und Ihr Betriebssystem ist bis zu Core / Prozessoren in ausgewogener Weise zuteilen. Wenn Sie auf Multi-Thread-Programm sind, höchstwahrscheinlich Ansatz ist ein mpi Prozess für den Knoten laufen und dann OpenMP Threads erzeugen.

Lassen Sie mich wissen, wenn Sie Erläuterungen benötigen

Als Diagnose, versuchen Sie diese Anweisungen direkt nach Ihrem Aufruf zum MPI_GET_PROCESSOR_NAME einlegen.

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

Wenn alle Prozesse derselben Knoten-ID zu, dass zurückkehren, wäre es mir vor, dass Sie nicht ganz verstehen, was auf dem Job-Management-System wird auf und Cluster - vielleicht PBS ist (trotz Sie anscheinend nicht anders sagen) alle 10 Prozesse auf einem Knoten setzen (tun Sie 10 Kerne in einem Knoten haben?).

Wenn diese unterschiedliche Ergebnisse, die suggeriert mir etwas falsch mit Ihrem Code, wenn es OK für mich aussieht.

Es ist ein Fehler im Code in keinem Zusammenhang mit mpich, haben Sie mich in Ihren zwei Schleifen wiederverwendet werden.

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++)  

Die zweite for-Schleife Willen durcheinander zu bringen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top