Last active
October 30, 2017 18:34
-
-
Save BillMoriarty/ad459a1966fafdb3849f652b46cdd530 to your computer and use it in GitHub Desktop.
A C project for Temple University to multiply two square matrices ("matrix1.txt" and "matrix2.txt") using the MPI protocol and write to "resulting-matrix.txt"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <mpi.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <string.h> | |
#include <ctype.h> | |
#define min(x, y) ((x)<(y)?(x):(y)) | |
//code altered by Bill Moriarty for Temple University | |
//This code includes many print statement that were required for our lab project. | |
int main(int argc, char *argv[]) { | |
FILE *inFile; | |
FILE *inFile2; | |
// code below is to open matrix files | |
if (argc > 1) { | |
char inMatrix[13]; | |
char inMatrix2[13]; | |
//open the files | |
/* check that the files opened correcty */ | |
if ((inFile = fopen(argv[1], "r")) == NULL) { | |
perror("error reading %s for input\n"); | |
return 1; | |
} /* end if */ | |
if ((inFile2 = fopen(argv[2], "r")) == NULL) { | |
perror("error reading %s for output\n"); | |
return 1; | |
} /* end if */ | |
}// end if argc>1 | |
//above is code to get the file info from argv | |
int nrows, ncols; | |
int matrixOneRows, matrixOneColums, matrixTwoRows, matrixTwoColums; | |
fscanf(inFile, " %d", &matrixOneRows); | |
fscanf(inFile, " %d", &matrixOneColums); | |
fscanf(inFile2, " %d", &matrixTwoRows); | |
fscanf(inFile2, " %d", &matrixTwoColums); | |
printf("%d %d %d %d \n", matrixOneRows, matrixOneColums, matrixTwoRows, matrixTwoColums); | |
//create int arrays to hold the numbers from matrices and malloc space | |
int **matrixOneArray = (int **)malloc(matrixOneRows * sizeof(int *)); | |
for (int i=0; i<matrixOneRows; i++) { | |
matrixOneArray[i] = (int *) malloc(matrixOneColums * sizeof(int)); | |
} | |
int **matrixTwoArray = (int **)malloc(matrixTwoRows * sizeof(int *)); | |
for (int i=0; i<matrixTwoRows; i++) { | |
matrixTwoArray[i] = (int *) malloc(matrixTwoColums * sizeof(int)); | |
} | |
//push all the elements from the first matrix to matrixOneArray | |
for(int k = 0; k < matrixOneRows; ++k) { | |
//malloc space for this int todo | |
for(int l=0; l<matrixOneColums; ++l){ | |
//malloc space for this int todo | |
fscanf(inFile, " %d", &matrixOneArray[k][l]); | |
}//end inner loop | |
}//end outer loop | |
//push all the elements from the second matrix to matrixTwoArray | |
for(int k = 0; k < matrixTwoRows; ++k) { | |
for(int l=0; l<matrixTwoColums; ++l){ | |
fscanf(inFile2, " %d", &matrixTwoArray[k][l]); | |
}//end inner loop | |
}//end outer loop | |
//print the arrays to make sure they were correctly stored | |
for(int i=0; i<matrixOneRows; i++){ | |
for(int j=0; j<matrixOneColums; j++){ | |
printf("%d", matrixOneArray[i][j]); | |
} | |
printf(" \n"); | |
}//end for | |
for(int i=0; i<matrixTwoRows; i++){ | |
for(int j=0; j<matrixTwoColums; j++){ | |
printf("%d", matrixTwoArray[i][j]); | |
} | |
printf(" \n"); | |
}// end for | |
nrows = matrixOneRows; | |
ncols = matrixTwoColums; | |
printf("nrows is %d \n", matrixOneRows); | |
printf("ncolums is %d \n", matrixTwoColums); | |
// | |
double *aa, *b, *receivedData; | |
double *buffer, *ans; | |
double *times; | |
double total_times; | |
int run_index; | |
int nruns; | |
int myid, master, numprocs; | |
double starttime, endtime; | |
MPI_Status status; | |
int i, j, numsent, sender; | |
int anstype, row; | |
srand(time(0)); | |
MPI_Init(&argc, &argv); | |
MPI_Comm_size(MPI_COMM_WORLD, &numprocs); | |
MPI_Comm_rank(MPI_COMM_WORLD, &myid); | |
int receivedDataArray[nrows]; | |
int *arrayToPrint; | |
if (argc > 1) { | |
//mallow space for arrayToPrint | |
arrayToPrint = (int *) malloc(sizeof(int) * (ncols*nrows) ); | |
receivedData = (double *) malloc(sizeof(double) * nrows); | |
buffer = (double *) malloc(sizeof(double) * ncols); | |
master = 0; | |
if (myid == master) { | |
// Master Code goes here | |
starttime = MPI_Wtime(); | |
numsent = 0; | |
MPI_Bcast(*matrixTwoArray, ncols, MPI_DOUBLE, master, MPI_COMM_WORLD); | |
//below deals with sending rows | |
for (i = 0; i < min(numprocs - 1, nrows); i++) { | |
for (j = 0; j < ncols; j++) { | |
buffer[j] = matrixOneArray[i][j]; | |
}//end for j<ncols | |
MPI_Send(buffer, ncols, MPI_DOUBLE, i+1, i+1, MPI_COMM_WORLD); | |
numsent++; | |
}//end for i<min... | |
//below deals with receiving | |
for (i = 0; i < nrows; i++) { | |
MPI_Recv(receivedDataArray, ncols, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); | |
sender = status.MPI_SOURCE; | |
anstype = status.MPI_TAG - 1; | |
//put the received row into our 2d array | |
printf("anstype is %d\n", anstype); | |
//printf("receveivedDataArray[%d] is %d ", t, receivedDataArray[t]); | |
int arrayStart=anstype*ncols; | |
for (int k = 0; k < ncols; ++k) { | |
//printf("receveivedDataArray[%d] is %d ", k, (int)receivedDataArray[k]); | |
printf("Trying to put %d into arrayToPrint positon %d \n", (int)receivedDataArray[k], arrayStart); | |
arrayToPrint[arrayStart] = (int)receivedDataArray[k]; | |
arrayStart++; | |
} //end for | |
//open a file out stream and write arrayToPrint to a text file | |
FILE *f = fopen("resulting-matrix.txt", "w"); | |
if (f == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
//print the arrayToPrint | |
int printIndex=0; | |
for(int y=0; y<(nrows); y++){ | |
//print the first 5 elements | |
for(int g=0; g<ncols; g++){ | |
printf("%d ", arrayToPrint[printIndex]); | |
// write to file stream | |
fprintf(f, "%d ", arrayToPrint[printIndex]); | |
printIndex++; | |
} | |
//print a new line | |
printf("\n"); | |
fprintf(f, "\n"); | |
}//end outer for | |
//close the file stream | |
fclose(f); | |
if (numsent < nrows) { | |
for (j = 0; j < ncols; j++) { | |
buffer[j] = matrixOneArray[numsent][j]; | |
}//end for | |
MPI_Send(buffer, ncols, MPI_DOUBLE, sender, numsent + 1, MPI_COMM_WORLD); | |
numsent++; | |
} else { | |
MPI_Send(MPI_BOTTOM, 0, MPI_DOUBLE, sender, 0, MPI_COMM_WORLD); | |
}//end else | |
}//end for for (i = 0; i < nrows; i++) | |
endtime = MPI_Wtime(); | |
printf("endtime - starttime is %f\n", (endtime - starttime)); | |
} else { | |
// Slave Code goes here | |
MPI_Bcast(*matrixTwoArray, ncols, MPI_DOUBLE, master, MPI_COMM_WORLD); | |
if (myid <= nrows) { | |
while (1) { | |
MPI_Recv(buffer, ncols, MPI_DOUBLE, master, MPI_ANY_TAG, MPI_COMM_WORLD, &status); | |
if (status.MPI_TAG == 0) { | |
break; | |
}// end if ==0 | |
row = status.MPI_TAG; | |
int j=row-1; | |
int tempAns[ncols]; | |
for(int r=0; r<ncols; r++){ | |
tempAns[r]=0; //reset this | |
for (int s=0; s < ncols; s++) { | |
tempAns[r] += buffer[s] * matrixTwoArray[s][r]; | |
}//end for with s | |
}// end for with r | |
for (int z =0; z<ncols; z++){ | |
} // end for print | |
MPI_Send(tempAns, ncols, MPI_DOUBLE, master, row, MPI_COMM_WORLD); | |
}// end while 1 | |
} //end if myid <= rows | |
} //end else | |
}//end argc>13 | |
else | |
{ | |
fprintf(stderr, "Usage matrix_times_vector <size>\n"); | |
} | |
MPI_Finalize(); | |
return 0; | |
} //end main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment