Abgeleitete Datentypen
. .
Kollektive Operationen
. .
Funktionsübersicht
Hilfesystem für den Message Passing Interface Standard MPI
Beispiel
Verwenden von MPI_Reduce
Beispiel für eine selbstdefinierte globale Operation -
globale Summe mit komplexen Zahlen
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 4
#define TRUE 1
typedef struct {
int real;
int imag;
} Complex;
void my_reduce_add(Complex *invec, Complex *inoutvec, int *len,
MPI_Datatype *datatype);
Complex *init_data();
int main(int argc, char *argv[]) {
int i, choice, stop;
Complex *data, *res;
int me, numprocs;
MPI_Datatype complext;
MPI_Op my_add;
MPI_User_function *fmy_reduce_add;
if (MPI_Init(&argc, &argv)!=MPI_SUCCESS) {
fprintf( stderr,"MPI_Init failed.\n");
}
MPI_Comm_rank(MPI_COMM_WORLD, &me);
if (me==0)
fprintf(stderr,"Computing global sum with complex numbers\n");
MPI_Barrier(MPI_COMM_WORLD); /* damit die Ausgabe lesbar bleibt */
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Type_contiguous(2, MPI_INT, &complext);
MPI_Type_commit(&complext);
fmy_reduce_add=(MPI_User_function *)&my_reduce_add;
MPI_Op_create(fmy_reduce_add, TRUE, &my_add);
data=init_data();
if (me==0) {
res=malloc(DATA_SIZE*2*sizeof(int));
}
MPI_Barrier(MPI_COMM_WORLD);
while (!stop) {
if (me==0) {
fprintf(stderr,"1 global sum\n 0 quit\n");
fprintf(stderr,"Your choice: ");
if (scanf("%d", &choice)!=1) {
choice=0;
}
}
MPI_Bcast(&choice,1,MPI_INT,0,MPI_COMM_WORLD);
if (choice==1) {
MPI_Reduce(data, res, DATA_SIZE, complext, my_add,
0, MPI_COMM_WORLD);
}
else stop=1;
if (me==0 && (!stop)) {
fprintf(stderr,"Proc %d: Result:\n(", me);
for (i=0; i<DATA_SIZE; i++) {
fprintf(stderr,"%d+%di ", res[i].real, res[i].imag);
}
fprintf(stderr,")\n");
}
}
MPI_Op_free(&my_add);
MPI_Type_free(&complext);
MPI_Finalize();
}
void my_reduce_add(Complex *invec, Complex *inoutvec, int *len,
MPI_Datatype *datatype) {
int i;
Complex c;
for (i=0; i<*len; i++, invec++, inoutvec++) {
c.real = invec->real + inoutvec->real;
c.imag = invec->imag + inoutvec->imag;
*inoutvec = c;
}
}
/* Erzeugt ein paar simple komplexe Zahlen - nur damit was zum Rechnen
* da ist ... */
Complex *init_data() {
Complex *data;
int i, me;
div_t x;
data=malloc(DATA_SIZE*2*sizeof(int));
MPI_Comm_rank(MPI_COMM_WORLD, &me);
for (i=0; i<DATA_SIZE; i++) {
data[i].real=i+1;
data[i].imag=i+1;
}
fprintf(stderr,"Proc %d: ", me);
for (i=0; i<DATA_SIZE; i++) {
fprintf(stderr,"%d: %d+%di ", i,data[i].real, data[i].imag);
}
fprintf(stderr,"\n");
return data;
}