#include #include "mpi.h" #include /* ***************************************************** * Block Matrix Multiply on a 2*2 grid of processors * * PE 0: 00, PE1: 01, PE2: 10, PE3: 11 * ***************************************************** */ /* block size */ #define b 8 /* arr is an int* */ void printblock(int arr[b][b]) { int i,j; for(i=0;i 1 */ printf("PE0: <--> PE1: Row Exchange\n"); MPI_Recv( (int *)A01, b*b, MPI_INT, 1, 1, MPI_COMM_WORLD, &status); MPI_Send( (int *)A00, b*b, MPI_INT, 1, 2, MPI_COMM_WORLD); /* Col Exchange 0 <--> 2 */ printf("PE0: <--> PE2: Col Exchange\n"); MPI_Recv( (int *)B10, b*b, MPI_INT, 2, 3, MPI_COMM_WORLD, &status); MPI_Send( (int *)B00, b*b, MPI_INT, 2, 4, MPI_COMM_WORLD); /* Block Multiply C00 = A00*B00 + A01*B10 */ multblock(C00,A00,B00); multblock(C00,A01,B10); /* Gather */ printf("PE0: Gather C01 <-- PE1\n"); MPI_Recv( (int *)C01, b*b, MPI_INT, 1, 5, MPI_COMM_WORLD, &status); printf("PE0: Gather C10 <-- PE2\n"); MPI_Recv( (int *)C10, b*b, MPI_INT, 2, 6, MPI_COMM_WORLD, &status); printf("PE0: Gather C11 <-- PE3\n"); MPI_Recv( (int *)C11, b*b, MPI_INT, 3, 7, MPI_COMM_WORLD, &status); /* Print */ printf("PE0: Print blocks\n"); printf("\n C00: "); printblock(C00); printf("\n C01: "); printblock(C01); printf("\n C10: "); printblock(C10); printf("\n C11: "); printblock(C11); printf("\n"); break; case 1: printf("PE1: Init\n"); /* Initialize A01, B01 and C01 */ for(i=0,ioff=b;i 1 */ printf("PE1: <--> PE0: Row Exchange\n"); MPI_Send( (int *)A01, b*b, MPI_INT, 0, 1, MPI_COMM_WORLD); MPI_Recv( (int *)A00, b*b, MPI_INT, 0, 2, MPI_COMM_WORLD, &status); /* Col Exchange 1 <--> 3 */ printf("PE1: <--> PE3: Col Exchange\n"); MPI_Recv( (int *)B11, b*b, MPI_INT, 3, 3, MPI_COMM_WORLD, &status); MPI_Send( (int *)B01, b*b, MPI_INT, 3, 4, MPI_COMM_WORLD); /* Block Multiply C01 = A00*B01 + A01*B11 */ multblock(C01,A00,B01); multblock(C01,A01,B11); /* Gather */ printf("PE1: Gather C01 --> PE0\n"); MPI_Send( (int *)C01, b*b, MPI_INT, 0, 5, MPI_COMM_WORLD); break; case 2: printf("PE2: Init\n"); /* Initialize A10, B10 and C10 */ for(i=0,ioff=b;i 3 */ printf("PE2: <--> PE3: Row Exchange\n"); MPI_Recv( (int *)A11, b*b, MPI_INT, 3, 1, MPI_COMM_WORLD, &status); MPI_Send( (int *)A10, b*b, MPI_INT, 3, 2, MPI_COMM_WORLD); /* Col Exchange 0 <--> 2 */ printf("PE2: <--> PE0: Col Exchange\n"); MPI_Send( (int *)B10, b*b, MPI_INT, 0, 3, MPI_COMM_WORLD); MPI_Recv( (int *)B00, b*b, MPI_INT, 0, 4, MPI_COMM_WORLD, &status); /* Block Multiply C10 = A10*B00 + A11*B10 */ multblock(C10,A10,B00); multblock(C10,A11,B10); /* Gather */ printf("PE2: Gather C10 --> PE0\n"); MPI_Send( (int *)C10, b*b, MPI_INT, 0, 6, MPI_COMM_WORLD); break; case 3: printf("PE3: Init\n"); /* Initialize A11, B11 and C11 */ for(i=0,ioff=b;i 3 */ printf("PE3: <--> PE2: Row Exchange\n"); MPI_Send( (int *)A11, b*b, MPI_INT, 2, 1, MPI_COMM_WORLD); MPI_Recv( (int *)A10, b*b, MPI_INT, 2, 2, MPI_COMM_WORLD, &status); /* Col Exchange 1 <--> 3 */ printf("PE3: <--> PE1: Col Exchange\n"); MPI_Send( (int *)B11, b*b, MPI_INT, 1, 3, MPI_COMM_WORLD); MPI_Recv( (int *)B01, b*b, MPI_INT, 1, 4, MPI_COMM_WORLD, &status); /* Block Multiply C11 = A10*B01 + A11*B11 */ multblock(C11,A10,B01); multblock(C11,A11,B11); /* Gather */ printf("PE3: Gather C11 --> PE0\n"); MPI_Send( (int *)C11, b*b, MPI_INT, 0, 7, MPI_COMM_WORLD); break; } EXIT: MPI_Finalize(); }