#include "common.h" #define INPUTFILE1 "assignment3.in1" #define INPUTFILE2 "assignment3.in2" /*#define INPUTFILE1 "a.in"*/ /*#define INPUTFILE2 "b.in"*/ #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; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); MPI_Comm_rank(MPI_COMM_WORLD, &numRank); int *arrMatrix1, *arrMatrix2, *arrBlockSizes, *arrBlockIndices; int arrDimensions[NUM_DIMS] = {0}; if (numRank == 0) { 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]); arrDimensions[DIM_ROWS1] = arrDimensions[DIM_COUNT1] / arrDimensions[DIM_COLS1]; arrDimensions[DIM_ROWS2] = arrDimensions[DIM_COUNT2] / arrDimensions[DIM_COLS2]; if (arrDimensions[DIM_COLS1] != arrDimensions[DIM_COLS2]) { printf("Matrices cannot be multiplied! Check dimensions.\n"); exit(EXIT_FAILURE); } 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(arrDimensions, NUM_DIMS, MPI_INT, 0, MPI_COMM_WORLD); 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); 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("s: 1, r: %2d, [%d] = %d\n", numRank, i, arrSlice1[i]); //} //for (int i = 0; i < arrBlockData[CODE_SIZE]; i++) { //printf("s: 2, r: %2d, [%d] = %d\n", numRank, i, arrSlice2[i]); //} //for (int i = 0; i < NUM_DIMS; i++) //printf("%6d (%d)\n", arrDimensions[i], i); int sum = 0; int col = 0; for (int row = 0; row < arrDimensions[DIM_ROWS2]; row++) { col = row * arrDimensions[DIM_COLS2]; for (int i = 0; i < arrBlockData[CODE_SIZE]; i++) { sum += arrSlice1[i] * arrSlice2[col]; //printf("%2d[%d%d]\n", sum, i, col); col++; if (col == (row + 1) * arrDimensions[DIM_COLS2]) { printf("%3d ", sum); col = row * arrDimensions[DIM_COLS2]; sum = 0; } } printf("\n"); } /* for (int j = 0; j < 2; j++) { //sum += (arrSlice1[i] * arrSlice2[j]); //if (j % arrDimensions[DIM_COLS1] == 0) { ////printf("%4d (%d);", sum, numRank); //printf("%4d; ", sum); //sum = 0; //} //printf("%4d; ", sum); printf("%2d[%d%d]\t", i, j, arrSlice1[i] * arrSlice2[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; } //int numBlockIndex = 0; //int numRemainder = numCount1 % numProcesses; //arrBlockIndices = my_malloc(numProcesses * sizeof(int)); //arrBlockSizes = my_malloc(numProcesses * sizeof(int)); //for (int i = 0; i < numProcesses; i++) { //arrBlockSizes[i] = numCount1 / numProcesses; //if (numRemainder > 0) { //arrBlockSizes[i]++; //numRemainder--; //} //arrBlockIndices[i] = numBlockIndex; //numBlockIndex += arrBlockSizes[i]; //printf("size[%d] = %d\tindex[%d] = %d\n", i, arrBlockSizes[i], i, arrBlockIndices[i]); //int arrBlockData[NUM_CODES]; //arrBlockData[CODE_SIZE] = arrBlockSizes[i]; //arrBlockData[CODE_INDEX] = arrBlockIndices[i]; //// Send every process starting index of 1D represented matrix and number of //// succeding indices to calculate transposition //MPI_Send(arrBlockData, NUM_CODES, MPI_INT, i, 1, MPI_COMM_WORLD); //} //for (int i = 0; i < numProcesses; i++) { //printf("size[%d] = %d\tindex[%d] = %d\n", i, arrBlockSizes[i], i, arrBlockIndices[i]); //}