Assignments for parallel processing using OpenMPI.
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.
 
 
 

133 lines
4.3 KiB

#include "common.h"
void *my_malloc(size_t size) {
void *ptr = malloc(size);
if (ptr == NULL) {
printf("Memory allocation unsuccessful.\n");
exit(EXIT_FAILURE);
}
return ptr;
}
void *my_calloc(size_t nitems, size_t size) {
void *ptr = calloc(nitems, size);
if (ptr == NULL) {
printf("Memory allocation with initialisation unsuccessful.\n");
exit(EXIT_FAILURE);
}
return ptr;
}
void *my_realloc(void *ptr, size_t size) {
void *temp = realloc(ptr, size);
if (temp == NULL) {
printf("Insufficient memory; can't add more items.\n");
exit(EXIT_FAILURE);
}
return temp;
}
FILE *my_fopen(const char *filename, const char *mode) {
FILE *file = fopen(filename, mode);
if (file == NULL) {
printf("File %s could not be opened.\n", filename);
exit(EXIT_FAILURE);
}
return file;
}
void *buffer_grow(void *ptr, int numCount, int *sizeBufferTotal) {
// Grow the buffer exponentially when needed
if (numCount == *sizeBufferTotal) {
*sizeBufferTotal *= GROWTH_FACTOR;
ptr = my_realloc(ptr, *sizeBufferTotal * sizeof(int));
}
return ptr;
}
bool check_parallel_worth(int numProcesses, int numCount, int limit) {
if (numProcesses > numCount / limit) {
//printf("*********************************************************************************\n");
printf("The number of processes if greater than number of parallel computations required!\n");
//printf("*********************************************************************************\n\n");
exit(EXIT_FAILURE);
}
return true;
}
void spread_evenly(int numProcesses, int numCount, int multiplier, int **arrBlockIndices, int **arrBlockSizes) {
int numBlockIndex = 0;
int numRemainder = numCount % numProcesses;
*arrBlockSizes = my_malloc(numProcesses * sizeof(int));
*arrBlockIndices = my_malloc(numProcesses * sizeof(int));
for (int i = 0; i < numProcesses; i++) {
int numBlockSize = numCount / numProcesses;
if (numRemainder > 0) {
numBlockSize++;
numRemainder--;
}
numBlockSize *= multiplier;
(*arrBlockSizes)[i] = numBlockSize;
int arrBlockData[NUM_CODES];
arrBlockData[CODE_SIZE] = numBlockSize;
arrBlockData[CODE_INDEX] = numBlockIndex;
//printf("size[%d] = %d\tindex[%d] = %d\n", i, numBlockSize, i, numBlockIndex);
(*arrBlockIndices)[i] = numBlockIndex;
numBlockIndex += numBlockSize;
// 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);
//(*ptrFciLoopEnd)(&numBlockSize, i);
//MPI_Send(&arrBlockSizes[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
}
}
void *read_matrix_file(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 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);
}