parent
82289ba54a
commit
4f3a6d78ac
@ -0,0 +1,148 @@ |
||||
#include "common.h" |
||||
|
||||
#define INPUTFILE1 "assignment3.in1" |
||||
#define INPUTFILE2 "assignment3.in2" |
||||
|
||||
// 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); |
||||
|
||||
void *read_datafile(const char *filename, int *numCols, int *numCount) { |
||||
// To avoid aggresive buffer growth at the beggining of the sequence
|
||||
int sizeBufferTotal = INIT_BUFFER_SIZE; |
||||
// Allocate enough memory for initial buffer
|
||||
int *ptr = my_malloc(sizeBufferTotal * sizeof(int)); |
||||
// Open the file with input data
|
||||
FILE *ptrFile = my_fopen(filename, "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
|
||||
ptr = buffer_grow(ptr, *numCount, &sizeBufferTotal); |
||||
// Convert string to base 10
|
||||
numValue = strtol(ptrBuffer, &ptrBuffer, 10); |
||||
// Store the number read in memory
|
||||
ptr[*numCount] = numValue; |
||||
*numCount = *numCount + 1; |
||||
*numCols = *numCols + 1; |
||||
} |
||||
} |
||||
|
||||
fclose(ptrFile); |
||||
|
||||
return ptr; |
||||
} |
||||
|
||||
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, *arrIndicesTransp, *arrBlockSizes, *arrBlockIndices; |
||||
int numCols1, numCount1 = 0, numCols2, numCount2 = 0; |
||||
|
||||
if (numRank == 0) { |
||||
arrMatrix1 = read_datafile(INPUTFILE1, &numCols1, &numCount1); |
||||
arrMatrix2 = read_datafile(INPUTFILE2, &numCols2, &numCount2); |
||||
|
||||
checkParallelWorth(numProcesses, numCount1); |
||||
|
||||
arrIndicesTransp = my_malloc(numCount1 * sizeof(int)); |
||||
|
||||
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]; |
||||
|
||||
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(&numCount1, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
MPI_Bcast(&numCols1, 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 * numCols1 = numCount1
|
||||
int numRows = numCount1 / numCols1; |
||||
int *arrIndicesSub = my_malloc(numCount1 * 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, numCols1); |
||||
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 < numCount1; i++) {
|
||||
//printf("%d ", arrMatrix1[i]);
|
||||
//if ((i + 1) % numCols1 == 0)
|
||||
//printf("\n");
|
||||
//}
|
||||
//printf("\n");
|
||||
//}
|
||||
|
||||
if (numRank == 0) { |
||||
printf("transposed matrix:"); |
||||
for (int i = 0; i < numCount1; i++) { |
||||
if (i % numRows == 0) |
||||
printf("\n"); |
||||
printf("%d ", arrMatrix1[arrIndicesTransp[i]]); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
|
||||
printf("fe %d\n", arrMatrix2[0]); |
||||
|
||||
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); |
||||
} |
||||
|
Loading…
Reference in new issue