/************************************************************ File: sum_array_mpi.cc Description: A program that genberates the elements of an array randomly and computes their sum. Author: Dana Vrajitoru Organization: IUSB Date: October 2020 **************************************************************/ #include #include #include #include #include #include #include using namespace std; // Computes and returns the sum of the elements of an array. int Compute_sum(int a[], int size) { int sum = 0; for (int i = 0; i < size; i++) sum += a[i]; return sum; } // Generates random numbers between 0 and the limit -1. The array must // have been allocated before calling this function. void Generate_array(int a[], int size, int limit) { int i; for (int i = 0; i < size; i++) a[i] = rand() % limit; } // Outputs the array void Write_array(int a[], int size) { cout << "The elements of the array are:" << endl; for (int i = 0; i < size; i++) cout << a[i] << ' '; cout << endl; } // Master function. Inputs the data, shares it woth the workers, // performs some computations, gathers results from the workers, then // outputs the result. void Master(int np) { int *a, size, limit, my_size, sum, other_sum; MPI_Status status; // Input data cout << "Enter the size of the array and the limit for their values" << endl; cin >> size >> limit; my_size = size/np; // Share with all the processes MPI_Bcast(&my_size, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&limit, 1, MPI_INT, 0, MPI_COMM_WORLD); // do the computations a = new int[my_size]; Generate_array(a, my_size, limit); Write_array(a, my_size); sum = Compute_sum(a, my_size); // Get the results from everyone else for (int i = 1; i < np; i++) { MPI_Recv(&other_sum, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &status); sum += other_sum; } // Output the results cout << "The sum of the elements of the array is " << sum << endl; delete a; } // Worker function. Gets some data from the master, performs // computations, and send the result to the master. void Worker() { int *a, limit, my_size, sum; MPI_Status status; // Get the data from the master MPI_Bcast(&my_size, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&limit, 1, MPI_INT, 0, MPI_COMM_WORLD); // do the computations a = new int[my_size]; Generate_array(a, my_size, limit); Write_array(a, my_size); sum = Compute_sum(a, my_size); // Send the result to the master MPI_Send(&sum, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); delete a; } // main function. Initializes things, then calls the master or worker // functions. Also does the timing. main(int argc, char **argv) { int size, limit; double timing; int my_id, nr_proc; /* Initialize MPI */ MPI_Init (&argc, &argv); /* Get the rank of this process */ MPI_Comm_rank (MPI_COMM_WORLD, &my_id); /* Get nb of processes */ MPI_Comm_size (MPI_COMM_WORLD, &nr_proc); srand(time(NULL) + my_id * 10); timing = MPI_Wtime(); if (my_id == 0) Master(nr_proc); else Worker(); timing = MPI_Wtime() - timing; cout << "This program has run on " << nr_proc << " processes in " << timing << " seconds." << endl; /* Finalize MPI */ MPI_Finalize (); return 0; }