Revision [9892]
This is an old revision of MpiExerciseMpmdQt made by ToBo on 2009-08-12 01:35:12.
MPMD mit Qt
Ein kurzes Beispiel, wie MPI im Prinzip zusamen mir Qt als grafische Oberfläche genutzt werden kann.
MPMD steht für Multiple Programm Multiple Data
Qt ist eine Bibliothek, die man u.a. für grafische Oberflächen benutzen kann
Das Master Programm (master) hat eine grafische Oberfläche und unterscheidet sich zu dem Workern (worker) - deshalb MPMD. Der Master sammelt Pakete von den Workern ein und zeigt den Fortschritt mit einer Fortschrittsanzeige an. Weil das alles sehr schnell ablaufen würde ist eine Wartezeit zwischen den Empfang der einzelnen Pakete eingebaut. Der Worker hat die Aufgabe ein Paket an den Master zu senden, dann hat er Feierabend. Sind alle Pakete eingesammelt, dann muss das Programm noch per Hand beendet werden.
Probiert habe ich es auf meinem MpiMpdRing MPD-Ring mit dem folgenden Startskript, das auf dem Rechner Amygdala ausgeführt wurde.
Der Rechner auf dem der Master läuft sollte brauch einen X-Server und einen Bildschirm, oder wie in meinem Fall, wenn nur Strom und Ethernet dran ist, sollte angegeben werden wo die Ausgaben gemacht werden. Mit export DISPLAY=IP_DES_X_SERVERS:0 ; Funktioniert wunderbar.
Das Skript startet auf dem lokalen Rechner den Master und dann noch 8 Worker im MPI-Cluster.
start
#!/bin/bash
MASTER=~/10_mpmd/master
WORKER=~/10_mpmd/worker
THISHOST=`hostname`
mpiexec -l -n 1 -host $THISHOST $MASTER $1 \
: -n 8 $WORKER $1
MASTER=~/10_mpmd/master
WORKER=~/10_mpmd/worker
THISHOST=`hostname`
mpiexec -l -n 1 -host $THISHOST $MASTER $1 \
: -n 8 $WORKER $1
worker.cpp
/*
* @author Andreas Tobola
* @since Januar 2009
*
* MPI - Exercise 10
*
* This example consits of two programms master.cpp and worker.cpp
* by means of Multiple Programm Multipe Data ( MPMD)
*
* Documentation and Results:
* http://www.tnotes.de/MpiExerciseMPMD
*
* Compile using:
* mpicxx worker.cpp -o worker
*/
#include <stdio.h>
#include <mpi.h>
using namespace MPI;
#define NUM_OF_VALUES 10000
#define TAG_DOUBLE_ARRAY 0
int main(int argc, char* argv[])
{
int rank;
double buff[NUM_OF_VALUES];
Init(argc,argv);
printf("Worker\n");
// Send some data to master
COMM_WORLD.Ssend(&buff, NUM_OF_VALUES, DOUBLE, 0, TAG_DOUBLE_ARRAY);
printf("Job done! \n");
Finalize();
return 0;
}
* @author Andreas Tobola
* @since Januar 2009
*
* MPI - Exercise 10
*
* This example consits of two programms master.cpp and worker.cpp
* by means of Multiple Programm Multipe Data ( MPMD)
*
* Documentation and Results:
* http://www.tnotes.de/MpiExerciseMPMD
*
* Compile using:
* mpicxx worker.cpp -o worker
*/
#include <stdio.h>
#include <mpi.h>
using namespace MPI;
#define NUM_OF_VALUES 10000
#define TAG_DOUBLE_ARRAY 0
int main(int argc, char* argv[])
{
int rank;
double buff[NUM_OF_VALUES];
Init(argc,argv);
printf("Worker\n");
// Send some data to master
COMM_WORLD.Ssend(&buff, NUM_OF_VALUES, DOUBLE, 0, TAG_DOUBLE_ARRAY);
printf("Job done! \n");
Finalize();
return 0;
}
master.cpp
/*
* @author Andreas Tobola
* @since Januar 2009
*
* MPI - Exercise 10
*
* This example consits of two programms master.cpp and worker.cpp
* by means of Multiple Programm Multipe Data ( MPMD)
*
* Documentation and Results:
* http://www.tnotes.de/MpiExerciseMPMD
*
* Compile using:
* make
*/
#include <stdio.h>
#include <mpi.h>
// Qt includes
#include <QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>
#include <QProgressBar>
#include <QThread>
#define NUM_OF_VALUES 10000
#define TAG_DOUBLE_ARRAY 0
using namespace MPI;
class MpiThread : public QThread
{
public:
void run();
void setProgressBar(QProgressBar *pb) {m_progressbar = pb;};
private:
QProgressBar *m_progressbar; // Number of processes
};
void MpiThread::run()
{
double buff[NUM_OF_VALUES];
int size; // Number of processes
int source;
size = COMM_WORLD.Get_size();
m_progressbar->setRange(0, size-1);
printf("Master\n");
for (source=1; source<size; source++)
{
COMM_WORLD.Recv(&buff, NUM_OF_VALUES, DOUBLE, source, TAG_DOUBLE_ARRAY);
usleep(800000);
m_progressbar->setValue(source);
}
printf("Job done! You can exit the GUI. \n");
this->exit();
}
int main(int argc, char* argv[])
{
int retval; // Qt return value
Init(argc,argv);
QApplication app(argc, argv);
QWidget *window = new QWidget;
window->setWindowTitle("My MPI user interface");
QProgressBar *progressbar = new QProgressBar();
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(progressbar);
window->setLayout(layout);
window->move(100,100);
window->show();
// Run our MPI processing thread as we need this thread (main) for Qt
MpiThread *mt = new MpiThread();
mt->setProgressBar(progressbar);
mt->start();
retval = app.exec(); // Execute Qt application
Finalize();
return retval;
}
* @author Andreas Tobola
* @since Januar 2009
*
* MPI - Exercise 10
*
* This example consits of two programms master.cpp and worker.cpp
* by means of Multiple Programm Multipe Data ( MPMD)
*
* Documentation and Results:
* http://www.tnotes.de/MpiExerciseMPMD
*
* Compile using:
* make
*/
#include <stdio.h>
#include <mpi.h>
// Qt includes
#include <QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>
#include <QProgressBar>
#include <QThread>
#define NUM_OF_VALUES 10000
#define TAG_DOUBLE_ARRAY 0
using namespace MPI;
class MpiThread : public QThread
{
public:
void run();
void setProgressBar(QProgressBar *pb) {m_progressbar = pb;};
private:
QProgressBar *m_progressbar; // Number of processes
};
void MpiThread::run()
{
double buff[NUM_OF_VALUES];
int size; // Number of processes
int source;
size = COMM_WORLD.Get_size();
m_progressbar->setRange(0, size-1);
printf("Master\n");
for (source=1; source<size; source++)
{
COMM_WORLD.Recv(&buff, NUM_OF_VALUES, DOUBLE, source, TAG_DOUBLE_ARRAY);
usleep(800000);
m_progressbar->setValue(source);
}
printf("Job done! You can exit the GUI. \n");
this->exit();
}
int main(int argc, char* argv[])
{
int retval; // Qt return value
Init(argc,argv);
QApplication app(argc, argv);
QWidget *window = new QWidget;
window->setWindowTitle("My MPI user interface");
QProgressBar *progressbar = new QProgressBar();
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(progressbar);
window->setLayout(layout);
window->move(100,100);
window->show();
// Run our MPI processing thread as we need this thread (main) for Qt
MpiThread *mt = new MpiThread();
mt->setProgressBar(progressbar);
mt->start();
retval = app.exec(); // Execute Qt application
Finalize();
return retval;
}
Wie wird das Kompiliert?
- mit "qmake -project" wird aus einer C++ Datei ein QtProject-File (.pro) erzeugt
- "qmake" um MAKE-Files zu erzeugen
- Dann im Makefile "g++" durch "mpicxx" ersetzen!
- Master mit dann "make" kompilieren
- Worker mit "mpicxx worker.cpp -o worker" kompilieren
- vor dem Start muss das Skript mpiexec angepasst werden
CategoryStudiumSE
Siehe auch