Skip to content

Instantly share code, notes, and snippets.

@jacquerie
Last active December 28, 2015 18:39
Show Gist options
  • Save jacquerie/7544335 to your computer and use it in GitHub Desktop.
Save jacquerie/7544335 to your computer and use it in GitHub Desktop.
#include <mpi.h>
#include <stdio.h>
#define ROOT 0
#define REORDER 0
int main (int argc, char** argv) {
int i, j, local_rank, rank, size;
int rank_src, rank_dest, north, east, south, west;
double avg;
int rows_rank, cols_rank, rows_size, cols_size, sum;
double rows_avg, cols_avg;
// Declare the torus communicator
MPI_Comm torus;
int dims[] = { 0, 0 };
int periods[] = { 1, 1 };
// Declare a dummy status
MPI_Status status;
// Declare rows and columns communicators
MPI_Comm rows, cols;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Allocate the received ranks
int received_ranks[2 * size];
// Create the torus communicator
MPI_Dims_create(size, 2, dims);
MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, REORDER, &torus);
// Allocate the received averages
double received_rows_avgs[dims[0]];
double received_cols_avgs[dims[1]];
// 1. Compare the local rank with the global MPI_COMM_WORLD rank.
MPI_Comm_rank(torus, &local_rank);
int sent_ranks[] = { rank, local_rank };
MPI_Gather(sent_ranks, 2, MPI_INT, received_ranks, 2, MPI_INT, ROOT, MPI_COMM_WORLD);
if (rank == ROOT) {
for (i = 0; i < size; i++) {
printf("%d\t%d\n", received_ranks[2*i], received_ranks[2*i + 1]);
}
printf("\n");
}
// 2.Calculate on each task the average between its local rank and the local rank from each of its neighbours (north, east, south, west).
MPI_Cart_shift(torus, 0, -1, &rank_src, &rank_dest);
MPI_Sendrecv(&local_rank, 1, MPI_INT, rank_dest, 0, &north, 1, MPI_INT, rank_src, 0, torus, &status);
MPI_Cart_shift(torus, 1, 1, &rank_src, &rank_dest);
MPI_Sendrecv(&local_rank, 1, MPI_INT, rank_dest, 0, &east, 1, MPI_INT, rank_src, 0, torus, &status);
MPI_Cart_shift(torus, 0, 1, &rank_src, &rank_dest);
MPI_Sendrecv(&local_rank, 1, MPI_INT, rank_dest, 0, &south, 1, MPI_INT, rank_src, 0, torus, &status);
MPI_Cart_shift(torus, 1, -1, &rank_src, &rank_dest);
MPI_Sendrecv(&local_rank, 1, MPI_INT, rank_dest, 0, &west, 1, MPI_INT, rank_src, 0, torus, &status);
avg = (north + east + south + west + local_rank) / 5.0;
// 3. Calculate the average of the local ranks on each row and column.
int select_rows[] = { 1, 0 };
MPI_Cart_sub(torus, select_rows, &rows);
MPI_Comm_rank(rows, &rows_rank);
MPI_Comm_size(rows, &rows_size);
MPI_Reduce(&local_rank, &sum, 1, MPI_INT, MPI_SUM, ROOT, rows);
if (rows_rank == ROOT) {
rows_avg = ((double) sum) / rows_size;
printf("%f\n", rows_avg);
}
MPI_Comm_free(&rows);
int select_cols[] = { 0, 1 };
MPI_Cart_sub(torus, select_cols, &cols);
MPI_Comm_rank(cols, &cols_rank);
MPI_Comm_size(cols, &cols_size);
MPI_Reduce(&local_rank, &sum, 1, MPI_INT, MPI_SUM, ROOT, cols);
if (cols_rank == ROOT) {
cols_avg = ((double) sum) / cols_size;
printf("%f\n", cols_avg);
}
MPI_Comm_free(&cols);
// Final cleanup
MPI_Comm_free(&torus);
MPI_Finalize();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment