|
|
|
@ -2,62 +2,65 @@ |
|
|
|
|
|
|
|
|
|
#define INPUTFILE "zadanie2.in" |
|
|
|
|
|
|
|
|
|
// TODO: define custom structure for this probably
|
|
|
|
|
#define CODE_SIZE 0 |
|
|
|
|
#define CODE_INDEX 1 |
|
|
|
|
//#define CODE_COLS 0
|
|
|
|
|
//#define CODE_COUNT 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_Status status; |
|
|
|
|
|
|
|
|
|
MPI_Init(&argc, &argv); |
|
|
|
|
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); |
|
|
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &numRank); |
|
|
|
|
|
|
|
|
|
int sizeBufferUsed = 0, sizeBufferTotal; |
|
|
|
|
int *arrNumbers, *arrBlockSizes, *arrBlockIndices, cols; |
|
|
|
|
int *arrNumbers, *arrBlockSizes, *arrBlockIndices; |
|
|
|
|
int cols = 0, numCount = 0; |
|
|
|
|
|
|
|
|
|
if (numRank == 0) { |
|
|
|
|
|
|
|
|
|
char *ptrBuffer, strBuffer[MAX_LINE_LENGTH]; |
|
|
|
|
FILE *ptrFile = my_fopen(INPUTFILE, "r"); |
|
|
|
|
sizeBufferTotal = INIT_BUFFER_SIZE; |
|
|
|
|
// To avoid aggresive buffer growth at the beggining of the sequence
|
|
|
|
|
int sizeBufferTotal = INIT_BUFFER_SIZE; |
|
|
|
|
// Allocate enough memory for initial buffer
|
|
|
|
|
arrNumbers = 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) { |
|
|
|
|
// Grow the buffer when needed
|
|
|
|
|
if (sizeBufferUsed == sizeBufferTotal) { |
|
|
|
|
sizeBufferTotal *= GROWTH_FACTOR; |
|
|
|
|
arrNumbers = my_realloc(arrNumbers, sizeBufferTotal * sizeof(int)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Store the pointer
|
|
|
|
|
ptrBuffer = strBuffer; |
|
|
|
|
cols = 0; |
|
|
|
|
int numValue; |
|
|
|
|
// Read untill newline
|
|
|
|
|
while (*ptrBuffer != '\n') { |
|
|
|
|
// Grow buffer when needed
|
|
|
|
|
arrNumbers = buffer_grow(arrNumbers, numCount, &sizeBufferTotal); |
|
|
|
|
// Convert string to base 10
|
|
|
|
|
numValue = strtol(ptrBuffer, &ptrBuffer, 10); |
|
|
|
|
// Store the number read in memory
|
|
|
|
|
arrNumbers[sizeBufferUsed++] = numValue; |
|
|
|
|
arrNumbers[numCount++] = numValue; |
|
|
|
|
cols++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (numProcesses > sizeBufferUsed / 2) { |
|
|
|
|
printf("*********************************************************************************\n"); |
|
|
|
|
printf("The number of processes if greater than number of parallel computations required!\n"); |
|
|
|
|
printf("*********************************************************************************\n\n"); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
//printf("count: %d, buffer: %d\n", sizeBufferUsed, sizeBufferTotal);
|
|
|
|
|
checkParallelWorth(numProcesses, numCount); |
|
|
|
|
|
|
|
|
|
int numBlockIndex = 0; |
|
|
|
|
int numRemainder = sizeBufferUsed % numProcesses; |
|
|
|
|
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] = sizeBufferUsed / numProcesses; |
|
|
|
|
arrBlockSizes[i] = numCount / numProcesses; |
|
|
|
|
if (numRemainder > 0) { |
|
|
|
|
arrBlockSizes[i]++; |
|
|
|
|
numRemainder--; |
|
|
|
@ -65,61 +68,139 @@ int main(int argc, char *argv[]) { |
|
|
|
|
|
|
|
|
|
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(&sizeBufferTotal, 1, MPI_INT, 0, MPI_COMM_WORLD); |
|
|
|
|
printf("total %d in %d\n", sizeBufferTotal, numRank); |
|
|
|
|
//int packet[NUM_CODES];
|
|
|
|
|
//MPI_Scatter(arrPackets, NUM_CODES, MPI_INT, packet, NUM_CODES, MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
MPI_Bcast(&numCount, 1, MPI_INT, 0, MPI_COMM_WORLD); |
|
|
|
|
MPI_Bcast(&cols, 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 *arrSlice = my_malloc(sizeBufferTotal * sizeof(int));
|
|
|
|
|
//MPI_Scatterv(arrNumbers, arrPackets, arrPackets, MPI_INT, arrSlice, sizeBufferTotal, MPI_INT, 0, MPI_COMM_WORLD);
|
|
|
|
|
|
|
|
|
|
int *arrSlice = my_malloc(sizeBufferTotal * sizeof(int)); |
|
|
|
|
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice, sizeBufferTotal, MPI_INT, 0, MPI_COMM_WORLD); |
|
|
|
|
|
|
|
|
|
/*printf("original matrix: \n");
|
|
|
|
|
for (int i = 0; i < sizeBufferUsed; i++) { |
|
|
|
|
printf("%d ", arrNumbers[i]); |
|
|
|
|
if ((i + 1) % cols == 0) |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
|
|
|
|
|
// We can calculate rows * cols = sizeBufferused
|
|
|
|
|
int rows = sizeBufferUsed / cols; |
|
|
|
|
int *arrIndices = my_malloc(sizeBufferUsed * sizeof(int)); |
|
|
|
|
for (int i = 0; i < sizeBufferUsed; i++) { |
|
|
|
|
//if (numRank == 0 ) {
|
|
|
|
|
//printf("original matrix: \n");
|
|
|
|
|
//for (int i = 0; i < numCount; i++) {
|
|
|
|
|
//printf("%d ", arrNumbers[i]);
|
|
|
|
|
//if ((i + 1) % cols == 0)
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//}
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
int arrTransp[NUM_CODES]; |
|
|
|
|
MPI_Recv(arrTransp, NUM_CODES, MPI_INT, 0, NUM_CODES, MPI_COMM_WORLD, &status); |
|
|
|
|
//for (int i = 0; i < numCount; i++) {
|
|
|
|
|
//printf("rank %d: m[%d] = %d\n", numRank, i, arrSlice[i]);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//We can calculate rows * cols = numCount
|
|
|
|
|
int rows = numCount / cols; |
|
|
|
|
int *arrIndices = 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++) { |
|
|
|
|
//if (i % rows == 0)
|
|
|
|
|
//printf("\n");
|
|
|
|
|
// Only the indices are transposed
|
|
|
|
|
int index = ((rows * i) / (cols * rows)) + ((rows * i) % (cols * rows)); |
|
|
|
|
arrIndices[index] = i; |
|
|
|
|
int index = transpose_index(i + arrTransp[CODE_INDEX], rows, cols); |
|
|
|
|
arrIndices[i] = index; |
|
|
|
|
//printf("%2d[%2d](%d)\n", i, index, numRank);
|
|
|
|
|
//arrIndices[index] = i;
|
|
|
|
|
//printf("%2d[%2d](%d)\n", index, i, numRank);
|
|
|
|
|
} |
|
|
|
|
//printf("\n");
|
|
|
|
|
|
|
|
|
|
printf("transposed matrix:"); |
|
|
|
|
for (int i = 0; i < sizeBufferUsed; i++) { |
|
|
|
|
if (i % rows == 0) |
|
|
|
|
printf("\n"); |
|
|
|
|
printf("%d ", arrNumbers[arrIndices[i]]); |
|
|
|
|
}*/ |
|
|
|
|
//printf("rank %d, rows %d, cols %d, count %d, index %2d, size %2d\n", numRank, rows, cols, numCount,
|
|
|
|
|
//arrTransp[CODE_INDEX], arrTransp[CODE_SIZE]);
|
|
|
|
|
|
|
|
|
|
int *arrMatrix; |
|
|
|
|
if (numRank == 0) |
|
|
|
|
arrMatrix = my_malloc(numCount * sizeof(int)); |
|
|
|
|
MPI_Gatherv(arrIndices, arrTransp[CODE_SIZE], MPI_INT, arrMatrix, arrBlockSizes, arrBlockIndices, MPI_INT, 0, MPI_COMM_WORLD); |
|
|
|
|
|
|
|
|
|
if (numRank == 0) { |
|
|
|
|
//for (int i = 0; i < numCount; i++) {
|
|
|
|
|
//printf("arrMatrix[%2d] = %2d\n", i, arrMatrix[i]);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
printf("transposed matrix:"); |
|
|
|
|
for (int i = 0; i < numCount; i++) { |
|
|
|
|
if (i % rows == 0) |
|
|
|
|
printf("\n"); |
|
|
|
|
printf("%d ", arrNumbers[arrMatrix[i]]); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//printf("\n");
|
|
|
|
|
MPI_Finalize(); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int transpose_index(int index, int rows, int cols) { |
|
|
|
|
//return ((rows * index) / (cols * rows)) + ((rows * index) % (colss * rows));
|
|
|
|
|
//return (index / cols) + rows * (index % cols);
|
|
|
|
|
return (index / rows) + cols * (index % rows); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//printf("trasnposed matrix:");
|
|
|
|
|
//for (int i = 0; i < sizeBufferUsed; i++) {
|
|
|
|
|
//for (int i = 0; i < numCount; i++) {
|
|
|
|
|
//if (i % rows == 0)
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//printf("%d ", arrTrans[i]);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
/* for (int i = 0; i < sizeBufferUsed; i++) {*/ |
|
|
|
|
/* for (int i = 0; i < numCount; i++) {*/ |
|
|
|
|
//if (i % rows == 0)
|
|
|
|
|
//printf("\n");
|
|
|
|
|
//printf("%2d[%2d]\t", i, arrIndices[i]);
|
|
|
|
|
/*}*/ |
|
|
|
|
|
|
|
|
|
//printf("rows: %zu, cols: %d\n", sizeBufferUsed / cols, cols);
|
|
|
|
|
//printf("rows: %zu, cols: %d\n", numCount / cols, cols);
|
|
|
|
|
/*
|
|
|
|
|
int numBlockIndex = 0; |
|
|
|
|
int numRemainder = numCount % numProcesses; |
|
|
|
|
|
|
|
|
|
arrBlockIndices = my_malloc(numProcesses * sizeof(int)); |
|
|
|
|
arrBlockSizes = my_malloc(numProcesses * sizeof(int)); |
|
|
|
|
int numPackets = numProcesses * NUM_CODES; |
|
|
|
|
arrPackets = my_malloc(numPackets * sizeof(int)); |
|
|
|
|
for (int i = 0; i < numPackets; i += NUM_CODES) { |
|
|
|
|
arrBlockSizes[i] = arrPackets[i + CODE_SIZE] = numCount / numProcesses; |
|
|
|
|
if (numRemainder > 0) { |
|
|
|
|
arrPackets[i]++; |
|
|
|
|
numRemainder--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
arrBlockIndices[i] = arrPackets[i + CODE_INDEX] = numBlockIndex; |
|
|
|
|
numBlockIndex += arrPackets[i]; |
|
|
|
|
arrPackets[i + CODE_COLS] = cols; |
|
|
|
|
arrPackets[i + CODE_COUNT] = numCount; |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
//for (int i = 0; i < numPackets; i += 2) {
|
|
|
|
|
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrPackets[i], i + 1, arrPackets[i + 1]);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//for (int i = 0; i < numProcesses; i++) {
|
|
|
|
|
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrPackets[i], i, arrPackets[i + 1]);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//for (int i = 0; i < numProcesses; i++) {
|
|
|
|
|
//MPI_Send(&arrPackets[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
|
|
|
|
|
//}
|
|
|
|
|