#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); }