|
|
|
@ -3,7 +3,13 @@ |
|
|
|
|
#define INPUTFILE1 "assignment3.in1" |
|
|
|
|
#define INPUTFILE2 "assignment3.in2" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define DIM_COUNT1 0 |
|
|
|
|
#define DIM_COUNT2 1 |
|
|
|
|
#define DIM_COLS1 2 |
|
|
|
|
#define DIM_COLS2 3 |
|
|
|
|
#define DIM_ROWS1 4 |
|
|
|
|
#define DIM_ROWS2 5 |
|
|
|
|
#define NUM_DIMS 6 |
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
|
int numProcesses, numRank; |
|
|
|
@ -13,63 +19,84 @@ int main(int argc, char *argv[]) { |
|
|
|
|
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); |
|
|
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &numRank); |
|
|
|
|
|
|
|
|
|
int *arrMatrix1, *arrMatrix2, *arrIndicesTransp, *arrBlockSizes, *arrBlockIndices; |
|
|
|
|
int numCols1, numCount1 = 0, numCols2, numCount2 = 0; |
|
|
|
|
int *arrMatrix1, *arrMatrix2, *arrBlockSizes, *arrBlockIndices; |
|
|
|
|
int arrDimensions[NUM_DIMS] = {0}; |
|
|
|
|
|
|
|
|
|
if (numRank == 0) { |
|
|
|
|
arrMatrix1 = read_matrix_file(INPUTFILE1, &numCols1, &numCount1); |
|
|
|
|
arrMatrix2 = read_matrix_file(INPUTFILE2, &numCols2, &numCount2); |
|
|
|
|
arrMatrix1 = read_matrix_file(INPUTFILE1, &arrDimensions[DIM_COLS1], &arrDimensions[DIM_COUNT1]); |
|
|
|
|
// Matrix transposition was done in assignment2 so we will assume already transposed matrix
|
|
|
|
|
arrMatrix2 = read_matrix_file(INPUTFILE2, &arrDimensions[DIM_COLS2], &arrDimensions[DIM_COUNT2]); |
|
|
|
|
|
|
|
|
|
checkParallelWorth(numProcesses, numCount2); |
|
|
|
|
arrDimensions[DIM_ROWS1] = arrDimensions[DIM_COUNT1] / arrDimensions[DIM_COLS1]; |
|
|
|
|
arrDimensions[DIM_ROWS2] = arrDimensions[DIM_COUNT2] / arrDimensions[DIM_COLS2]; |
|
|
|
|
|
|
|
|
|
arrIndicesTransp = my_malloc(numCount2 * sizeof(int)); |
|
|
|
|
if (arrDimensions[DIM_ROWS1] != arrDimensions[DIM_ROWS2]) { |
|
|
|
|
printf("Matrices cannot be multiplied! Check dimensions.\n"); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
spread_evenly(numProcesses, numCount2, &arrBlockIndices, &arrBlockSizes); |
|
|
|
|
check_parallel_worth(numProcesses, arrDimensions[DIM_ROWS1], 1); |
|
|
|
|
|
|
|
|
|
//arrIndicesTransp = my_malloc(arrDimensions[DIM_COUNT2] * sizeof(int));
|
|
|
|
|
|
|
|
|
|
spread_evenly(numProcesses, arrDimensions[DIM_ROWS1], arrDimensions[DIM_COLS1], &arrBlockIndices, &arrBlockSizes); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
MPI_Bcast(&numCount2, 1, MPI_INT, 0, MPI_COMM_WORLD); |
|
|
|
|
MPI_Bcast(&numCols2, 1, MPI_INT, 0, MPI_COMM_WORLD); |
|
|
|
|
//printf("size %2d, index %2d, buffer %2d, rank %d\n", packet[0], packet[1], packet[CODE_COUNT], numRank);
|
|
|
|
|
|
|
|
|
|
int arrBlockData[NUM_CODES]; |
|
|
|
|
MPI_Recv(arrBlockData, NUM_CODES, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
|
|
|
|
|
|
|
|
|
//We can calculate numRows2 * numCols2 = numCount2
|
|
|
|
|
int numRows2 = numCount2 / numCols2; |
|
|
|
|
int *arrIndicesSub = my_malloc(numCount2 * sizeof(int)); |
|
|
|
|
//for (int i = arrBlockData[CODE_INDEX]; i < (arrBlockData[CODE_SIZE] + arrBlockData[CODE_INDEX]); i++) {
|
|
|
|
|
for (int i = 0; i < arrBlockData[CODE_SIZE]; i++) { |
|
|
|
|
// Only the indices are transposed in parallel
|
|
|
|
|
int index = transpose_index(i + arrBlockData[CODE_INDEX], numRows2, numCols2); |
|
|
|
|
arrIndicesSub[i] = index; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//if (numRank == 0)
|
|
|
|
|
MPI_Gatherv(arrIndicesSub, arrBlockData[CODE_SIZE], MPI_INT, arrIndicesTransp, arrBlockSizes, arrBlockIndices,
|
|
|
|
|
MPI_INT, 0, MPI_COMM_WORLD); |
|
|
|
|
//MPI_Bcast(arrDimensions, NUM_DIMS, MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
|
|
|
|
|
if (numRank == 0 ) { |
|
|
|
|
printf("normal 1st matrix: \n"); |
|
|
|
|
for (int i = 0; i < numCount1; i++) { |
|
|
|
|
printf("%d ", arrMatrix1[i]); |
|
|
|
|
if ((i + 1) % numCols1 == 0) |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
//int *arrSlice1 = my_malloc(arrDimensions[DIM_COUNT1] * sizeof(int));
|
|
|
|
|
//MPI_Scatterv(arrMatrix1, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice1, arrDimensions[DIM_COUNT1], MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
|
|
|
|
|
if (numRank == 0) { |
|
|
|
|
printf("transposed 2nd matrix:"); |
|
|
|
|
for (int i = 0; i < numCount2; i++) { |
|
|
|
|
if (i % numRows2 == 0) |
|
|
|
|
printf("\n"); |
|
|
|
|
printf("%d ", arrMatrix2[arrIndicesTransp[i]]); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
//int *arrSlice2 = my_malloc(arrDimensions[DIM_COUNT2] * sizeof(int));
|
|
|
|
|
//MPI_Scatterv(arrMatrix2, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice2, arrDimensions[DIM_COUNT2], MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
////MPI_Bcast(&arrDimensions[DIM_COUNT2], 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
////MPI_Bcast(&numCols2, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
|
|
|
|
|
//int arrBlockData[NUM_CODES];
|
|
|
|
|
//MPI_Recv(arrBlockData, NUM_CODES, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
|
|
|
|
|
////printf("rank %d, size %d, indices %d\n", numRank, arrBlockData[CODE_SIZE], arrBlockData[CODE_INDEX]);
|
|
|
|
|
////printf("nc1 %d, nc2 %d\n", arrDimensions[DIM_COUNT1], arrDimensions[DIM_COUNT2]);
|
|
|
|
|
|
|
|
|
|
//for (int i = 0; i < arrBlockData[CODE_SIZE]; i++) {
|
|
|
|
|
//printf("rank %d, slice1[%d] = %d\n", numRank, i, arrSlice1[i]);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
////We can calculate arrDimensions[DIM_ROWS2] * numCols2 = numCount2
|
|
|
|
|
//int arrDimensions[DIM_ROWS2] = numCount2 / numCols2;
|
|
|
|
|
//int *arrIndicesSub = my_malloc(numCount2 * sizeof(int));
|
|
|
|
|
////for (int i = arrBlockData[CODE_INDEX]; i < (arrBlockData[CODE_SIZE] + arrBlockData[CODE_INDEX]); i++) {
|
|
|
|
|
//for (int i = 0; i < arrBlockData[CODE_SIZE]; i++) {
|
|
|
|
|
//// Only the indices are transposed in parallel
|
|
|
|
|
//int index = transpose_index(i + arrBlockData[CODE_INDEX], arrDimensions[DIM_ROWS2], numCols2);
|
|
|
|
|
//arrIndicesSub[i] = index;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
////if (numRank == 0)
|
|
|
|
|
//MPI_Gatherv(arrIndicesSub, arrBlockData[CODE_SIZE], MPI_INT, arrIndicesTransp, arrBlockSizes, arrBlockIndices,
|
|
|
|
|
//MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
|
|
|
|
|
//if (numRank == 0 ) {
|
|
|
|
|
//printf("normal 1st matrix: \n");
|
|
|
|
|
//for (int i = 0; i < arrDimensions[DIM_COUNT1]; i++) {
|
|
|
|
|
//printf("%d ", arrMatrix1[i]);
|
|
|
|
|
//if ((i + 1) % numCols1 == 0)
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//}
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//if (numRank == 0) {
|
|
|
|
|
//printf("transposed 2nd matrix:");
|
|
|
|
|
//for (int i = 0; i < arrDimensions[DIM_COUNT2]; i++) {
|
|
|
|
|
//if (i % arrDimensions[DIM_ROWS2] == 0)
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//printf("%d ", arrMatrix2[arrIndicesTransp[i]]);
|
|
|
|
|
//}
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
MPI_Finalize(); |
|
|
|
|
return 0; |
|
|
|
|