Work have be done thanks for the response
OPTION A:
Part 01:
Please download the attachment ‘MPI 01.tar.gz’ (Attached the file) and complete the following questions.
Q1: Understand the source code for each of the following five programs. Compile, run and paste one output sequence for each program.
(a) MPI-Hello.c (b) Ring-Example-1.c (c) Ring-Example-2.c
(d) Ring-Example-3.c (e) Send-Receive.c
Part 02:
Please download the attachment ‘MPI-02.tar.gz’ (Attached the file) and complete the four questions Q1 ~ Q4
Q1: Complete the program ‘Scatter-Reduce.c’ (Refer to ‘Scatter-Gather.c’) to compute the product of all elements in a given array.
Q2: Complete the program ‘Bcast-Reduce-Assignment.c’ (Refer to ‘Bcast-Reduce-Example.c’) to make the program have the output as follows if we run the program using 2 processes.
The input sequence is:
0 1 2 3
The output sequence is:
0 2 6 12
Q3: The MPI program ‘Standard-Deviation.c’ computes the standard deviation for an array of elements.(https://en.wikipedia.org/wiki/Standard_deviation
Links to an external site.). Here, we assume that the maximum number of elements in the array is 10. Some necessary error checkings are performed to ensure that the number of inputs is correct and their values are valid. Please run the program using each of the following commands and submit your screenshots for the outputs.
(a) mpiexec -n 2 ./Stddev (b) mpiexec -n 2 ./Stddev 0 (c) mpiexec -n 3 ./Stddev 7
(d) mpiexec -n 3 ./Stddev 9 (e) mpiexec -n 4 ./Stddev 21
Q4: Complete the MPI program ‘Send-Receive-Checking’ to perform the necessary error checking for our previous example ‘Send-Receive.c’ to ensure that two processes are required for running the program.
OPTION B
Part 03:
Please download the attachment ‘MPI-01.tar.gz’ (Attached the file) and complete the two questions Q1 and Q2 by following the instructions below.
Q1: Complete the program ‘Ring-Assignment-1.c’ to make the program work well for any number of processes specified by users and have one possible output sequence as follows if we run the program using 4 processes.
Process 0: Token value < 4 > is received from process 3
Process 2: Token value < 2 > is received from process 1
Process 1: Token value < 1 > is received from process 0
Process 3: Token value < 3 > is received from process 2
Q2: Complete the program ‘Ring-Assignment-2.c’ to make the program have the same outputs as ‘Ring-Example-2.c’.
Part 04:
Please download the attachment ‘Project Description ‘ (Attached the file) and complete the question Q1 by following the instructions below.
Q1: Write an MPI program ‘Estimate-Pi.c’ from the scratch to estimate the value of Pi (π) using a Monte Carlo method. Your program should perform necessary error checking for inputs. Please see the project description (
Project-Description
)
OPTION C:
Part 05:
Complete the assignment by following the instructions.
1. In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n.
Example: 4! = 4*3*2*1 = 24 Note: 0! = 1
Write a Pthreads program ‘Factorial.c’ from the scratch to calculate the factorial of a given non-negative integer. Your program should perform necessary error checking for inputs.
MPI-01/Ring-Pass/Ring-Pass-3/Ring-Example-3.c
////////////////////////////////////////////////////////////////
//
// This is our third version of ring pass program in MPI
//
// Compile: mpicc Ring-Example-3.c -o Ring-Example-3
//
// Run: mpiexec -n
./Ring-Example-3
//
// -p: the number of processes
//
///////////////////////////////////////////////////////////////
#include
#include
#include
#include
int main(void)
{
char Greeting[100];
int comm_sz, my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if (my_rank == 0)
{
sprintf(Greeting, “Greeting from process %d!”, my_rank);
MPI_Send(Greeting, strlen(Greeting) + 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
/* print out the message */
printf(“Process %d sent the message > %s < to process %d\n", my_rank, Greeting, my_rank + 1);
MPI_Recv(Greeting, 100, MPI_CHAR, comm_sz - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Process %d received: %s \n", my_rank, Greeting);
}
else if (my_rank == comm_sz - 1)
{
MPI_Recv(Greeting, 100, MPI_CHAR, my_rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Send(Greeting, strlen(Greeting) + 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
/* print out the message */
printf("Process %d sent the message > %s < to process %d\n", my_rank, Greeting, 0);
}
else
{
MPI_Recv(Greeting, 100, MPI_CHAR, my_rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Send(Greeting, strlen(Greeting) + 1, MPI_CHAR, my_rank + 1, 0, MPI_COMM_WORLD);
/* print out the message */
printf("Process %d sent the message > %s < to process %d\n", my_rank, Greeting, my_rank + 1);
}
MPI_Finalize();
return 0;
}
MPI-01/Ring-Pass/Ring-Pass-2/Ring-Assignment-2.c
#include
#include
#include
#include
int main(void)
{
char Greeting[100];
int comm_sz, my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
sprintf(Greeting, “Greeting from process %d!”, my_rank);
MPI_Send(&Greeting, strlen(Greeting) + 1, MPI_CHAR, (my_rank + 1) % comm_sz, 0, MPI_COMM_WORLD);
if (my_rank != 0)
{
}
else
{
}
MPI_Finalize();
return 0;
}
MPI-01/Ring-Pass/Ring-Pass-2/Ring-Example-2.c
/////////////////////////////////////////////////////////////////
//
// This is our second version of ring pass program in MPI
//
// Compile: mpicc Ring-Example-2.c -o Ring-Example-2
//
// Run: mpiexec -n
./Ring-Example-2
//
// -p: the number of processes
//
///////////////////////////////////////////////////////////////
#include
#include
#include
#include
int main(void)
{
char Greeting[100];
int comm_sz, my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
// The function ‘sprintf’ is very similar to the function ‘print’, except that
// instead of writing to stdout, it writes to a string.
sprintf(Greeting, “Greeting from process %d!”, my_rank);
MPI_Send(Greeting, strlen(Greeting) + 1, MPI_CHAR, (my_rank + 1) % comm_sz, 0, MPI_COMM_WORLD);
/* print out the message */
printf(“Process %d sent message to process %d\n”, my_rank, (my_rank + 1) % comm_sz);
if (my_rank == 0)
{
MPI_Recv(Greeting, 100, MPI_CHAR, comm_sz – 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* print out the message */
printf(“Process %d received message: %s\n”, my_rank, Greeting);
}
else
{
MPI_Recv(Greeting, 100, MPI_CHAR, my_rank – 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* print out the message */
printf(“Process %d received message: %s\n”, my_rank, Greeting);
}
MPI_Finalize();
return 0;
}
MPI-01/Ring-Pass/Ring-Pass-1/Ring-Assignment-1.c
#include
#include
#include
int main(void)
{
int comm_sz, my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int token = 1;
MPI_Send(&token, 1, MPI_INT, (my_rank + 1) % comm_sz, 0, MPI_COMM_WORLD);
if (my_rank == 0)
MPI_Recv(&token, 1, MPI_INT, comm_sz – 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
else
MPI_Recv(&token, 1, MPI_INT, my_rank – 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Finalize();
return 0;
}
MPI-01/Ring-Pass/Ring-Pass-1/Ring-Example-1.c
/////////////////////////////////////////////////////////////////
//
// This is our first version of ring pass program in MPI
//
// Compile: mpicc Ring-Example-1.c -o Ring-Example-1
//
// Run: mpiexec -n
./Ring-Example-1
//
// -p: the number of processes
//
///////////////////////////////////////////////////////////////
#include
#include
#include
int main(void)
{
int comm_sz, my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int token = 1;
MPI_Send(&token, 1, MPI_INT, (my_rank + 1) % comm_sz, 0, MPI_COMM_WORLD);
if (my_rank == 0)
{
MPI_Recv(&token, 1, MPI_INT, comm_sz – 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* print out the message */
printf(“Process %d received token value < %d > from process %d\n”, my_rank, token, comm_sz – 1);
}
else
{
MPI_Recv(&token, 1, MPI_INT, my_rank – 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* print out the message */
printf(“Process %d received token value < %d > from process %d\n”, my_rank, token, my_rank – 1);
}
MPI_Finalize();
return 0;
}
MPI-01/Hello-World/MPI-Hello.c
////////////////////////////////////////////////////////////////
//
// This is a simple hello world program in MPI
//
// Compile: mpicc Hello-World.c -o Hello-World
//
// Run: mpiexec -n
./Hello-World
//
// -p: the number of processes
//
///////////////////////////////////////////////////////////////
#include
#include
#include
int main(void)
{
int comm_sz, my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
/* print out the message */
printf(“Hello from process %d of %d\n”, my_rank, comm_sz);
MPI_Finalize();
return 0;
}
MPI-01/Send-Receive/Send-Receive.c
////////////////////////////////////////////////////////////////
//
// This is a simple send/receive program in MPI
//
// Compile: mpicc Send-Receive.c -o Send-Receive
//
// Run: mpiexec -n 2 ./Send-Receive
//
///////////////////////////////////////////////////////////////
#include
#include
#include
int main(void)
{
int my_rank, comm_sz;
int token = 1;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(my_rank == 0)
{
MPI_Send(&token, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
printf(“Process %d sent token %d to process 1\n”, my_rank, token);
}
else
{
MPI_Recv(&token, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf(“Process %d received token %d from process 0\n”, my_rank, token);
}
MPI_Finalize();
return 0;
}
MPI-02/Question-04/Send-Receive-Checking.c
////////////////////////////////////////////////////////////////
//
// This is a simple send/receive program in MPI
//
// Compile: mpicc Send-Receive-Checking.c -o Send-Receive
//
// Run: mpiexec -n 2 ./Send-Receive
//
///////////////////////////////////////////////////////////////
#include
#include
#include
int main(int argc, char* argv[])
{
int my_rank, comm_sz;
int token = 1;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if ( )
{
if (my_rank == 0)
fprintf(stderr, ” \n”);
MPI_Finalize();
return 0;
}
if(my_rank == 0)
{
MPI_Send(&token, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
printf(“\nProcess %d sent token %d to process 1.\n”, my_rank, token);
}
else
{
MPI_Recv(&token, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf(“Process %d received token %d from process 0.\n\n”, my_rank, token);
}
MPI_Finalize();
return 0;
}
MPI-02/Question-01/Scatter-Reduce.c
#include
#include
#include
#include
int *Random_Num_Generator(int Num_Elements);
int Compute_Product(int *array, int num_elements);
int main(int argc, char* argv[])
{
int comm_sz, my_rank;
int i, Result;
int Num_Per_Proc = atoi(argv[1]);
// Seed the random number generator to get different results each time
srand(time(NULL));
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
// Generate a random array of elements on process 0
int *Random_Nums = NULL;
if (my_rank == 0)
{
Random_Nums = Random_Num_Generator(Num_Per_Proc * comm_sz);
printf(“The random numbers generated: \n”);
for (i = 0; i < Num_Per_Proc * comm_sz; i++)
printf("%d; ", Random_Nums[i]);
printf("\n");
}
// Generate a buffer for holding a subset of the entire array
int *Sub_Random_Nums = (int *)malloc(sizeof(int) * Num_Per_Proc);
// Scatter the random integer numbers from process 0 to all processes
MPI_Scatter(Random_Nums, Num_Per_Proc, MPI_INT, Sub_Random_Nums, Num_Per_Proc, MPI_INT, 0, MPI_COMM_WORLD);
// Compute the product value of a subset array on each process
int Sub_Product = Compute_Product(Sub_Random_Nums, Num_Per_Proc);
// Reduce the total product value of all elements to process 0
MPI_Reduce(&Sub_Product, , 1, MPI_INT, , 0, MPI_COMM_WORLD);
if (my_rank == 0)
printf("Total product of all elements is %d\n", Result);
// Clean up
if (my_rank == 0)
free(Random_Nums);
free(Sub_Random_Nums);
MPI_Finalize();
return 0;
}
// Create an array of random integer numbers ranging from 1 to 10
int *Random_Num_Generator(int Num_Elements)
{
int *Rand_Nums = (int *)malloc(sizeof(int) * Num_Elements);
int i;
for (i = 0; i < Num_Elements; i++)
Rand_Nums[i] = (rand() % 10) + 1;
return Rand_Nums;
}
// Computes the product of an array of numbers
int Compute_Product(int *array, int num_elements)
{
int product = 1;
int i;
for (i = 0; i < num_elements; i++)
product *= array[i];
return product;
}
MPI-02/Question-01/Scatter-Gather.c
/////////////////////////////////////////////////////////////////////////
//
// This is an MPI program using MPI_Scatter and MPI_Gather functions
// to compute the product of all elements in a given array.
//
// Note: The array is generated according to its size, which is the
// number of elements per process times the number of processes.
//
// Compile: mpicc Scatter-Gather.c -o Scatter-Gather-Example
//
// Run: mpiexec -n
./Scatter-Gather-Example
//
// -p: the number of processes
// -N: the number of elements per process
//
/////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
int *Random_Num_Generator(int Num_Elements);
int Compute_Product(int *array, int num_elements);
int main(int argc, char* argv[])
{
int comm_sz, my_rank;
int i;
int Num_Per_Proc = atoi(argv[1]);
// Seed the random number generator to get different results each time
srand(time(NULL));
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
// Generate a random array of elements on process 0
int *Random_Nums = NULL;
if (my_rank == 0)
{
Random_Nums = Random_Num_Generator(Num_Per_Proc * comm_sz);
printf(“The random numbers generated: \n”);
for (i = 0; i < Num_Per_Proc * comm_sz; i++)
printf("%d ", Random_Nums[i]);
printf("\n");
}
// Generate a buffer for holding a subset of the entire array
int *Sub_Random_Nums = (int *)malloc(sizeof(int) * Num_Per_Proc);
// Scatter the random integer numbers from process 0 to all processes
MPI_Scatter(Random_Nums, Num_Per_Proc, MPI_INT, Sub_Random_Nums, Num_Per_Proc, MPI_INT, 0, MPI_COMM_WORLD);
// Compute the product value of a subset array on each process
int Sub_Product = Compute_Product(Sub_Random_Nums, Num_Per_Proc);
// Gather all partial product values to process 0
int *Partial_Results = NULL;
if (my_rank == 0)
Partial_Results = (int *)malloc(sizeof(int) * comm_sz);
MPI_Gather(&Sub_Product, 1, MPI_INT, Partial_Results, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Compute the total product value of all numbers on process 0
if (my_rank == 0)
{
int Result = Compute_Product(Partial_Results, comm_sz);
printf("Total product of all elements is %d\n", Result);
}
// Clean up
if (my_rank == 0)
{
free(Random_Nums);
free(Partial_Results);
}
free(Sub_Random_Nums);
MPI_Finalize();
return 0;
}
// Create an array of random integer numbers ranging from 1 to 10
int *Random_Num_Generator(int Num_Elements)
{
int *Rand_Nums = (int *)malloc(sizeof(int) * Num_Elements);
int i;
for (i = 0; i < Num_Elements; i++)
Rand_Nums[i] = (rand() % 10) + 1;
return Rand_Nums;
}
// Computes the product of an array of numbers
int Compute_Product(int *array, int num_elements)
{
int product = 1;
int i;
for (i = 0; i < num_elements; i++)
product *= array[i];
return product;
}
MPI-02/Question-03/Standard-Deviation.c
///////////////////////////////////////////////////////////////////////////////////////
//
// This is an MPI program that computes the standard deviation for an array of elements.
//
// Note: The array is generated according to its size (the number of elements), which
// is specified by users from the command line. In the program, we assume its
// maximum number is 10.
//
// Compile: mpicc Standard-Deviation.c -o Stddev -lm
//
// Run: mpiexec -n
./Stddev
//
// -p: the number of processes
// -N: the number of elements
//
///////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
int *Random_Num_Generator(int Num_Elements);
int Compute_Sum(int *array, int num_elements);
int main(int argc, char** argv)
{
int comm_sz, my_rank;
int i, Product;
double local_start, local_finish, local_elapsed, elapsed;
//Seed the random number generator to get different results each time
srand(time(NULL));
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
//The error checking here should be performed to ensure that the number of arguments is 2. Otherwise, the usage is printed.
if (argc != 2)
{
if (my_rank == 0)
fprintf(stderr, “USAGE: mpiexec -n
MPI_Finalize();
return 0;
}
int Num_Elements = atoi(argv[1]);
//The error checking here is performed to ensure that the size of vector is an integer in the range between 1 and 10.
if (Num_Elements < 1 || Num_Elements > 10)
{
if (my_rank == 0)
fprintf(stderr, “Error: The size of the vector should be an integer in the range between 1 and 10!\n”);
MPI_Finalize();
return 0;
}
// The error checking here is performed to ensure that the number of elements are evenly divisible by the number of the processes
if (Num_Elements % comm_sz != 0)
{
if (my_rank == 0)
fprintf(stderr, “Error: The size of the vector should be evenly divisible by the number of Processes!\n”);
MPI_Finalize();
return 0;
}
// Generate a random array of elements on process 0
int *Random_Nums = NULL;
if (my_rank == 0)
{
Random_Nums = Random_Num_Generator(Num_Elements);
printf(“\nThe random numbers generated: \n”);
for (i = 0; i < Num_Elements; i++)
printf("%d ", Random_Nums[i]);
printf("\n");
}
// Compute number of random intergers on each process
int Num_Per_Proc = Num_Elements / comm_sz;
// Generate a buffer for holding a subset of the entire array
int *Sub_Random_Nums = (int *)malloc(sizeof(int) * Num_Per_Proc);
// Scatter the random integer numbers from process 0 to all processes
MPI_Scatter(Random_Nums, Num_Per_Proc, MPI_INT, Sub_Random_Nums, Num_Per_Proc, MPI_INT, 0, MPI_COMM_WORLD);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Start point for code to be timed
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
MPI_Barrier(MPI_COMM_WORLD);
local_start = MPI_Wtime();
// Compute the sum of the subset array on each process
int Sub_Sum = Compute_Sum(Sub_Random_Nums, Num_Per_Proc);
// Compute the sum of the entire array and distribute it to each process
int Total_Sum;
MPI_Allreduce(&Sub_Sum, &Total_Sum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
// Compute the average of the entire array on each process
float Average = (float) Total_Sum / Num_Elements;
// Compute the partial sum of the squared differences from the average on each process
float Sub_Square_diff = 0;
for (i = 0; i < Num_Per_Proc; i++)
Sub_Square_diff += (Sub_Random_Nums[i] - Average) * (Sub_Random_Nums[i] - Average);
// Reduce the total sum of the squared differences to the process 0 (root process)
float Total_Square_diff;
MPI_Reduce(&Sub_Square_diff, &Total_Square_diff, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
// Compute the standard deviation
if (my_rank == 0)
{
// The standard deviation is the square root of the averaged total sum of squared differences
float Standard_Deviation = sqrt(Total_Square_diff / Num_Elements);
printf("Standard deviation = %f\n", Standard_Deviation);
}
local_finish = MPI_Wtime();
local_elapsed = local_finish - local_start;
MPI_Reduce(&local_elapsed, &elapsed, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
if (my_rank == 0)
printf("Elapsed time = %e seconds\n", elapsed);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// End point for Code to be timed
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Clean up
if (my_rank == 0)
free(Random_Nums);
free(Sub_Random_Nums);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
// Create an array of random integer numbers ranging from 1 to 10
int *Random_Num_Generator(int Num_Elements)
{
int *Rand_Nums = (int *)malloc(sizeof(int) * Num_Elements);
int i;
for (i = 0; i < Num_Elements; i++)
Rand_Nums[i] = (rand() % 10) + 1;
return Rand_Nums;
}
// Computes the sum of an array of numbers
int Compute_Sum(int *array, int num_elements)
{
int sum = 0;
int i;
for (i = 0; i < num_elements; i++)
sum += array[i];
return sum;
}
MPI-02/Question-02/Bcast-Reduce-Example.c
//////////////////////////////////////////////////////////////////////////
//
// This is a simple MPI program using MPI_Bcast and MPI_Reduce functions
//
// Compile: mpicc Bcast-Reduce-Example.c -o Bcast-Reduce-Example
//
// Run: mpiexec -n
./Bcast-Reduce-Example
//
// -p: the number of processes
//
/////////////////////////////////////////////////////////////////////////
#include
#include
#include
int main(void)
{
int my_rank, comm_sz;
int i;
int Count = 4;
int Number[4];
int PartialResult = 0;
int Result;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(my_rank == 0)
{
printf(“The input sequence is as follows: \n”);
for (i = 0; i < Count; i++)
{
Number[i] = i;
printf("%d ", Number[i]);
}
printf("\n");
}
// Process 0 sends data to all of the processes
MPI_Bcast(Number, Count, MPI_INT, 0, MPI_COMM_WORLD);
for (i = 0; i < Count; i++)
{
Number[i] += my_rank;
PartialResult += Number[i];
}
MPI_Reduce(&PartialResult, &Result, 1, MPI_INT, MPI_PROD, 0, MPI_COMM_WORLD);
// Print out the result
if (my_rank == 0)
printf("The final resutl is: %d. \n", Result);
MPI_Finalize();
return 0;
}
MPI-02/Question-02/Bcast-Reduce-Assignment.c
#include
#include
#include
int main(void)
{
int my_rank, comm_sz;
int i;
int Count = 4;
int Number[4];
int Result[4];
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(my_rank == 0)
{
printf(“The input sequence is: \n”);
for (i = 0; i < Count; i++)
{
Number[i] = i;
printf("%d ", Number[i]);
}
printf("\n");
}
// Process 0 sends data to all of the processes
MPI_Bcast(Number, Count, MPI_INT, 0, MPI_COMM_WORLD);
for (i = 0; i < Count; i++)
Number[i] += my_rank;
MPI_Reduce( , Result, , MPI_INT, MPI_PROD, 0, MPI_COMM_WORLD);
// Print out the result
if (my_rank == 0)
{
printf("The output sequence is: \n");
printf("\n");
}
MPI_Finalize();
return 0;
}
1
Project Description
Write an MPI program that uses a Monte Carlo method to estimate π. Suppose we toss darts
randomly at a square dartboard, whose bullseye is at the origin, and whose sides are 2 feet in
length. Suppose also that there’s a circle inscribed in the square dartboard. The radius of the
circle is 1 foot, and its area is π square feet. If the points that are hit by the darts are
uniformly distributed (and we always hit the square), then the number of darts that hit inside
the circle should approximately satisfy the equation
number in circle
total number of tosses
=
𝜋
4
,
since the ratio of the area of the circle to the area of the square is π/4.
We can use this formula to estimate the value of π with a random number generator:
number_in_circle = 0;
for (toss = 0; toss < number_of_tosses; toss++) {
x = random double between -1 and 1;
y = random double between -1 and 1;
distance_squared = x*x + y*y;
if (distance_squared <= 1) number_in_circle++;
}
pi_estimate = 4*number_in_circle/((double) number_of_tosses);
This is called a “Monte Carlo” method, since it uses randomness (the dart tosses).
Specifically, the MPI program can be implemented in the following way.
(1) Process 0 should read in the total number of tosses and broadcast it to the other processes.
(2) Use MPI_Reduce to find the global sum of the local variable number_in_circle, and have
process 0 print the result.
(3) You may want to use long long ints for the number of hits in the circle and the number
of tosses, since both may have to be very large to get a reasonable estimate of π.
Pthreads-01/Matrix-Vector-Multiplication/Pthreads-Version/Pth_Mat_Vect.c
///////////////////////////////////////////////////////////////////////////////////////
//
// Purpose: This is a parallel implementation of matrix-vector multiplication.
// Matrix and vector are distributed by block rows and blocks, respectively.
//
// Compile: gcc Pth_Mat_Vect.c -o Pth_Mat_Vect -lpthread
//
// Usage: ./Pth_Mat_Vect
// Notes:
// 1. Local storage for A, x, y is dynamically allocated.
// 2. Number of threads(thread_count) should evenly divide both
// m and n.The program doesn’t check for this.
// 3. We use a 1 – dimensional array for A and compute subscripts
// using the formula A[i][j] = A[i*n + j]
// 4. Distribution of A, x, and y is logical : all three are
// globally shared.
//
///////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
int thread_count;
int m, n;
double* A;
double* x;
double* y;
// Serial functions
void Get_dims(int* m_p, int* n_p);
void Read_matrix(double A[], int m, int n);
void Read_vector(double x[], int n);
void Print_result(double y[], int m);
// Parallel function
void *Pth_mat_vect(void* rank);
int main(int argc, char* argv[])
{
long thread;
pthread_t* thread_handles;
if (argc != 2)
fprintf(stderr, “usage: pth_mat_vect
thread_count = atoi(argv[1]);
thread_handles = malloc(thread_count*sizeof(pthread_t));
Get_dims(&m, &n);
A = malloc(m*n*sizeof(double));
x = malloc(n*sizeof(double));
y = malloc(m*sizeof(double));
Read_matrix(A, m, n);
Read_vector(x, n);
for (thread = 0; thread < thread_count; thread++)
pthread_create(&thread_handles[thread], NULL,
Pth_mat_vect, (void*) thread);
for (thread = 0; thread < thread_count; thread++)
pthread_join(thread_handles[thread], NULL);
Print_result(y, m);
free(A);
free(x);
free(y);
return 0;
}
////////////////////////////////////////////////////////////////
//
// Purpose: Read the dimensions of the matrix from stdin
//
////////////////////////////////////////////////////////////////
void Get_dims(int* m_p, int* n_p)
{
printf("Enter the number of rows\n");
scanf("%d", m_p);
printf("Enter the number of columns\n");
scanf("%d", n_p);
if (*m_p <= 0 || *n_p <= 0)
{
fprintf(stderr, "m and n must be positive\n");
exit(-1);
}
}
////////////////////////////////////////////////////////////////
//
// Purpose: Read the contents of the matrix from stdin
//
////////////////////////////////////////////////////////////////
void Read_matrix(double A[], int m, int n)
{
int i, j;
printf("Enter the matrix A:\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%lf", &A[i*n + j]);
}
////////////////////////////////////////////////////////////////
//
// Purpose: Read a vector from stdin
//
////////////////////////////////////////////////////////////////
void Read_vector(double x[], int n)
{
int i;
printf("Enter the vector x:\n");
for (i = 0; i < n; i++)
scanf("%lf", &x[i]);
}
////////////////////////////////////////////////////////////////
//
// Purpose: Multiply an mxn matrix by an nx1 column vector
//
////////////////////////////////////////////////////////////////
void *Pth_mat_vect(void* rank)
{
long my_rank = (long) rank;
int i, j;
int local_m = m/thread_count;
int my_first_row = my_rank*local_m;
int my_last_row = (my_rank+1)*local_m - 1;
for (i = my_first_row; i <= my_last_row; i++)
{
y[i] = 0.0;
for (j = 0; j < n; j++)
y[i] += A[i*n+j]*x[j];
}
return NULL;
}
////////////////////////////////////////////////////////////////
//
// Purpose: Print the contents of a vector to stdout
//
////////////////////////////////////////////////////////////////
void Print_result(double y[], int m)
{
int i;
printf("\nThe vector y:\n");
for (i = 0; i < m; i++)
printf("%f ", y[i]);
printf("\n");
}
Pthreads-01/Matrix-Vector-Multiplication/Serial-Version/Serial_Mat_Vect.c
/////////////////////////////////////////////////////////////////////////////////
//
// Purpose: This is a serial implementation of matrix-vector multiplication
// using one-dimensional arrays to store the vectors and the matrix.
//
// Compile: gcc Serial_Mat_Vect.c -o Serial_Mat_Vect
//
// Usage: ./Serial_Mat_Vect
//
//////////////////////////////////////////////////////////////////////////////////
#include
#include
void Get_dims(int* m_p, int* n_p);
void Read_matrix(double A[], int m, int n);
void Read_vector(double x[], int n);
void Print_result(double y[], int m);
void Mat_vect_mult(double A[], double x[], double y[], int m, int n);
int main(void)
{
double* A = NULL;
double* x = NULL;
double* y = NULL;
int m, n;
Get_dims(&m, &n);
A = malloc(m*n*sizeof(double));
x = malloc(n*sizeof(double));
y = malloc(m*sizeof(double));
if (A == NULL || x == NULL || y == NULL)
{
fprintf(stderr, “Can’t allocate storage\n”);
exit(-1);
}
Read_matrix(A, m, n);
Read_vector(x, n);
Mat_vect_mult(A, x, y, m, n);
Print_result(y, m);
free(A);
free(x);
free(y);
return 0;
}
//////////////////////////////////////////////////////////////// void * Hello_Fun() int main(int argc, char * argv[]) Pthreads-01/Hello-World/Version-02/Pth_Hello_2.c ////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[])
//
// Purpose: Read the dimensions of the matrix from stdin
//
////////////////////////////////////////////////////////////////
void Get_dims(int* m_p, int* n_p)
{
printf(“Enter the number of rows\n”);
scanf(“%d”, m_p);
printf(“Enter the number of columns\n”);
scanf(“%d”, n_p);
if (*m_p <= 0 || *n_p <= 0)
{
fprintf(stderr, "m and n must be positive\n");
exit(-1);
}
}
////////////////////////////////////////////////////////////////
//
// Purpose: Read the contents of the matrix from stdin
//
////////////////////////////////////////////////////////////////
void Read_matrix(double A[], int m, int n)
{
int i, j;
printf("Enter the matrix A:\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%lf", &A[i*n+j]);
}
////////////////////////////////////////////////////////////////
//
// Purpose: Read a vector from stdin
//
////////////////////////////////////////////////////////////////
void Read_vector(double x[], int n)
{
int i;
printf("Enter the vector x:\n");
for (i = 0; i < n; i++)
scanf("%lf", &x[i]);
}
////////////////////////////////////////////////////////////////
//
// Purpose: Print the contents of a vector to stdout
//
////////////////////////////////////////////////////////////////
void Print_result(double y[], int m)
{
int i;
printf("\nThe vector y:\n");
for (i = 0; i < m; i++)
printf("%f ", y[i]);
printf("\n");
}
////////////////////////////////////////////////////////////////
//
// Purpose: Multiply a matrix by a vector
//
////////////////////////////////////////////////////////////////
void Mat_vect_mult(double A[], double x[], double y[], int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
{
y[i] = 0.0;
for (j = 0; j < n; j++)
y[i] += A[i*n+j]*x[j];
}
}
Pthreads-01/Hello-World/Version-01/Pth_Hello_1.c
//////////////////////////////////////////////////////////////////////////
//
// Purpose: Create a single thread and print a message.
//
// Compile: gcc Pth_Hello_1.c -o Pth_Hello_1 -lpthread
//
// Usage: ./Pth_Hello_1
//
///////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
{
printf(“Hello World!\n”);
return NULL;
}
{
pthread_t thread; //Thread identifier
//Create a new thread to have it run the function Hello_Fun
pthread_create(&thread, NULL, Hello_Fun, NULL);
//Wait until the thread completes
pthread_join(thread, NULL);
return 0;
}
//
// Purpose: Create some threads, each of which prints a message.
//
// Compile: gcc Pth_Hello_2.c -o Pth_Hello_2 -lpthread
//
// Usage: ./Pth_Hello_2
///////////////////////////////////////////////////////////////////////////
#include
#include
#include
//Global variable: accessible to all threads
int thread_count;
void Usage(char* prog_name);
void *Hello(void* rank); //Thread function
{
long thread; //Use long in case of a 64-bit system
pthread_t* thread_handles;
//Get number of threads from command line
if (argc != 2) Usage(argv[0]);
thread_count = strtol(argv[1], NULL, 10);
if (thread_count <= 0 || thread_count > MAX_THREADS) Usage(argv[0]);
thread_handles = malloc (thread_count*sizeof(pthread_t));
for (thread = 0; thread < thread_count; thread++)
pthread_create(&thread_handles[thread], NULL,
Hello, (void*) thread);
printf("Hello from the main thread\n");
for (thread = 0; thread < thread_count; thread++)
pthread_join(thread_handles[thread], NULL);
free(thread_handles);
return 0;
} /* main */
void *Hello(void* rank)
{
long my_rank = (long) rank; //Use long in case of 64-bit system
printf("Hello from thread %ld of %d\n", my_rank, thread_count);
return NULL;
} /* Hello */
void Usage(char* prog_name)
{
fprintf(stderr, "usage: %s
fprintf(stderr, “0 < number of threads <= %d\n", MAX_THREADS);
exit(0);
} /* Usage */