/* File: mpi_trap1.c
* Purpose: Use MPI to implement a parallel version of the trapezoidal
* rule. In this version the endpoints of the interval and
* the number of trapezoids are hardwired.
*
* Input: None.
* Output: Estimate of the integral from a to b of f(x)
* using the trapezoidal rule and n trapezoids.
*
* Compile: mpicc -g -Wall -o mpi_trap1 mpi_trap1.c
* Run: mpiexec -n <number of processes> ./mpi_trap1
*
* Algorithm:
* 1. Each process calculates "its" interval of
* integration.
* 2. Each process estimates the integral of f(x)
* over its interval using the trapezoidal rule.
* 3a. Each process != 0 sends its integral to 0.
* 3b. Process 0 sums the calculations received from
* the individual processes and prints the result.
*
* Note: f(x), a, b, and n are all hardwired.
*
* IPP: Section 3.2.2 (pp. 96 and ff.)
*/
#include <stdio.h>
/* We'll be using MPI routines, definitions, etc. */
#include <mpi.h>
/* Calculate local integral */
double Trap(double left_endpt, double right_endpt, int trap_count,
double base_len);
/* Function we're integrating */
double f(double x);
void bcs211002(int my_rank, int comm_sz, double* a, double* b,
int* n);
int main(void) {
int my_rank, comm_sz, n, local_n;
double a, b, h, local_a, local_b;
double local_int, total_int;
int source;
/* Initialize MPI */
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
/* Get input values */
bcs211002(my_rank, comm_sz, &a, &b, &n);
h = (b - a) / n; /* Width of trapezoids */
local_n = n / comm_sz; /* Number of trapezoids for each process */
/* Calculate local interval */
local_a = a + my_rank * local_n * h;
local_b = local_a + local_n * h;
local_int = Trap(local_a, local_b, local_n, h);
/* Collect and print results */
if (my_rank != 0) {
MPI_Send(&local_int, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
} else {
total_int = local_int;
printf("The trapezoid area calculated by Process %d of %d is %.15e\n", my_rank
, comm_sz
, local_int
);
for (source = 1; source < comm_sz; source++) {
MPI_Recv(&local_int, 1, MPI_DOUBLE, source, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("The trapezoid area received by Process %d of %d is %.15e\n", source
, comm_sz
, local_int
); total_int += local_int;
}
printf("With n = %d trapezoids, our estimate\n", n
); printf("of the integral from %f to %f = %.15e\n", a
, b
, total_int
); }
/* Finalize MPI */
MPI_Finalize();
return 0;
}
/* main */
void bcs211002(int my_rank, int comm_sz, double* a, double* b,
int* n) {
int dest;
if (my_rank == 0) {
printf("Enter the value of a(starting value):\n"); printf("Enter the value of b (ending value):\n"); printf("Enter the value of n(no of trapezoids):\n");
for (dest = 1; dest < comm_sz; dest++) {
MPI_Send(a, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
MPI_Send(b, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
MPI_Send(n, 1, MPI_INT, dest, 0, MPI_COMM_WORLD);
}
} else { /* my_rank != 0 */
MPI_Recv(a, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
MPI_Recv(b, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
MPI_Recv(n, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
}
} /* Get_input */
/*------------------------------------------------------------------
* Function: Trap
* Purpose: Serial function for estimating a definite integral
* using the trapezoidal rule
* Input args: left_endpt
* right_endpt
* trap_count
* base_len
* Return val: Trapezoidal rule estimate of integral from
* left_endpt to right_endpt using trap_count
* trapezoids
*/
double Trap(
double left_endpt /* in */,
double right_endpt /* in */,
int trap_count /* in */,
double base_len /* in */) {
double estimate, x;
int i;
estimate = (f(left_endpt) + f(right_endpt))/2.0;
for (i = 1; i <= trap_count-1; i++) {
x = left_endpt + i*base_len;
estimate += f(x);
}
estimate = estimate*base_len;
return estimate;
} /* Trap */
/*------------------------------------------------------------------
* Function: f
* Purpose: Compute value of function to be integrated
* Input args: x
*/
double f(double x) {
return x*x;
} /* f */
LyogRmlsZTogICAgIG1waV90cmFwMS5jCiAqIFB1cnBvc2U6ICBVc2UgTVBJIHRvIGltcGxlbWVudCBhIHBhcmFsbGVsIHZlcnNpb24gb2YgdGhlIHRyYXBlem9pZGFsIAogKiAgICAgICAgICAgcnVsZS4gIEluIHRoaXMgdmVyc2lvbiB0aGUgZW5kcG9pbnRzIG9mIHRoZSBpbnRlcnZhbCBhbmQKICogICAgICAgICAgIHRoZSBudW1iZXIgb2YgdHJhcGV6b2lkcyBhcmUgaGFyZHdpcmVkLgogKgogKiBJbnB1dDogICAgTm9uZS4KICogT3V0cHV0OiAgIEVzdGltYXRlIG9mIHRoZSBpbnRlZ3JhbCBmcm9tIGEgdG8gYiBvZiBmKHgpCiAqICAgICAgICAgICB1c2luZyB0aGUgdHJhcGV6b2lkYWwgcnVsZSBhbmQgbiB0cmFwZXpvaWRzLgogKgogKiBDb21waWxlOiAgbXBpY2MgLWcgLVdhbGwgLW8gbXBpX3RyYXAxIG1waV90cmFwMS5jCiAqIFJ1bjogICAgICBtcGlleGVjIC1uIDxudW1iZXIgb2YgcHJvY2Vzc2VzPiAuL21waV90cmFwMQogKgogKiBBbGdvcml0aG06CiAqICAgIDEuICBFYWNoIHByb2Nlc3MgY2FsY3VsYXRlcyAiaXRzIiBpbnRlcnZhbCBvZgogKiAgICAgICAgaW50ZWdyYXRpb24uCiAqICAgIDIuICBFYWNoIHByb2Nlc3MgZXN0aW1hdGVzIHRoZSBpbnRlZ3JhbCBvZiBmKHgpCiAqICAgICAgICBvdmVyIGl0cyBpbnRlcnZhbCB1c2luZyB0aGUgdHJhcGV6b2lkYWwgcnVsZS4KICogICAgM2EuIEVhY2ggcHJvY2VzcyAhPSAwIHNlbmRzIGl0cyBpbnRlZ3JhbCB0byAwLgogKiAgICAzYi4gUHJvY2VzcyAwIHN1bXMgdGhlIGNhbGN1bGF0aW9ucyByZWNlaXZlZCBmcm9tCiAqICAgICAgICB0aGUgaW5kaXZpZHVhbCBwcm9jZXNzZXMgYW5kIHByaW50cyB0aGUgcmVzdWx0LgogKgogKiBOb3RlOiAgZih4KSwgYSwgYiwgYW5kIG4gYXJlIGFsbCBoYXJkd2lyZWQuCiAqCiAqIElQUDogICBTZWN0aW9uIDMuMi4yIChwcC4gOTYgYW5kIGZmLikKICovCiNpbmNsdWRlIDxzdGRpby5oPgoKLyogV2UnbGwgYmUgdXNpbmcgTVBJIHJvdXRpbmVzLCBkZWZpbml0aW9ucywgZXRjLiAqLwojaW5jbHVkZSA8bXBpLmg+CgovKiBDYWxjdWxhdGUgbG9jYWwgaW50ZWdyYWwgICovCmRvdWJsZSBUcmFwKGRvdWJsZSBsZWZ0X2VuZHB0LCBkb3VibGUgcmlnaHRfZW5kcHQsIGludCB0cmFwX2NvdW50LCAKICAgZG91YmxlIGJhc2VfbGVuKTsgICAgCgovKiBGdW5jdGlvbiB3ZSdyZSBpbnRlZ3JhdGluZyAqLwpkb3VibGUgZihkb3VibGUgeCk7IAoKdm9pZCBiY3MyMTEwMDIoaW50IG15X3JhbmssIGludCBjb21tX3N6LCBkb3VibGUqIGEsIGRvdWJsZSogYiwKICAgICAgaW50KiBuKTsKCmludCBtYWluKHZvaWQpIHsKICAgaW50IG15X3JhbmssIGNvbW1fc3osIG4sIGxvY2FsX247CiAgIGRvdWJsZSBhLCBiLCBoLCBsb2NhbF9hLCBsb2NhbF9iOwogICBkb3VibGUgbG9jYWxfaW50LCB0b3RhbF9pbnQ7CiAgIGludCBzb3VyY2U7CgogICAvKiBJbml0aWFsaXplIE1QSSAqLwogICBNUElfSW5pdChOVUxMLCBOVUxMKTsKICAgTVBJX0NvbW1fcmFuayhNUElfQ09NTV9XT1JMRCwgJm15X3JhbmspOwogICBNUElfQ29tbV9zaXplKE1QSV9DT01NX1dPUkxELCAmY29tbV9zeik7CgogICAvKiBHZXQgaW5wdXQgdmFsdWVzICovCiAgIGJjczIxMTAwMihteV9yYW5rLCBjb21tX3N6LCAmYSwgJmIsICZuKTsKCiAgIGggPSAoYiAtIGEpIC8gbjsgICAgICAgICAgIC8qIFdpZHRoIG9mIHRyYXBlem9pZHMgKi8KICAgbG9jYWxfbiA9IG4gLyBjb21tX3N6OyAgICAgLyogTnVtYmVyIG9mIHRyYXBlem9pZHMgZm9yIGVhY2ggcHJvY2VzcyAqLwoKICAgLyogQ2FsY3VsYXRlIGxvY2FsIGludGVydmFsICovCiAgIGxvY2FsX2EgPSBhICsgbXlfcmFuayAqIGxvY2FsX24gKiBoOwogICBsb2NhbF9iID0gbG9jYWxfYSArIGxvY2FsX24gKiBoOwogICBsb2NhbF9pbnQgPSBUcmFwKGxvY2FsX2EsIGxvY2FsX2IsIGxvY2FsX24sIGgpOwoKICAgLyogQ29sbGVjdCBhbmQgcHJpbnQgcmVzdWx0cyAqLwogICBpZiAobXlfcmFuayAhPSAwKSB7CiAgICAgIE1QSV9TZW5kKCZsb2NhbF9pbnQsIDEsIE1QSV9ET1VCTEUsIDAsIDAsIE1QSV9DT01NX1dPUkxEKTsKICAgfSBlbHNlIHsKICAgICAgdG90YWxfaW50ID0gbG9jYWxfaW50OwogICAgICBwcmludGYoIlRoZSB0cmFwZXpvaWQgYXJlYSBjYWxjdWxhdGVkIGJ5IFByb2Nlc3MgJWQgb2YgJWQgaXMgJS4xNWVcbiIsIG15X3JhbmssIGNvbW1fc3osIGxvY2FsX2ludCk7CgogICAgICBmb3IgKHNvdXJjZSA9IDE7IHNvdXJjZSA8IGNvbW1fc3o7IHNvdXJjZSsrKSB7CiAgICAgICAgIE1QSV9SZWN2KCZsb2NhbF9pbnQsIDEsIE1QSV9ET1VCTEUsIHNvdXJjZSwgMCwgTVBJX0NPTU1fV09STEQsIE1QSV9TVEFUVVNfSUdOT1JFKTsKICAgICAgICAgcHJpbnRmKCJUaGUgdHJhcGV6b2lkIGFyZWEgcmVjZWl2ZWQgYnkgUHJvY2VzcyAlZCBvZiAlZCBpcyAlLjE1ZVxuIiwgc291cmNlLCBjb21tX3N6LCBsb2NhbF9pbnQpOwogICAgICAgICB0b3RhbF9pbnQgKz0gbG9jYWxfaW50OwogICAgICB9CgogICAgICBwcmludGYoIldpdGggbiA9ICVkIHRyYXBlem9pZHMsIG91ciBlc3RpbWF0ZVxuIiwgbik7CiAgICAgIHByaW50Zigib2YgdGhlIGludGVncmFsIGZyb20gJWYgdG8gJWYgPSAlLjE1ZVxuIiwgYSwgYiwgdG90YWxfaW50KTsKICAgfQoKICAgLyogRmluYWxpemUgTVBJICovCiAgIE1QSV9GaW5hbGl6ZSgpOwoKICAgcmV0dXJuIDA7Cn0KIC8qICBtYWluICAqLwoKIAp2b2lkIGJjczIxMTAwMihpbnQgbXlfcmFuaywgaW50IGNvbW1fc3osIGRvdWJsZSogYSwgZG91YmxlKiBiLAogICAgICBpbnQqIG4pIHsKICAgaW50IGRlc3Q7CgogICBpZiAobXlfcmFuayA9PSAwKSB7CgogICAgICAgICAgICAgICAgcHJpbnRmKCJFbnRlciB0aGUgdmFsdWUgb2YgYShzdGFydGluZyB2YWx1ZSk6XG4iKTsKCQlzY2FuZigiJWxmIiwgYSk7CgkJcHJpbnRmKCJFbnRlciB0aGUgdmFsdWUgb2YgYiAoZW5kaW5nIHZhbHVlKTpcbiIpOwoJCXNjYW5mKCIlbGYiLCBiKTsKCQlwcmludGYoIkVudGVyIHRoZSB2YWx1ZSBvZiBuKG5vIG9mIHRyYXBlem9pZHMpOlxuIik7CgkJc2NhbmYoIiVkIiwgbik7CgogICAgICBmb3IgKGRlc3QgPSAxOyBkZXN0IDwgY29tbV9zejsgZGVzdCsrKSB7CiAgICAgICAgIE1QSV9TZW5kKGEsIDEsIE1QSV9ET1VCTEUsIGRlc3QsIDAsIE1QSV9DT01NX1dPUkxEKTsKICAgICAgICAgTVBJX1NlbmQoYiwgMSwgTVBJX0RPVUJMRSwgZGVzdCwgMCwgTVBJX0NPTU1fV09STEQpOwogICAgICAgICBNUElfU2VuZChuLCAxLCBNUElfSU5ULCBkZXN0LCAwLCBNUElfQ09NTV9XT1JMRCk7CiAgICAgIH0gCiAgIH0gZWxzZSB7IC8qIG15X3JhbmsgIT0gMCAqLwogICAgICBNUElfUmVjdihhLCAxLCBNUElfRE9VQkxFLCAwLCAwLCBNUElfQ09NTV9XT1JMRCwKICAgICAgICAgICAgTVBJX1NUQVRVU19JR05PUkUpOwogICAgICBNUElfUmVjdihiLCAxLCBNUElfRE9VQkxFLCAwLCAwLCBNUElfQ09NTV9XT1JMRCwKICAgICAgICAgICAgTVBJX1NUQVRVU19JR05PUkUpOwogICAgICBNUElfUmVjdihuLCAxLCBNUElfSU5ULCAwLCAwLCBNUElfQ09NTV9XT1JMRCwKICAgICAgICAgICAgTVBJX1NUQVRVU19JR05PUkUpOwogICB9IAp9ICAvKiBHZXRfaW5wdXQgKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIEZ1bmN0aW9uOiAgICAgVHJhcAogKiBQdXJwb3NlOiAgICAgIFNlcmlhbCBmdW5jdGlvbiBmb3IgZXN0aW1hdGluZyBhIGRlZmluaXRlIGludGVncmFsIAogKiAgICAgICAgICAgICAgIHVzaW5nIHRoZSB0cmFwZXpvaWRhbCBydWxlCiAqIElucHV0IGFyZ3M6ICAgbGVmdF9lbmRwdAogKiAgICAgICAgICAgICAgIHJpZ2h0X2VuZHB0CiAqICAgICAgICAgICAgICAgdHJhcF9jb3VudCAKICogICAgICAgICAgICAgICBiYXNlX2xlbgogKiBSZXR1cm4gdmFsOiAgIFRyYXBlem9pZGFsIHJ1bGUgZXN0aW1hdGUgb2YgaW50ZWdyYWwgZnJvbQogKiAgICAgICAgICAgICAgIGxlZnRfZW5kcHQgdG8gcmlnaHRfZW5kcHQgdXNpbmcgdHJhcF9jb3VudAogKiAgICAgICAgICAgICAgIHRyYXBlem9pZHMKICovCmRvdWJsZSBUcmFwKAogICAgICBkb3VibGUgbGVmdF9lbmRwdCAgLyogaW4gKi8sIAogICAgICBkb3VibGUgcmlnaHRfZW5kcHQgLyogaW4gKi8sIAogICAgICBpbnQgICAgdHJhcF9jb3VudCAgLyogaW4gKi8sIAogICAgICBkb3VibGUgYmFzZV9sZW4gICAgLyogaW4gKi8pIHsKICAgZG91YmxlIGVzdGltYXRlLCB4OyAKICAgaW50IGk7CgogICBlc3RpbWF0ZSA9IChmKGxlZnRfZW5kcHQpICsgZihyaWdodF9lbmRwdCkpLzIuMDsKICAgZm9yIChpID0gMTsgaSA8PSB0cmFwX2NvdW50LTE7IGkrKykgewogICAgICB4ID0gbGVmdF9lbmRwdCArIGkqYmFzZV9sZW47CiAgICAgIGVzdGltYXRlICs9IGYoeCk7CiAgIH0KICAgZXN0aW1hdGUgPSBlc3RpbWF0ZSpiYXNlX2xlbjsKCiAgIHJldHVybiBlc3RpbWF0ZTsKfSAvKiAgVHJhcCAgKi8KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBGdW5jdGlvbjogICAgZgogKiBQdXJwb3NlOiAgICAgQ29tcHV0ZSB2YWx1ZSBvZiBmdW5jdGlvbiB0byBiZSBpbnRlZ3JhdGVkCiAqIElucHV0IGFyZ3M6ICB4CiAqLwpkb3VibGUgZihkb3VibGUgeCkgewogICByZXR1cm4geCp4Owp9IC8qIGYgKi8K