Untitled

 avatar
unknown
plain_text
2 years ago
3.5 kB
5
Indexable
#include <mpi.h>
#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
#include "hw3_header.h" 

int main(int argc, char *argv[]) {
    //Initialize MPI
    int mpi_num_of_procs, mpi_rank;
    MPI_Status  status;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &mpi_num_of_procs);
    if (mpi_num_of_procs != NUM_MPI_PROCESSES) {
       printf("Run the example with two processes only\n");
       MPI_Abort(MPI_COMM_WORLD, __LINE__);
    }
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
    
    //Initialize host arrays
    size_t arr_size = ARR_SIZE * sizeof(int);
    size_t hist_size = NUM_RANGE * sizeof(int);
    int* h_array;
    int* h_hist;

    // Allocate memory for host array
    if ((h_array = (int*)malloc(arr_size)) == NULL)
    {
      printf("Host array allocation failed!\n");
      MPI_Abort(MPI_COMM_WORLD, __LINE__);
    }

    //Master sequentially creates array of random numbers and sends array to slave, each takes half
    //Since the array is read only, there is no race condition
    if(mpi_rank == 0)
    {
      //Generate random numbers
      for (int i = 0; i < ARR_SIZE; i++)
        h_array[i] = rand() % NUM_RANGE;

      MPI_Send(h_array, ARR_SIZE, MPI_INT, 1, 0, MPI_COMM_WORLD);
    }
    else
    {
      MPI_Recv(h_array, ARR_SIZE, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
    }

    // Allocate memory for histogram array, individual for each process since they are summed at the end
    if ((h_hist = (int*)malloc(hist_size)) == NULL)
    {
      printf("Host histogram allocation failed!\n");
      MPI_Abort(MPI_COMM_WORLD, __LINE__);
    }

    // Initialize histogram array for each process
    for (int i = 0;  i < NUM_RANGE;  i++)
      h_hist[i] = 0;
  
    //Initialize omp threads
    omp_set_num_threads(NUM_OMP_THREADS);

    // On each process - perform a first half of its task with OpenMP     
#pragma omp parallel shared(h_hist)    
{		
    int* h_hist_temp;

    if((h_hist_temp = (int*)malloc(hist_size))==NULL)
    {
      printf("Temporary histogram allocation failed!\n");
      MPI_Abort(MPI_COMM_WORLD, __LINE__);
    }

    for(int i=0; i<NUM_RANGE; i++)
    {
      h_hist_temp[i] = 0;
    }

    // Get OpenMP thread id
    int tid = omp_get_thread_num();

    
    if (computeOnGPU(h_array, 30, h_hist_temp) != 0)
       MPI_Abort(MPI_COMM_WORLD, __LINE__);
    
    // Sum all histograms for each thread by using pragma omp atomic to avoid race condition
    for(int i=0;i<NUM_RANGE;i++){
      #pragma omp atomic
      h_hist[i] += h_hist_temp[i];
    }

    //free temporary histogram
    free(h_hist_temp);
}
    // Collect the result on one of processes
    if (mpi_rank == 0) 
    {
      int* h_hist_slave;
      
      if ((h_hist_slave = (int*)malloc(hist_size)) == NULL)
      {
        printf("Slave histogram allocation failed!\n");
        MPI_Abort(MPI_COMM_WORLD, __LINE__);
      }
      
      MPI_Recv(h_hist_slave, NUM_RANGE, MPI_INT, 1, 0, MPI_COMM_WORLD, &status);
      for(int i=0;i<NUM_RANGE;i++)
      {
        h_hist[i] += h_hist_slave[i];
      }

      //free slave array
      free(h_hist_slave);

      printf("Task completed successfully!\n");
      printf("Result Histogram:\n");
      for(int i=0;i<NUM_RANGE;i++)
      {
        printf("%d:[%d]\n", i, h_hist[i]);
      }

    }
    else 
    {
      MPI_Send(h_hist, NUM_RANGE, MPI_INT, 0, 0, MPI_COMM_WORLD);
    }

    //Free host memory
    free(h_array);
    free(h_hist);

    MPI_Finalize();

    return 0;
}


Editor is loading...