You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.7 KiB
122 lines
3.7 KiB
4 years ago
|
/*******************************************************************
|
||
|
*
|
||
|
* A similar example that uses MPI_Scatterv and MPI_Gatherv
|
||
|
*
|
||
|
* The program should be run with exactly 8 processes.
|
||
|
* Process 0 initializes a matrix (x) of 8 by 8 integers and distributes
|
||
|
* the lower triangular part of the matrix to the processes using
|
||
|
* MPI_Scatterv. The processes receive different number of elements:
|
||
|
* process 0 gets one element, process 1 gets 2 elements and process i
|
||
|
* gets i+1 elements. The elements of all processes are then gathered
|
||
|
* (using MPI_Gatherv) again in another 8 by 8 matrix (res) of process 0
|
||
|
* (which is initialized with zeros) in triangular shape.
|
||
|
*
|
||
|
* ********************************************************************/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "mpi.h"
|
||
|
#define MAXPROC 8 /* Max number of procsses */
|
||
|
#define LENGTH 8 /* Size of matrix is LENGTH * LENGTH */
|
||
|
|
||
|
main(int argc, char* argv[]) {
|
||
|
int i, j, np, me;
|
||
|
const int root = 0; /* Root process in scatter */
|
||
|
|
||
|
int x[LENGTH][LENGTH]; /* Send buffer */
|
||
|
int y[LENGTH]; /* Receive buffer */
|
||
|
int res[LENGTH][LENGTH]; /* Final receive buffer */
|
||
|
|
||
|
int *sendcount, *recvcount; /* Arrays for sendcounts and recvcounts */
|
||
|
int *displs1, *displs2; /* Arrays for displacements */
|
||
|
|
||
|
MPI_Init(&argc, &argv); /* Initialize MPI */
|
||
|
MPI_Comm_size(MPI_COMM_WORLD, &np); /* Get nr of processes */
|
||
|
MPI_Comm_rank(MPI_COMM_WORLD, &me); /* Get own identifier */
|
||
|
|
||
|
/* Check that we have one process for each row in the matrix */
|
||
|
if (np != LENGTH) {
|
||
|
if (me == 0) {
|
||
|
printf("You have to use %d processes\n", LENGTH);
|
||
|
}
|
||
|
MPI_Finalize();
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
/* Allocate memory for the sendcount and displacements arrays */
|
||
|
sendcount = (int *)malloc(LENGTH*sizeof(int));
|
||
|
displs1 = (int *)malloc(LENGTH*sizeof(int));
|
||
|
|
||
|
/* Initialize sendcount and displacements arrays */
|
||
|
for (i=0; i<LENGTH; i++) {
|
||
|
sendcount[i] = i+1;
|
||
|
displs1[i] = i*LENGTH;
|
||
|
}
|
||
|
|
||
|
if (me == 0) { /* Process 0 does this */
|
||
|
/* Initialize the matrix x with values 0 .. LENGTH*LENGTH-1 */
|
||
|
for (i=0; i<LENGTH; i++) {
|
||
|
for (j=0; j<LENGTH; j++) {
|
||
|
x[i][j] = i*LENGTH+j;
|
||
|
}
|
||
|
}
|
||
|
/* Print out the matrix before it is distributed */
|
||
|
printf("The initial matrix is\n");
|
||
|
for (i=0; i<LENGTH; i++) {
|
||
|
for (j=0; j<LENGTH; j++) {
|
||
|
printf("%4d ", x[i][j]);
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Scatter the lower triangular part of array x to all proceses, place it in y */
|
||
|
MPI_Scatterv(&x, sendcount, displs1, MPI_INT, &y, sendcount[me], MPI_INT, root, MPI_COMM_WORLD);
|
||
|
|
||
|
if (me==0) {
|
||
|
/* Initialize the result matrix res with values 0 */
|
||
|
for (i=0; i<LENGTH; i++) {
|
||
|
for (j=0; j<LENGTH; j++) {
|
||
|
res[i][j] = 0;
|
||
|
}
|
||
|
}
|
||
|
/* Print out the result matrix res before gathering */
|
||
|
printf("The result matrix before gathering is\n");
|
||
|
for (i=0; i<LENGTH; i++) {
|
||
|
for (j=0; j<LENGTH; j++) {
|
||
|
printf("%4d ", res[i][j]);
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Allocate memory for the recvcount and displacements arrays */
|
||
|
recvcount = (int *)malloc(LENGTH*sizeof(int));
|
||
|
displs2 = (int *)malloc(LENGTH*sizeof(int));
|
||
|
|
||
|
for (i=0; i<LENGTH; i++) {
|
||
|
recvcount[i] = i+1;
|
||
|
displs2[i] = i*LENGTH;
|
||
|
}
|
||
|
|
||
|
/* Gather the local elements of each process to form a triangular matrix in the root */
|
||
|
MPI_Gatherv(&y, recvcount[me], MPI_INT, &res, recvcount, displs2, MPI_INT, root, MPI_COMM_WORLD);
|
||
|
|
||
|
if (me == 0) { /* Process 0 does this */
|
||
|
/* Print out the result matrix after gathering */
|
||
|
printf("The result matrix after gathering is\n");
|
||
|
for (i=0; i<LENGTH; i++) {
|
||
|
for (j=0; j<LENGTH; j++) {
|
||
|
printf("%4d ", res[i][j]);
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MPI_Finalize();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|