You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.7 KiB
136 lines
4.7 KiB
#include "common.h"
|
|
|
|
#define INPUTFILE "assignment2.in"
|
|
|
|
// TODO: define custom structure for this probably
|
|
#define CODE_SIZE 0
|
|
#define CODE_INDEX 1
|
|
#define NUM_CODES 2
|
|
|
|
int transpose_index(int index, int rows, int cols);
|
|
|
|
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 *arrMatrixOriginal, *arrIndicesTransp, *arrBlockSizes, *arrBlockIndices;
|
|
int numCols, numCount = 0;
|
|
|
|
if (numRank == 0) {
|
|
|
|
// To avoid aggresive buffer growth at the beggining of the sequence
|
|
int sizeBufferTotal = INIT_BUFFER_SIZE;
|
|
// Allocate enough memory for initial buffer
|
|
arrMatrixOriginal = my_malloc(sizeBufferTotal * sizeof(int));
|
|
// Open the file with input data
|
|
FILE *ptrFile = my_fopen(INPUTFILE, "r");
|
|
|
|
// Read line by line until the end of file
|
|
// TODO: remove the MAX_LINE_LENGTH limitation of strBuffer
|
|
char *ptrBuffer, strBuffer[MAX_LINE_LENGTH];
|
|
while (fgets(strBuffer, sizeof strBuffer, ptrFile) != 0) {
|
|
// Store the pointer
|
|
ptrBuffer = strBuffer;
|
|
numCols = 0;
|
|
int numValue;
|
|
// Read untill newline
|
|
while (*ptrBuffer != '\n') {
|
|
// Grow buffer when needed
|
|
arrMatrixOriginal = buffer_grow(arrMatrixOriginal, numCount, &sizeBufferTotal);
|
|
// Convert string to base 10
|
|
numValue = strtol(ptrBuffer, &ptrBuffer, 10);
|
|
// Store the number read in memory
|
|
arrMatrixOriginal[numCount++] = numValue;
|
|
numCols++;
|
|
}
|
|
}
|
|
|
|
checkParallelWorth(numProcesses, numCount);
|
|
|
|
arrIndicesTransp = my_malloc(numCount * sizeof(int));
|
|
|
|
int numBlockIndex = 0;
|
|
int numRemainder = numCount % numProcesses;
|
|
|
|
arrBlockIndices = my_malloc(numProcesses * sizeof(int));
|
|
arrBlockSizes = my_malloc(numProcesses * sizeof(int));
|
|
|
|
for (int i = 0; i < numProcesses; i++) {
|
|
arrBlockSizes[i] = numCount / numProcesses;
|
|
if (numRemainder > 0) {
|
|
arrBlockSizes[i]++;
|
|
numRemainder--;
|
|
}
|
|
|
|
arrBlockIndices[i] = numBlockIndex;
|
|
numBlockIndex += arrBlockSizes[i];
|
|
|
|
int arrTransp[NUM_CODES];
|
|
arrTransp[CODE_SIZE] = arrBlockSizes[i];
|
|
arrTransp[CODE_INDEX] = arrBlockIndices[i];
|
|
// Send every process starting index of 1D represented matrix and number of
|
|
// succeding indices to calculate transposition
|
|
MPI_Send(arrTransp, NUM_CODES, MPI_INT, i, NUM_CODES, MPI_COMM_WORLD);
|
|
}
|
|
|
|
//for (int i = 0; i < numProcesses; i++) {
|
|
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrBlockSizes[i], i, arrBlockIndices[i]);
|
|
//}
|
|
|
|
}
|
|
|
|
MPI_Bcast(&numCount, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
MPI_Bcast(&numCols, 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 arrTransp[NUM_CODES];
|
|
MPI_Recv(arrTransp, NUM_CODES, MPI_INT, 0, NUM_CODES, MPI_COMM_WORLD, &status);
|
|
|
|
//We can calculate numRows * numCols = numCount
|
|
int numRows = numCount / numCols;
|
|
int *arrIndicesSub = my_malloc(numCount * sizeof(int));
|
|
//for (int i = arrTransp[CODE_INDEX]; i < (arrTransp[CODE_SIZE] + arrTransp[CODE_INDEX]); i++) {
|
|
for (int i = 0; i < arrTransp[CODE_SIZE]; i++) {
|
|
// Only the indices are transposed in parallel
|
|
int index = transpose_index(i + arrTransp[CODE_INDEX], numRows, numCols);
|
|
arrIndicesSub[i] = index;
|
|
}
|
|
|
|
//if (numRank == 0)
|
|
MPI_Gatherv(arrIndicesSub, arrTransp[CODE_SIZE], MPI_INT, arrIndicesTransp, arrBlockSizes, arrBlockIndices,
|
|
MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
//if (numRank == 0 ) {
|
|
//printf("original matrix: \n");
|
|
//for (int i = 0; i < numCount; i++) {
|
|
//printf("%d ", arrMatrixOriginal[i]);
|
|
//if ((i + 1) % numCols == 0)
|
|
//printf("\n");
|
|
//}
|
|
//printf("\n");
|
|
//}
|
|
|
|
if (numRank == 0) {
|
|
printf("transposed matrix:");
|
|
for (int i = 0; i < numCount; i++) {
|
|
if (i % numRows == 0)
|
|
printf("\n");
|
|
printf("%d ", arrMatrixOriginal[arrIndicesTransp[i]]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
MPI_Finalize();
|
|
return 0;
|
|
}
|
|
|
|
int transpose_index(int index, int rows, int cols) {
|
|
//return ((rows * index) / (cols * rows)) + ((rows * index) % (cols * rows));
|
|
//return (index / cols) + rows * (index % cols);
|
|
return (index / rows) + cols * (index % rows);
|
|
}
|
|
|
|
|