Untitled
unknown
plain_text
2 years ago
3.5 kB
9
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...