//Carter Wright
//Program to compute the value of Pi
//demonstrating parallel computing capabilities
// Include necessary libraries
#include <mpi.h>
#include <cmath>
#include <cstdlib>
#include <iostream>
// Function to compute pi using the sum of the reciprocals of the squares method
double compute_pi_reciprocal_squares(int rank, int size, int num_terms) {
double sum = 0.0;
// Each process computes a part of the sum
for (int i = rank + 1; i <= num_terms; i += size) {
sum += 1.0 / (i * i);
}
return sum;
}
// Function to compute pi using the trapezoid rule
double compute_pi_trapezoid(int rank, int size, int num_intervals) {
double h = 1.0 / num_intervals;
double sum = 0.0;
// Each process computes a part of the sum
for (int i = rank + 1; i <= num_intervals; i += size) {
double x = h * (i - 0.5);
sum += 4.0 / (1.0 + x * x);
}
return h * sum;
}
int main(int argc, char *argv[]) {
// Initialize MPI and get the rank and size
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Process 0 asks the user for the method and the number of terms or intervals
if (rank == 0) {
std::cout << "Enter the method you wish to use (1=reciprocal squares, 2=trapezoid rule): ";
int method;
std::cin >> method;
// Broadcast the method to all processes
MPI_Bcast(&method, 1, MPI_INT, 0, MPI_COMM_WORLD);
std::cout << "Enter the number of terms or intervals: ";
int num;
std::cin >> num;
// Broadcast the number of terms or intervals to all processes
MPI_Bcast(&num, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
// All processes receive the method and the number of terms or intervals
int method, num;
MPI_Bcast(&method, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&num, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Depending on the method, compute the local sum
double local_sum;
if (method == 1) {
local_sum = compute_pi_reciprocal_squares(rank, size, num);
} else if (method == 2) {
local_sum = compute_pi_trapezoid(rank, size, num);
}
// Reduce the local sums to a global sum
double global_sum;
MPI_Reduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
// Process 0 computes and prints the value of Pi
if (rank == 0) {
double pi;
if (method == 1) {
pi
= sqrt(6.0 * global_sum
); } else if (method == 2) {
pi = global_sum;
}
printf("Computed value of Pi: %f\n", pi
); }
// Finalize MPI and end the program
MPI_Finalize();
return 0;
}
Ly9DYXJ0ZXIgV3JpZ2h0Ci8vUHJvZ3JhbSB0byBjb21wdXRlIHRoZSB2YWx1ZSBvZiBQaQovL2RlbW9uc3RyYXRpbmcgcGFyYWxsZWwgY29tcHV0aW5nIGNhcGFiaWxpdGllcwoKCi8vIEluY2x1ZGUgbmVjZXNzYXJ5IGxpYnJhcmllcwojaW5jbHVkZSA8bXBpLmg+CiNpbmNsdWRlIDxjbWF0aD4KI2luY2x1ZGUgPGNzdGRsaWI+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCi8vIEZ1bmN0aW9uIHRvIGNvbXB1dGUgcGkgdXNpbmcgdGhlIHN1bSBvZiB0aGUgcmVjaXByb2NhbHMgb2YgdGhlIHNxdWFyZXMgbWV0aG9kCmRvdWJsZSBjb21wdXRlX3BpX3JlY2lwcm9jYWxfc3F1YXJlcyhpbnQgcmFuaywgaW50IHNpemUsIGludCBudW1fdGVybXMpIHsKICAgIGRvdWJsZSBzdW0gPSAwLjA7CiAgICAvLyBFYWNoIHByb2Nlc3MgY29tcHV0ZXMgYSBwYXJ0IG9mIHRoZSBzdW0KICAgIGZvciAoaW50IGkgPSByYW5rICsgMTsgaSA8PSBudW1fdGVybXM7IGkgKz0gc2l6ZSkgewogICAgICAgIHN1bSArPSAxLjAgLyAoaSAqIGkpOwogICAgfQogICAgcmV0dXJuIHN1bTsKfQoKLy8gRnVuY3Rpb24gdG8gY29tcHV0ZSBwaSB1c2luZyB0aGUgdHJhcGV6b2lkIHJ1bGUKZG91YmxlIGNvbXB1dGVfcGlfdHJhcGV6b2lkKGludCByYW5rLCBpbnQgc2l6ZSwgaW50IG51bV9pbnRlcnZhbHMpIHsKICAgIGRvdWJsZSBoID0gMS4wIC8gbnVtX2ludGVydmFsczsKICAgIGRvdWJsZSBzdW0gPSAwLjA7CiAgICAvLyBFYWNoIHByb2Nlc3MgY29tcHV0ZXMgYSBwYXJ0IG9mIHRoZSBzdW0KICAgIGZvciAoaW50IGkgPSByYW5rICsgMTsgaSA8PSBudW1faW50ZXJ2YWxzOyBpICs9IHNpemUpIHsKICAgICAgICBkb3VibGUgeCA9IGggKiAoaSAtIDAuNSk7CiAgICAgICAgc3VtICs9IDQuMCAvICgxLjAgKyB4ICogeCk7CiAgICB9CiAgICByZXR1cm4gaCAqIHN1bTsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkgewogICAgLy8gSW5pdGlhbGl6ZSBNUEkgYW5kIGdldCB0aGUgcmFuayBhbmQgc2l6ZQogICAgaW50IHJhbmssIHNpemU7CiAgICBNUElfSW5pdCgmYXJnYywgJmFyZ3YpOwogICAgTVBJX0NvbW1fcmFuayhNUElfQ09NTV9XT1JMRCwgJnJhbmspOwogICAgTVBJX0NvbW1fc2l6ZShNUElfQ09NTV9XT1JMRCwgJnNpemUpOwoKICAgIC8vIFByb2Nlc3MgMCBhc2tzIHRoZSB1c2VyIGZvciB0aGUgbWV0aG9kIGFuZCB0aGUgbnVtYmVyIG9mIHRlcm1zIG9yIGludGVydmFscwogICAgaWYgKHJhbmsgPT0gMCkgewogICAgICAgIHN0ZDo6Y291dCA8PCAiRW50ZXIgdGhlIG1ldGhvZCB5b3Ugd2lzaCB0byB1c2UgKDE9cmVjaXByb2NhbCBzcXVhcmVzLCAyPXRyYXBlem9pZCBydWxlKTogIjsKICAgICAgICBpbnQgbWV0aG9kOwogICAgICAgIHN0ZDo6Y2luID4+IG1ldGhvZDsKICAgICAgICAvLyBCcm9hZGNhc3QgdGhlIG1ldGhvZCB0byBhbGwgcHJvY2Vzc2VzCiAgICAgICAgTVBJX0JjYXN0KCZtZXRob2QsIDEsIE1QSV9JTlQsIDAsIE1QSV9DT01NX1dPUkxEKTsKCiAgICAgICAgc3RkOjpjb3V0IDw8ICJFbnRlciB0aGUgbnVtYmVyIG9mIHRlcm1zIG9yIGludGVydmFsczogIjsKICAgICAgICBpbnQgbnVtOwogICAgICAgIHN0ZDo6Y2luID4+IG51bTsKICAgICAgICAvLyBCcm9hZGNhc3QgdGhlIG51bWJlciBvZiB0ZXJtcyBvciBpbnRlcnZhbHMgdG8gYWxsIHByb2Nlc3NlcwogICAgICAgIE1QSV9CY2FzdCgmbnVtLCAxLCBNUElfSU5ULCAwLCBNUElfQ09NTV9XT1JMRCk7CiAgICB9CgogICAgLy8gQWxsIHByb2Nlc3NlcyByZWNlaXZlIHRoZSBtZXRob2QgYW5kIHRoZSBudW1iZXIgb2YgdGVybXMgb3IgaW50ZXJ2YWxzCiAgICBpbnQgbWV0aG9kLCBudW07CiAgICBNUElfQmNhc3QoJm1ldGhvZCwgMSwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwogICAgTVBJX0JjYXN0KCZudW0sIDEsIE1QSV9JTlQsIDAsIE1QSV9DT01NX1dPUkxEKTsKCiAgICAvLyBEZXBlbmRpbmcgb24gdGhlIG1ldGhvZCwgY29tcHV0ZSB0aGUgbG9jYWwgc3VtCiAgICBkb3VibGUgbG9jYWxfc3VtOwogICAgaWYgKG1ldGhvZCA9PSAxKSB7CiAgICAgICAgbG9jYWxfc3VtID0gY29tcHV0ZV9waV9yZWNpcHJvY2FsX3NxdWFyZXMocmFuaywgc2l6ZSwgbnVtKTsKICAgIH0gZWxzZSBpZiAobWV0aG9kID09IDIpIHsKICAgICAgICBsb2NhbF9zdW0gPSBjb21wdXRlX3BpX3RyYXBlem9pZChyYW5rLCBzaXplLCBudW0pOwogICAgfQoKICAgIC8vIFJlZHVjZSB0aGUgbG9jYWwgc3VtcyB0byBhIGdsb2JhbCBzdW0KICAgIGRvdWJsZSBnbG9iYWxfc3VtOwogICAgTVBJX1JlZHVjZSgmbG9jYWxfc3VtLCAmZ2xvYmFsX3N1bSwgMSwgTVBJX0RPVUJMRSwgTVBJX1NVTSwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIC8vIFByb2Nlc3MgMCBjb21wdXRlcyBhbmQgcHJpbnRzIHRoZSB2YWx1ZSBvZiBQaQogICAgaWYgKHJhbmsgPT0gMCkgewogICAgICAgIGRvdWJsZSBwaTsKICAgICAgICBpZiAobWV0aG9kID09IDEpIHsKICAgICAgICAgICAgcGkgPSBzcXJ0KDYuMCAqIGdsb2JhbF9zdW0pOwogICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09IDIpIHsKICAgICAgICAgICAgcGkgPSBnbG9iYWxfc3VtOwogICAgICAgIH0KICAgICAgICBwcmludGYoIkNvbXB1dGVkIHZhbHVlIG9mIFBpOiAlZlxuIiwgcGkpOwogICAgfQoKICAgIC8vIEZpbmFsaXplIE1QSSBhbmQgZW5kIHRoZSBwcm9ncmFtCiAgICBNUElfRmluYWxpemUoKTsKICAgIHJldHVybiAwOwp9Cgo=