Skip to content

Instantly share code, notes, and snippets.

@BillMoriarty
Last active October 30, 2017 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BillMoriarty/ad459a1966fafdb3849f652b46cdd530 to your computer and use it in GitHub Desktop.
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"
#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