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 |