Untitled
unknown
plain_text
a year ago
6.0 kB
6
Indexable
/** * \file bitonicSort.c (implementation file) * * \brief Problem name: Bitonic sort. * * Synchronization based MPI (Message Passing Interface). * * * \author Rafael Gil & Diogo Magalhães - May 2024 */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <stdbool.h> #include <math.h> #include <string.h> #include <time.h> #include <ctype.h> #include <mpich/mpi.h> /** * \brief Read file and populate data array * * \param fileName name of the file to read */ void readFile(char *fileName, int *lenNumberArray, int **numberArray); /** * \brief define the number of sub-sequences to be distributed * * \param numWorkers number of worker threads */ void defineSubSequences(int numWorkers, int lenSubSequences, int lenNumberArray, int toBeProcessed, int initialNumberWorkers, int *activeWorkers); /** * \brief checks if the number array is ordered in decreasing order */ extern void verifyIfSequenceIsOrdered(); /** * \brief Main thread. * * 1 --> Checks if it has received the adequate number of arguments * 2 --> Check the validity of the arguments it has received * 3 --> Allocate memory for the necessary data structures * 4 --> Initialize Distributor thread * 5 --> Initialize Worker threads * 6 --> Wait for Distributor thread to finish * 7 --> Wait for Worker threads to finish * 8 --> Check if the sequence is correctly sorted * 9 --> Print elapsed time * * \param argc number of words of the command line * \param argv list of words of the command line * * \return status of operation */ int main(int argc, char *argv[]){ int rank, size; /** * \brief workers activity status * * 1 --> completed work * 0 --> waiting for work * -1 --> exited */ int *activeWorkers; /** \brief initial number of workers */ int initialNumberWorkers; /** \brief array to store the numbers read from the file */ int *numberArray; /** \brief array to receive the numbers read from the file */ int *recNumberArray; /** \brief length of the number array */ int lenNumberArray; /** \brief length of the sub sequences */ int lenSubSequences; /** \brief number of sub sequences left */ int toBeProcessed; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if(size != 1 && size != 2 && size != 4 && size != 8){ fprintf(stderr, "Invalid number of threads\nValid: 1 / 2 / 4 / 8\n"); printf("Exiting program...\n"); MPI_Finalize(); exit(EXIT_FAILURE); } if (argc < 2){ fprintf(stderr, "Invalid number of arguments\n"); MPI_Finalize(); exit(EXIT_FAILURE); } if(rank == 0){ printf("ROOT is going to read file\n"); readFile(argv[1], &lenNumberArray, &numberArray); } MPI_Scatter(numberArray, lenNumberArray, MPI_BYTE, ); printf("Len: %d. Rank: %d\n", lenNumberArray, rank); MPI_Finalize(); } /** * \brief Read file and populate data array * * \param fileName name of the file to read */ void readFile(char *fileName, int *lenNumberArray, int **numberArray){ FILE *file; file = fopen (fileName, "rb"); // checkif it was able to open the file if(file == NULL ) { printf("Not able to open the file.\n"); MPI_Finalize(); exit(EXIT_FAILURE); } printf("file opened %d\n", *lenNumberArray); // read the first byte from the file // which represents the ammount of numbers the file has int err = fread(lenNumberArray, sizeof(int), 1, file); if(err <= 0){ printf("Error while reading file"); MPI_Finalize(); exit(EXIT_FAILURE); } printf("Seq size read %d", *lenNumberArray); // allocate memory for the array // that will store the numbers read from the file numberArray = malloc(*lenNumberArray * sizeof(int)); if(numberArray == NULL){ printf("Error while allocating memory"); MPI_Finalize(); exit(EXIT_FAILURE); } printf("\nSize: %d\n", *lenNumberArray); // read every number if(fread(numberArray, sizeof(int), *lenNumberArray, file) != *lenNumberArray){ printf("Error while reading numbers to array"); MPI_Finalize(); exit(EXIT_FAILURE); } // close file pointer fclose(file); } /** * \brief checks if the number array is ordered in decreasing order */ void verifyIfSequenceIsOrdered(int lenNumberArray, int *numberArray){ for (int i = 0; i < lenNumberArray - 1; i++) { if (numberArray[i] < numberArray[i + 1]) { printf ("Error in position %d between element %d and %d\n", i, numberArray[i], numberArray[i+1]); return; } } printf ("Everything is OK!\n"); } /** * \brief define the number of sub-sequences to be distributed * * \param numWorkers number of worker threads */ void defineSubSequences(int numWorkers, int lenSubSequences, int lenNumberArray, int toBeProcessed, int initialNumberWorkers, int *activeWorkers){ lenSubSequences = lenNumberArray / numWorkers; toBeProcessed = initialNumberWorkers = numWorkers; if((activeWorkers = malloc(numWorkers * sizeof(int))) == NULL){ fprintf(stderr, "Error allocating memory for activeWorkers array\n"); MPI_Finalize(); exit(EXIT_FAILURE); } for (int i = 0; i < numWorkers; i++) { activeWorkers[i] = 0; // every worker is waiting for work at the start } } /** * \brief Print a formatted array * * \param arr array to be printed * \param size size of the array */ static void print_int_array(int *arr, int size){ printf("["); for (int i = 0; i < size; i++){ if (i != 0){ printf(", "); } printf("%d", arr[i]); } printf("]\n"); }
Editor is loading...
Leave a Comment