Last active
December 28, 2015 18:39
-
-
Save jacquerie/7544335 to your computer and use it in GitHub Desktop.
My (faulty) solution to: http://www.hpc.cineca.it/content/exercise-11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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