Funktionsübersicht

Hilfesystem für den Message Passing Interface Standard MPI


Beispiel

Erzeugt eine Matrix und transponiert sie parallel unter Verwendung einer Funktion, die einen eigenen Kommunikator nutzt (transpose_comm ist ein duplizierter Kommunikator, daher ist ROOT in MPI_COMM_WORLD der gleiche Prozeß, welcher ROOT in transpose_comm ist) Die transponierte Matrix wird unter Verwendung eines eigenen abgeleiteten Typs an alle Prozesse gesendet.


#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>

#define ELEMS    6
#define BLOCKLEN 4
#define STRIDE   4
#define VERT     BLOCKLEN
#define HORIZ    ELEMS
#define ROOT     0

static void init_data();
static void transpose(MPI_Comm transpose_comm);
static void print_matrix(int *mat, int rows, int cols, int me);
static int  data[VERT][HORIZ];
static int  result[HORIZ][VERT];

int main(int argc, char *argv[]) {
    int           me, numprocs, i, stop=-1;
    MPI_Status    stat;
    MPI_Datatype  vectortype;
    MPI_Comm      transpose_comm;

    if (MPI_Init(&argc, &argv)!=MPI_SUCCESS) {
	fprintf(stderr,"MPI_Init failed.\n");
	return -1;
    }
    MPI_Comm_rank(MPI_COMM_WORLD, &me);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Type_vector(ELEMS, BLOCKLEN, STRIDE, MPI_INT, &vectortype);
    MPI_Type_commit(&vectortype);
    if (me==ROOT) {
	init_data();
	fprintf(stderr,"The original:\n");
	print_matrix((int *)data, VERT, HORIZ, me);
    }
    MPI_Comm_dup(MPI_COMM_WORLD, &transpose_comm);
    transpose(transpose_comm);
    MPI_Comm_free(&transpose_comm);
    if (me==ROOT) {
	/* Ergebnismatrix im Stück an alle Procs verschicken */
	for (i=1; i<numprocs; i++) {
	    MPI_Send(result,1,vectortype,i,0,MPI_COMM_WORLD);
	}
    }
    else {
	MPI_Recv(result,1,vectortype,ROOT,0,MPI_COMM_WORLD, &stat);
    }
    fprintf(stderr,"Proc %d: transposed matrix:\n", me);
    print_matrix((int *)result, HORIZ, VERT, me);
    MPI_Finalize();
}

void init_data() {
    int  i, j, count=1;

    for (i=0; i<VERT; i++) {
	for (j=0; j<HORIZ; j++, count++) {
	     data[i][j]=count;
	}
    }
}

void transpose(MPI_Comm transpose_comm) {
    int     i, j, numprocs, me, size, offset;
    int     *dummy, *dummy_trans;
    div_t   part;


    MPI_Comm_size(transpose_comm, &numprocs);
    MPI_Comm_rank(transpose_comm, &me);

    part=div(VERT, numprocs);
    size=(part.quot+(part.rem!=0));
    dummy=malloc(size*HORIZ*sizeof(int));
    MPI_Scatter(data, size*HORIZ, MPI_INT, dummy, size*HORIZ, MPI_INT,
		ROOT, transpose_comm);
    dummy_trans=malloc(size*HORIZ*sizeof(int));

    for (i=0; i<size; i++) {
	for (j=0; j<HORIZ; j++) {
	    /* Indizes vertauschen */
	    *(dummy_trans+(j*size)+i)=*(dummy+(i*HORIZ)+j);
	}
    }
    free(dummy);
    MPI_Barrier(transpose_comm);
    for (i=0; i<HORIZ; i++) {
        MPI_Gather(dummy_trans+(i*size), size, MPI_INT,
		   &result[i], size, MPI_INT,
		   ROOT, transpose_comm);
    }
    free(dummy_trans);
}
       
void print_matrix(int *mat, int rows, int cols, int me) {
    int   i, j;

    fprintf(stderr,"Proc %d prints its matrix.\n", me);
    for (i=0; i<rows; i++) {
	fprintf(stderr,"(");
	for (j=0; j<cols; j++) {
	    fprintf(stderr,"%d, ", *(mat+(i*cols)+j));
	}
	fprintf(stderr,")\n");
    }
    fprintf(stderr,"\n");
}

Makefile C-Quelltext