/* Compile with -lm, Updated for Parsec 9-8-97 */ #include #include #include #define DEBUG 0 #define DEFAULT_INPUT_FNAME "input.dat" #define DEFAULT_OUTPUT_FNAME "output.dat" #define DEFAULT_NUM_PROC 4 #define DEFAULT_BLOCK_SIZE 2 #define MATRIX_MAX_SIZE 16 #define INDEX_ZERO 0 message Init { ename leftBlk; ename upBlk; ename drivEname; int blkRow; int blkCol;}; message Init_A {int rowA[MATRIX_MAX_SIZE]; int rowPosition;}; message Init_B {int rowB[MATRIX_MAX_SIZE]; int rowPosition;}; message ColOfA {int colA[MATRIX_MAX_SIZE];}; message RowOfB {int rowB[MATRIX_MAX_SIZE];}; message RowOfC {int rowC[MATRIX_MAX_SIZE]; int blkRow; int blkCol; int rowOffset;}; entity Blk_Entity(int, int); /**********************************************************/ /* Procedure Print_Mat */ /* Parameters: */ /* file_ptr : output file file pointer */ /* matrix : the output matrix (i.e. matrix c) */ /* matrixSize: the size of matrix */ /* */ /* Algorithm: */ /* printing the contents of the matrix with padding */ /**********************************************************/ void Print_Mat (file_ptr,matrix,matrixSize) FILE *file_ptr; int matrix[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; int matrixSize; { int i; int j; int tmp; int padding ; fprintf(file_ptr,"The result matrix is:\n\n"); for (i = 0; i < matrixSize; i++) { for (j = 0; j < matrixSize; j++) { padding = 6; tmp = matrix[i][j]; if (tmp < 0) padding--; while(tmp = tmp/10) padding--; while (padding--) fprintf(file_ptr," "); fprintf(file_ptr,"%d",matrix[i][j]); } fprintf(file_ptr,"\n"); } } /**********************************************************/ /* Procedure Copy_Row */ /* Parameter: */ /* matrix : the two dimensional matrix that we */ /* want to copy the row into */ /* rowArray : one dimensional array that contains */ /* the one row of the data that we want */ /* to be copy into matrix */ /* matrixRowPos: the actual row index of the matrix */ /* that we want to copy rowArray into. */ /* colOffset : the actual col index of the matrix */ /* that we want to copy rowArray into. */ /* blockSize : the size of a block (submatrix) */ /* */ /* Algorithm: */ /* Array rowArray contains the row of data that we */ /* to copy to into matrix "matrix" at positions */ /* specified by the variable matrixRowPos and */ /* colOffset. */ /* */ /* The index of rowArray corresponds to the */ /* index in "matrixRowPos"th row of matrix "matrix". */ /**********************************************************/ void Copy_Row(matrix,rowArray,matrixRowPos,colOffset,blockSize) int matrix[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; int rowArray[MATRIX_MAX_SIZE]; int matrixRowPos; int colOffset; int blockSize; { int colIndex; int arrayIndex = 0; for (colIndex=colOffset;colIndex<(colOffset+blockSize);colIndex++) { matrix[matrixRowPos][colIndex]=rowArray[arrayIndex]; arrayIndex++; } } /**********************************************************/ /* Read_Input */ /* Parameter: */ /* FILE infilePtr : input file pointer */ /* int matrixSize : size of matrix */ /* int matrixA : two dimensional matrix A */ /* int matrixB : two dimensional matrix B */ /* */ /* Algorithm: */ /* General Description: */ /* Read in matrix A and matrix B from input file, and */ /* also the size of matrix, then perform the initial */ /* shifting with Cannon's algorithm at the same time */ /**********************************************************/ int Read_Input(infilePtr,matrixSize,matrixA,matrixB) FILE *infilePtr; int *matrixSize; int matrixA[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; int matrixB[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; { int rowIndex = 0; int colIndex = 0; int readValue = 0; int shiftedIndex = 0; int numOfMatrix = 0; /********************************/ /* Scanf the size of the matrix */ /********************************/ fscanf(infilePtr,"%d\n",matrixSize); /*************************************************************/ /* Scanf the elements of matrix A and B and also perform the */ /* initial shifting */ /*************************************************************/ for (numOfMatrix = 0; numOfMatrix <= 1; numOfMatrix++) { /***********************************/ /* numOfMatrix = 0 -----> matrix A */ /* numOfMatrix = 1 -----> matrix B */ /***********************************/ for (rowIndex = 0; rowIndex < *matrixSize; rowIndex++) { for (colIndex = 0; colIndex < *matrixSize; colIndex++) { fscanf(infilePtr,"%d",&readValue); if (readValue == '\n') fscanf(infilePtr,"%d",&readValue); /***********************************/ /* numOfMatrix = 0 -----> matrix A */ /***********************************/ if (numOfMatrix == 0) { shiftedIndex = ((colIndex - rowIndex) + *matrixSize) % *matrixSize; matrixA[rowIndex][shiftedIndex] = readValue; /***********************************/ /* numOfMatrix = 1 -----> matrix B */ /***********************************/ } else { shiftedIndex = ((rowIndex - colIndex) + *matrixSize) % *matrixSize; matrixB[shiftedIndex][colIndex] = readValue; } } } } return(0); } /**********************************************************/ /* Entity Blk_Entity */ /* Parameters: */ /* blockSize : The size of a block (subMatrix) */ /* matrixSize : The size of the input matrix */ /* Local Parameters: */ /* */ /* int matrixA : The sub matrix of matrix A which is */ /* assigned to this entity (process) */ /* int matrixB : The sub matrix of matrix B which is */ /* assigned to this entity (process) */ /* int matrixC : The sub matrix of matrix C which is */ /* assigned to this eneity (process) and*/ /* will contain the answers to this sub */ /* matrix at the end. */ /* int temp : temporary array that is used to store*/ /* the values of a col, and will be used*/ /* in the messages to passed to other */ /* entities */ /* int rowIndex : row index of a matrix */ /* int colIndex : col index of a matrix */ /* int receivedCount: counter of number of messages that */ /* have been received already */ /* int count : counter variable */ /* ename LeftEname : */ /* ename UpEname : */ /* message Init : initial message that contains the */ /* ename of the left entity and up */ /* entity, the ename of the driver, */ /* row and column position of this */ /* entity in the Blk_Module array */ /* message Init_A : initial message that contains one row*/ /* of sub matrix A that belongs to this */ /* entity initially. */ /* message Init_B : initial message that contains one row*/ /* of sub matrix B that belongs to this */ /* entity initially. */ /* message ColOfA : sent by the right entity contains the*/ /* shifted column from right entity */ /* message RowOfB : sent by the down entity contains the */ /* shifted row from the down entity */ /* */ /* Algorithm: */ /* General Description: */ /* 1) waiting for initial message to indicate the */ /* entities on the left and up, and also the row */ /* and col positions in the Blk_Module */ /* 2) waiting for initial sub matrix A and sub matrix */ /* B, then copy into local matrix */ /* 3) compute initial sub matrix C using the initial */ /* sub matrix A and B. */ /* 4) */ /* (1) send the first column of sub matrix A to */ /* left entity and first row of sub matrix B */ /* to up entity */ /* (2) shift all elements of sub matrix A one */ /* index left and all elements of sub matrix B*/ /* one index up */ /* (3) waiting for the right entity to send its */ /* first column of sub matrix A and down */ /* entity to send its first row of sub matrix */ /* B, and update the sub matrix A and B */ /* (4) compute the sub matrix C */ /* (5) repeat sub step (1) to (4) number of times */ /* that is equal to (matrix size - 1) */ /* 5) send matrix C to driver entity row by row */ /**********************************************************/ entity Blk_Entity(int blockSize, int matrixSize) { int matrixA[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; int matrixB[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; int matrixC[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; int temp[MATRIX_MAX_SIZE]; int rowIndex; int colIndex; int receiveCount; int count; ename LeftEname; ename UpEname; message Init init; /*******************************************************/ /* Step 1) */ /*******************************************************/ /* Initialize matrix C to 0 */ for (rowIndex=0; rowIndex default: input.dat} */ /* -output { default: output.dat} */ /* -block { default: 2} */ /* -procs <# of processor> */ /* */ /* General Description: */ /* Assume: */ /* 1) each Blk_Entity entity will receive a sub */ /* matrix A and sub matrix B, and will calculate */ /* its sub matrix C and send it back to the driver*/ /* driver entity */ /* 2) the Blk_Entity are created by driver and stored*/ /* in a two dimensional ename type matrix */ /* 3) The assignment of the sub matrix A and B */ /* corresponds to the ename matrix Blk_Module */ /* */ /* i.e. block size = 1, matrix 2 x 2 */ /* matrixA[0][0] -> Blk_Module[0][0] */ /* matrixA[0][1] -> Blk_Module[0][1] */ /* matrixA[1][0] -> Blk_Module[1][0] */ /* matrixA[1][1] -> Blk_Module[1][1] */ /* */ /* Algorithm: */ /* */ /* 1) modifying command line variables: Block_Size, */ /* Output_Fname (output file name), Input_Fname */ /* (input file name), Num_of_Procs (number of */ /* processors) */ /* 2) call procedure Read_Input to read matrix size */ /* , matrix A , and matrix B from input file and */ /* also perform the initial shifting */ /* 3) calculate the size of Blk_Module (number of */ /* entity) , and also create the entities evently */ /* among the number of processors */ /* 4) for each entity: */ /* (1) calculate the row and col index of left */ /* entity and up entity in the Blk_Module, and */ /* send them along with the Init message */ /* (2) calculate the actual row and col index on */ /* matrix A and B, and then send the sub matrix */ /* to this entity */ /* (3) repeat sub step (1) and (2) for number of */ /* entities times which was obtained in sub step*/ /* (1) */ /* 5) waiting for the result sub matrix, and save them */ /* into matrix C */ /* 6) call procedure Print_Mat to print out the result */ /* matrix to output file */ /**********************************************************/ entity driver(int argc, char **argv) { FILE *Infile_Fp; /*Input file ptr*/ FILE *Outfile_Fp; /*Output file ptr*/ int Matrix_Size; /*Size of matrix*/ int Block_Size=DEFAULT_BLOCK_SIZE; /*Size of block at default*/ int Num_of_Blocks; /*Number of blocks*/ int Blk_Row_Pos; /*Row index in Blk_Module*/ int Blk_Col_Pos; /*Col index in Blk_Module*/ int Matrix_A[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; /*Matrix A at default 64x64*/ int Matrix_B[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; /*Matrix B at default 64x64*/ int Matrix_C[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; /*Matrix C at default 64x64*/ int Num_of_Procs=DEFAULT_NUM_PROC; /*Number of processors*/ int Matrix_Row_Pos; /*Row index in Matrix*/ int Matrix_Col_Pos; /*Col index in Matrix*/ int Left_Index; /*Col index of left entity*/ int Up_Index; /*Row index of up entity*/ int Process_Count=0; /*Number of processes*/ int count = 0; /*Counter*/ char Output_Fname[80]; /*Output file name string*/ char Input_Fname[80]; /*Input file name string*/ ename Blk_Module[MATRIX_MAX_SIZE][MATRIX_MAX_SIZE]; /*Two dim array of ename*/ /*default at 32 x 32 */ message RowOfC matrixCRow; /*******************************************************/ /* Step 1) */ /*******************************************************/ strcpy(Input_Fname,DEFAULT_INPUT_FNAME); strcpy(Output_Fname,DEFAULT_OUTPUT_FNAME); for (count=0; count < argc; count++) { if (strcmp(argv[count],"-procs") == 0) Num_of_Procs = atoi(argv[++count]); if (strcmp(argv[count],"-output") == 0) strcpy(Output_Fname,argv[++count]); if (strcmp(argv[count],"-input") == 0) strcpy(Input_Fname,argv[++count]); if (strcmp(argv[count],"-block") == 0) Block_Size = atoi(argv[++count]); } if ((Infile_Fp=fopen(Input_Fname,"r")) == NULL) { pc_printf("mult (input): can't open input file %s !\n",Input_Fname); pc_exit(1); } if ((Outfile_Fp=fopen(Output_Fname,"w")) == NULL) { pc_printf("mult (output): can't open output file %s !\n",Output_Fname); pc_exit(1); } /*******************************************************/ /* Step 2) */ /*******************************************************/ /* Reading input from input file */ if (Read_Input(Infile_Fp,&Matrix_Size,Matrix_A, Matrix_B) != 0) { pc_printf("mult (input): error in reading input !\n"); } fclose(Infile_Fp); /*******************************************************/ /* Step 3) */ /*******************************************************/ if ((Matrix_Size % Block_Size) == 0) { Num_of_Blocks = Matrix_Size / Block_Size; } else { pc_printf("mult (block): can't evently divide blocks\n"); pc_exit(1); } Process_Count = 0; for (Blk_Row_Pos=0;Blk_Row_Pos