#include "headers.h" int send_row(int dst, int nproc, int* row){ return MPI_Send(row, nproc, MPI_INT, dst, ROWTAG, MPI_COMM_WORLD); } int receive_row(int src, int nproc, int* row){ MPI_Status status; return MPI_Recv(row, nproc, MPI_INT, src, ROWTAG, MPI_COMM_WORLD, &status); } int main(int argc, char *argv[]){ int me, row, fd[3], i, j, nproc, square; int *Arow, *Brow, *Crow, *A, *B, *C; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &me); MPI_Comm_size(MPI_COMM_WORLD, &nproc); if(allocate_rows(&Arow, &Brow, &Crow, nproc + 1) < 0) goto fail; row = me + 1; square = nproc * nproc; if(me == BossMan){ /* parent code */ if(parse_args(argc, argv, fd, &nproc) < 0) goto fail; /* make the matrices */ if(allocate_rows(&A, &B, &C, square) < 0) goto fail; /* initialize A */ if(get_row(fd[0], square, row, A) == -1){ fprintf(stderr,"Initialization of A failed at row %d\n", row); goto fail; } /* initialize B */ if(get_row(fd[1], square, row, B) == -1){ fprintf(stderr,"Initialization of B failed at row %d\n", row); goto fail; } } if(DEBUG || (me == BossMan))fprintf(stderr, "Scattering A\n"); /* Scatter A */ if(MPI_Scatter(A, nproc, MPI_INT, &Arow[1], nproc, MPI_INT, BossMan, MPI_COMM_WORLD) != MPI_SUCCESS){ fprintf(stderr,"Scattering of A failed\n"); goto fail; } if(DEBUG || (me == BossMan))fprintf(stderr, "Scattering B\n"); /* Scatter B */ if(MPI_Scatter(B, nproc, MPI_INT, &Brow[1], nproc, MPI_INT, BossMan, MPI_COMM_WORLD) != MPI_SUCCESS){ fprintf(stderr,"Scattering of B failed\n"); goto fail; } /* ring code */ { int m; int dst = ( (me == (nproc - 1)) ? 0 : me + 1 ); int src = ( (me == 0) ? (nproc - 1) : me - 1 ); /* put a barrier up for fun */ if(SYNCHRO)MPI_Barrier(MPI_COMM_WORLD); /* initialize C */ if(DEBUG || (me == BossMan))fprintf(stderr, "Clone %i initializing C\n", me); for(j = 1; j <= nproc; j++) Crow[j] = Arow[row] * Brow[j]; if(DEBUG || (me == BossMan)) fprintf(stderr, "Clone %i finished initializing C\n", me); /* put a barrier up for fun */ if(SYNCHRO)MPI_Barrier(MPI_COMM_WORLD); /* pass the rows of B around the ring */ m = row; for(i = 1; i < nproc; i++){ if(DEBUG || (me == BossMan))fprintf(stderr, "Clone %i sending row %i\n", me, i); if(send_row(dst, nproc, &Brow[1]) != MPI_SUCCESS){ fprintf(stderr,"Write to ring by clone %d failed\n", me); goto fail; } if(DEBUG || (me == BossMan))fprintf(stderr, "Clone %i sent row %i\n", me, i); if(DEBUG || (me == BossMan))fprintf(stderr, "Clone %i receiving row %i\n", me, i); if(receive_row(src, nproc, &Brow[1]) != MPI_SUCCESS){ fprintf(stderr,"Read from ring by clone %d failed\n", me); goto fail; } if(DEBUG || (me == BossMan))fprintf(stderr, "Clone %i got row %i\n", me, i); if((m -= 1) == 0) m = nproc; for(j = 1; j <= nproc; j++) { Crow[j] += Arow[m] * Brow[j]; } } /* put a barrier up for fun */ if(SYNCHRO)MPI_Barrier(MPI_COMM_WORLD); /* Gathering C */ if(DEBUG || (me == BossMan))fprintf(stderr, "Gathering C\n"); if(MPI_Gather(&Crow[1], nproc, MPI_INT, C, nproc, MPI_INT, BossMan, MPI_COMM_WORLD) != MPI_SUCCESS){ fprintf(stderr, "Gathering of C failed\n"); goto fail; } if(DEBUG || (me == BossMan)) if(me == BossMan ) for(i = 0; i < square; i++) fprintf(stdout, "C[%d] = %d\n", i, C[i]); if(DEBUG || (me == BossMan))fprintf(stderr, "C Gathered\n"); if(me == BossMan ){ if(DEBUG || (me == BossMan))fprintf(stderr, "Writing C out\n"); if(set_row(fd[2], square, row, C) == -1) fprintf(stderr,"Writing of matrix C failed\n"); } /* Put a barrier up for fun */ if(SYNCHRO)MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); exit(EXIT_SUCCESS); } /* ring code */ fail: MPI_Finalize(); exit(EXIT_FAILURE); }