/* File: ex6.11_mpi_in_place.c
*
* Purpose: Compare the performance of MPI_Allgather using MPI_IN_PLACE
* with the performance of MPI_Allgather using separate
* send and receive buffers.
*
* Compile: mpicc -g -Wall -o ex6.11_mpi_in_place ex6.11_mpi_in_place.c
* Run: mpiexec -n
* per process = number of elements per process
* iters = number of iterations of allgather to use
*
* Input: None
* Output: Elapsed total time for each of the two allgathers. If DEBUG
* is set, results of each allgather on each process.
*
* IPP: Exercise 6.11
*/
#include
#include
#include
#include
int comm_sz, my_rank;
MPI_Comm comm;
void Get_input(int argc, char* argv[], int* per_proc_p, int* iters_p);
void Two_buffers(int z[], int x[], int n, int per_proc, int iters);
void In_place(int x[], int n, int per_proc, int iters);
int main(int argc, char* argv[]) {
int *x, *y, *z;
int per_proc, n, iters, i;
MPI_Init(&argc, &argv);
comm = MPI_COMM_WORLD;
MPI_Comm_size(comm, &comm_sz);
MPI_Comm_rank(comm, &my_rank);
Get_input(argc, argv, &per_proc, &iters);
n = comm_sz*per_proc;
x = malloc(n*sizeof(int));
y = x + my_rank*per_proc;
z = malloc(per_proc*sizeof(int));
for (i = 0; i < per_proc; i++) {
z[i] = my_rank + 2;
}
Two_buffers(z, x, n, per_proc, iters);
printf("\n");
for (i = 0; i < per_proc; i++) {
y[i] = my_rank + 1;
}
In_place(x, n, per_proc, iters);
free(x);
free(z);
MPI_Finalize();
return 0;
} /* main */
/*---------------------------------------------------------------------
* Get_input
*/
void Get_input(int argc, char* argv[], int* per_proc_p, int* iters_p) {
if (my_rank == 0) {
if (argc != 3) {
fprintf(stderr, "usage: mpiexec -n %s \n",
argv[0]);
*per_proc_p = *iters_p = 0;
} else {
*per_proc_p = strtol(argv[1],NULL,10);
*iters_p = strtol(argv[2],NULL,10);
}
}
MPI_Bcast(per_proc_p, 1, MPI_INT, 0, comm);
MPI_Bcast(iters_p, 1, MPI_INT, 0, comm);
if (*per_proc_p == 0) {
MPI_Finalize();
exit(0);
}
} /* Get_input */
/*---------------------------------------------------------------------
* Two_buffers
*/
void Two_buffers(int z[], int x[], int n, int per_proc, int iters) {
int i, j;
double start, finish, elapsed, my_elapsed;
# ifdef DEBUG
char string[1000];
# endif
MPI_Barrier(comm);
start = MPI_Wtime();
for (i = 0; i < iters; i++) {
MPI_Allgather(z, per_proc, MPI_INT,
x, per_proc, MPI_INT, comm);
# ifdef DEBUG
sprintf(string, "Proc %d > ", my_rank);
for (j = 0; j < n; j++)
sprintf(string + strlen(string), "%d ", x[j]);
printf("%s\n", string);
# endif
}
finish = MPI_Wtime();
my_elapsed = finish-start;
MPI_Reduce(&my_elapsed, &elapsed, 1, MPI_DOUBLE, MPI_MAX, 0, comm);
if (my_rank == 0)
printf("Elapsed for two buffers = %e secs\n", elapsed);
} /* Two_buffers */
/*---------------------------------------------------------------------
* In_place
*/
void In_place(int x[], int n, int per_proc, int iters) {
int i, j;
double start, finish, elapsed, my_elapsed;
# ifdef DEBUG
char string[1000];
# endif
MPI_Barrier(comm);
start = MPI_Wtime();
for (i = 0; i < iters; i++) {
MPI_Allgather(MPI_IN_PLACE, per_proc, MPI_INT,
x, per_proc, MPI_INT, comm);
# ifdef DEBUG
sprintf(string, "Proc %d > ", my_rank);
for (j = 0; j < n; j++)
sprintf(string + strlen(string), "%d ", x[j]);
printf("%s\n", string);
# endif
}
finish = MPI_Wtime();
my_elapsed = finish-start;
MPI_Reduce(&my_elapsed, &elapsed, 1, MPI_DOUBLE, MPI_MAX, 0, comm);
if (my_rank == 0)
printf("Elapsed for in place = %e secs\n", elapsed);
} /* In_place */