// version 0.1 modifed by ian a. mason // may 21 @ u.n.e // // tailored mm.0.1 to single architecture mode. // enlarged MAXROW to something more reasonable. #include #include #include #include #include #include #include #include "block.h" #define ENCODING PvmDataRaw #define MAXNTIDS 100 #define MAXROW 100 #define ATAG 2 #define BTAG 3 #define DIMTAG 5 #define VERBOSE 0 #define PERMS 0666 int parse_args(int argc, char *argv[ ], int *m, int *blksize, int *ntask, int fd[]){ int i; fprintf(stderr, "1: %d %s %s %s %s %s\n", argc, argv[1], argv[2], argv[3], argv[4], argv[5]); if ((argc != 6) || ((fd[0] = open(argv[1], O_RDONLY)) == -1) || ((fd[1] = open(argv[2], O_RDONLY)) == -1) || ((fd[2] = creat(argv[3], PERMS)) == -1) || ((*m = atoi(argv[4])) <= 0) || ((*blksize = atoi(argv[5])) <= 0)){ fprintf(stderr, "Usage: %s matrixA matrixB matrixC m blk\n", argv[0]); return(-1); }; if(*m > MAXROW){ fprintf(stderr, "m = %d not valid.\n", *m); return(-1); }; *ntask = (*m)*(*m); fprintf(stderr, "2: %d %s %s %s %d %d %d\n", argc, argv[1], argv[2], argv[3], *m, *blksize, *ntask); if ((*ntask < 1) || (*ntask >= MAXNTIDS)) { fprintf(stderr, "ntask in parse_args = %d not valid.\n", *ntask); pvm_exit(); return(-1); }; return(0); } int main(int argc, char* argv[]){ int ntask = 2; int info; int mytid, mygid; int child[MAXNTIDS-1]; int i, m, blksize; int myrow[MAXROW]; float *a, *b, *c, *atmp; int row, col, up, down; int crow, ccol; int fd[3]; /* A = fd[0] B = fd[1] C = fd[2] */ //real time for the time being int start_time = time(NULL); if(parse_args(argc, argv, &m, &blksize, &ntask, fd) < 0) exit(0); mytid = pvm_mytid(); pvm_setopt(PvmRoute, PvmRouteDirect); if (mytid < 0){ pvm_perror(argv[0]); return -1; } mygid = pvm_joingroup("mmult"); if (mygid < 0){ pvm_perror(argv[0]); pvm_exit(); return -1; } if (mygid == 0) { /* if (argc == 3) { m = atoi(argv[1]); blksize = atoi(argv[2]); } if (argc < 3) { fprintf(stderr, "usage: mmult m blk\n"); pvm_lvgroup("mmult"); pvm_exit(); return -1; } ntask = m*m; if ((ntask < 1) || (ntask >= MAXNTIDS)) { fprintf(stderr, "ntask here = %d not valid.\n", ntask); pvm_lvgroup("mmult"); pvm_exit(); return -1; } */ if (ntask == 1) goto barrier; fprintf(stderr, "3: %d %s %s %s %d %d %d\n", argc, argv[1], argv[2], argv[3], m, blksize, ntask); info = pvm_spawn("mm.0.3", &argv[1], PvmTaskDefault, (char*)0, ntask-1, child); if(info != ntask-1){ pvm_lvgroup("mmult"); pvm_exit(); return -1; } // pvm_initsend(ENCODING); // pvm_pkint(&m, 1, 1); // pvm_pkint(&blksize, 1, 1); // pvm_mcast(child, ntask-1, DIMTAG); } else { // pvm_recv(pvm_gettid("mmult", 0), DIMTAG); // pvm_upkint(&m, 1, 1); // pvm_upkint(&blksize, 1, 1); // ntask = m*m; } fprintf(stderr, "4: %d %s %s %s %d %d %d\n", argc, argv[1], argv[2], argv[3], m, blksize, ntask); pvm_exit(); exit(1); barrier: info = pvm_barrier("mmult",ntask); if (info < 0) pvm_perror(argv[0]); for (i = 0; i < m; i++) myrow[i] = pvm_gettid("mmult", (mygid/m)*m + i); a = (float*)malloc(sizeof(float)*blksize*blksize); b = (float*)malloc(sizeof(float)*blksize*blksize); c = (float*)malloc(sizeof(float)*blksize*blksize); atmp = (float*)malloc(sizeof(float)*blksize*blksize); if (!(a && b && c && atmp)) { fprintf(stderr, "%s: out of memory!\n", argv[0]); free(a); free(b); free(c); free(atmp); pvm_lvgroup("mmult"); pvm_exit(); return -1; } row = mygid/m; col = mygid % m; up = pvm_gettid("mmult", ((row)? (row-1): (m-1))*m+col); down = pvm_gettid("mmult", ((row == (m-1))? col: (row+1)*m+col)); InitBlock(a, b, c, blksize, row, col); for (i = 0; i < m; i++) { if (col == (row + i)%m) { pvm_initsend(ENCODING); pvm_pkfloat(a, blksize*blksize, 1); pvm_mcast(myrow, m, (i+1)*ATAG); BlockMult(c,a,b,blksize); } else { pvm_recv(pvm_gettid("mmult", row*m + (row +i)%m), (i+1)*ATAG); pvm_upkfloat(atmp, blksize*blksize, 1); BlockMult(c,atmp,b,blksize); } pvm_initsend(ENCODING); pvm_pkfloat(b, blksize*blksize, 1); pvm_send(up, (i+1)*BTAG); pvm_recv(down, (i+1)*BTAG); pvm_upkfloat(b, blksize*blksize, 1); } for (i = 0 ; i < blksize*blksize; i++) if (a[i] != c[i]) printf("Error a[%d] (%g) != c[%d] (%g) \n", i, a[i],i,c[i]); if(VERBOSE){ printf("Block C at [%d,%d] managed by task %d in:\n", row, col, mytid); for(crow = 0; crow < blksize; crow++){ for(ccol = 0; ccol < blksize; ccol++) printf("%5g ", c[(crow*blksize) + ccol]); printf("\n"); } printf("Block A at [%d,%d] managed by task %d in:\n", row, col, mytid); for(crow = 0; crow < blksize; crow++){ for(ccol = 0; ccol < blksize; ccol++) printf("%5g ", a[(crow*blksize) + ccol]); printf("\n"); } } printf("mm.0.3 %d %d task %d done sucessfully after %ld seconds.\n", m, blksize, mytid, time(NULL) - start_time); free(a); free(b); free(c); free(atmp); pvm_lvgroup("mmult"); pvm_exit(); return 0; }