Untitled
unknown
plain_text
2 years ago
6.0 kB
7
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