#include #include #include #include MPI_Comm cart_comm; int cart_rank; void SendToRootAndWrite(int sendvalue, int np, int nq) { int *values, numvalues; int i, j; numvalues=1; if ( (values = (int*)malloc(np*sizeof(int))) == NULL ) { fprintf(stderr,"Failed to allocate values[%d]",np); exit(-1); } values[0] = values[1] = 0; if ( MPI_Gather ( &sendvalue, 1, MPI_INTEGER, values, numvalues, MPI_INTEGER, 0, cart_comm ) != MPI_SUCCESS ) exit(-1); if ( cart_rank == 0 ) { printf("After sending, values = \n"); for (i=0; i < nq; i++ ) { for (j=0; j < nq; j++ ) { np = i + nq*j; printf(" %d",values[np]); } printf("\n"); } } } int main(int argc, char **argv) { int i, j, p, q, rc; float p_real; int my_rank, source, dest; int ldims[2], coords[2]; int periods[2], reorder; MPI_Status status; int cval; if ( MPI_Init(&argc, &argv) != MPI_SUCCESS ) exit(-1); if ( MPI_Comm_size(MPI_COMM_WORLD, &p) != MPI_SUCCESS ) exit(-1); if ( MPI_Comm_rank(MPI_COMM_WORLD, &my_rank) != MPI_SUCCESS ) exit(-1); p_real = p; q = sqrt(p_real); if ( q*q != p ) { if ( my_rank == 0 ) printf(" %d**2 != %d: program terminates",q,p); MPI_Finalize(); exit(-1); } /* Create new communicator QxQ dimensions */ ldims[0] = ldims[1] = q; periods[0] = periods[1] = 1; // true reorder = 0; // false if ( MPI_Cart_create(MPI_COMM_WORLD,2,ldims,periods,reorder,&cart_comm) != MPI_SUCCESS ) exit(-1); /* Get process coordinates */ if ( MPI_Comm_rank(cart_comm, &cart_rank) != MPI_SUCCESS ) exit(-1); if ( MPI_Cart_coords(cart_comm, cart_rank, 2, coords) != MPI_SUCCESS ) exit(-1); /* Each process defines a value equal to 2nd coordinate */ cval = 100*(1+coords[0])+(1+coords[1]); printf("For process %d coords=(%d,%d), cval = %d\n",cart_rank, coords[0],coords[1],cval); /* Collectively send value to root process */ SendToRootAndWrite(cval,p,q); /* Now send value to the process on the right */ if ( cart_rank == 0 ) fprintf(stdout,"Send values in direction 0\n"); if ( MPI_Cart_shift(cart_comm, 0, 1, &source, &dest) != MPI_SUCCESS ) exit(-1); if ( MPI_Sendrecv_replace(&cval, 1, MPI_INTEGER, dest, 0, source, 0, cart_comm, &status) != MPI_SUCCESS ) exit(-1); /* Again, collectively send value to root process */ SendToRootAndWrite(cval,p,q); /* Now send value downward */ if ( cart_rank == 0 ) fprintf(stdout,"Send values in direction 1\n"); if ( MPI_Cart_shift(cart_comm, 1, 1, &source, &dest) != MPI_SUCCESS ) exit(-1); if ( MPI_Sendrecv_replace(&cval, 1, MPI_INTEGER, dest, 0, source, 0, cart_comm, &status) != MPI_SUCCESS ) exit(-1); /* Again, collectively send value to root process */ SendToRootAndWrite(cval,p,q); ! MPI_Finalize(); return(0); }