/*
* example for dynamic task creation
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
#define WORKER "slave"
#define TAG_WORK 1
#define TAG_RESULT 2
#define DEFAULT_ANZAHL 10000L /* Defaultwert für Anzahl */
void main(int argc, char *argv[]) {
int nTasks; /* number of tasks */
int maxproc, nslaves; /* number of tasks: max, slaves */
int *maxproc_p, flag;
long total; /* total number of points */
long mytotal; /* number of points per process */
long myhits; /* number of hits per process */
long totalhits; /* total number of hits */
double pi; /* result */
MPI_Comm slavecomm; /* intercomm */
/* Anzahl der zu wuerfelnden Punkte pro Prozessor */
if (argc != 2) {
total = DEFAULT_ANZAHL;
} else {
total = 1000 * atol(argv[1]);
}
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nTasks);
if (nTasks != 1) {
printf("Warning: program should be started with just one task!\n");
}
/* get maximal number of tasks */
MPI_Attr_get(MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, &maxproc_p, &flag);
if (flag) {
maxproc = *maxproc_p;
} else {
printf("MPI_UNIVERSE_SIZE not set! Proceed fingers crossed\n");
maxproc = 4;
}
printf("MPI_UNIVERSE_SIZE = %d\n", maxproc);
/* compute number of slaves */
if (maxproc > 1) {
nslaves = maxproc - 1;
} else {
nslaves = 2;
printf("maxproc to small, trying to get 2 slaves!\n");
}
MPI_Spawn(WORKER, MPI_ARGV_NULL, nslaves, MPI_INFO_NULL, 0,
MPI_COMM_WORLD, &slavecomm, MPI_ERRCODES_IGNORE);
/* compute partial work for first part and send it to slaves */
mytotal = (long) ceil(total/nslaves);
total = nslaves * mytotal; /* correct total */
MPI_Bcast(&mytotal, 1, MPI_LONG, MPI_ROOT, slavecomm);
/* combine partial results */
totalhits = 0;
MPI_Reduce(&myhits, &totalhits, 1, MPI_LONG, MPI_SUM, MPI_ROOT, slavecomm);
/* compute final result */
pi = totalhits/(double)total*4;
printf("using %2d tasks: PI = %lf\n", nslaves, pi);
MPI_Finalize();
}