Untitled

mail@pastecode.io avatar
unknown
plain_text
2 months ago
6.0 kB
3
Indexable
Never
/**
 *  \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");
}
Leave a Comment