#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
const double a = 0;
const double b = 2000000000;
/* Function declarations */
void Get_input(int argc, char* argv[], int my_rank, double* n_p);
double Trap(double left_endpt, double right_endpt, int trap_count,
double base_len);
double f(double x);
int main(int argc, char** argv) {
int my_rank, comm_sz, local_n;
double n, h, local_a, local_b;
double local_int, total_int;
double start, finish, loc_elapsed, elapsed;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
Get_input(argc, argv, my_rank, &n); /*Read user input */
/*Note: h and local_n are the same for all processes*/
h = (b-a)/n; /* length of each trapezoid */
local_n = n/comm_sz; /* number of trapezoids per process */
/* Length of each process' interval of integration = local_n*h. */
local_a = a + my_rank*local_n*h;
local_b = local_a + local_n*h;
MPI_Barrier(MPI_COMM_WORLD);
start = MPI_Wtime();
/* Calculate each process' local integral using local endpoints*/
local_int = Trap(local_a, local_b, local_n, h);
finish = MPI_Wtime();
loc_elapsed = finish-start;
MPI_Reduce(&loc_elapsed, &elapsed, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
/* Add up the integrals calculated by each process */
MPI_Reduce(&local_int, &total_int, 1, MPI_DOUBLE, MPI_SUM, 0,
MPI_COMM_WORLD);
if (my_rank == 0) {
printf("With n = %.0f trapezoids, our estimate\n", n
); printf("of the integral from %.0f to %.0f = %.0f\n", a, b, total_int);
printf("Elapsed time = %f milliseconds \n", elapsed
* 1000); }
/* Shut down MPI */
MPI_Finalize();
return 0;
} /* main */
/*------------------------------------------------------------------
* Function: Get_input
* Purpose: Get the user input: the number of trapezoids
* Input args: my_rank: process rank in MPI_COMM_WORLD
* comm_sz: number of processes in MPI_COMM_WORLD
* Output args: n_p: pointer to number of trapezoids
*/
void Get_input(int argc, char* argv[], int my_rank, double* n_p){
if (my_rank == 0) {
if (argc!= 2){
fprintf(stderr
, "usage: mpirun -np <N> %s <number of trapezoids> \n", argv
[0]); *n_p = -1;
} else {
}
}
// Broadcasts value of n to each process
MPI_Bcast(n_p, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
// negative n ends the program
if (*n_p <= 0) {
MPI_Finalize();
}
} /* 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, double right_endpt, int trap_count, double base_len) {
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 */
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bXBpLmg+Cgpjb25zdCBkb3VibGUgYSA9IDA7CmNvbnN0IGRvdWJsZSBiID0gMjAwMDAwMDAwMDsKCi8qIEZ1bmN0aW9uIGRlY2xhcmF0aW9ucyAqLwp2b2lkIEdldF9pbnB1dChpbnQgYXJnYywgY2hhciogYXJndltdLCBpbnQgbXlfcmFuaywgZG91YmxlKiBuX3ApOwpkb3VibGUgVHJhcChkb3VibGUgbGVmdF9lbmRwdCwgZG91YmxlIHJpZ2h0X2VuZHB0LCBpbnQgdHJhcF9jb3VudCwKICAgZG91YmxlIGJhc2VfbGVuKTsKZG91YmxlIGYoZG91YmxlIHgpOwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgIGludCBteV9yYW5rLCBjb21tX3N6LCBsb2NhbF9uOwogICBkb3VibGUgbiwgaCwgbG9jYWxfYSwgbG9jYWxfYjsKICAgZG91YmxlIGxvY2FsX2ludCwgdG90YWxfaW50OwogICBkb3VibGUgc3RhcnQsIGZpbmlzaCwgbG9jX2VsYXBzZWQsIGVsYXBzZWQ7CgogICBNUElfSW5pdChOVUxMLCBOVUxMKTsKICAgTVBJX0NvbW1fcmFuayhNUElfQ09NTV9XT1JMRCwgJm15X3JhbmspOwogICBNUElfQ29tbV9zaXplKE1QSV9DT01NX1dPUkxELCAmY29tbV9zeik7CgogICBHZXRfaW5wdXQoYXJnYywgYXJndiwgbXlfcmFuaywgJm4pOyAvKlJlYWQgdXNlciBpbnB1dCAqLwoKICAgLypOb3RlOiBoIGFuZCBsb2NhbF9uIGFyZSB0aGUgc2FtZSBmb3IgYWxsIHByb2Nlc3NlcyovCiAgIGggPSAoYi1hKS9uOyAgICAgICAgICAvKiBsZW5ndGggb2YgZWFjaCB0cmFwZXpvaWQgKi8KICAgbG9jYWxfbiA9IG4vY29tbV9zejsgIC8qIG51bWJlciBvZiB0cmFwZXpvaWRzIHBlciBwcm9jZXNzICovCgogICAvKiBMZW5ndGggb2YgZWFjaCBwcm9jZXNzJyBpbnRlcnZhbCBvZiBpbnRlZ3JhdGlvbiA9IGxvY2FsX24qaC4gKi8KICAgbG9jYWxfYSA9IGEgKyBteV9yYW5rKmxvY2FsX24qaDsKICAgbG9jYWxfYiA9IGxvY2FsX2EgKyBsb2NhbF9uKmg7CgogICBNUElfQmFycmllcihNUElfQ09NTV9XT1JMRCk7CiAgIHN0YXJ0ID0gTVBJX1d0aW1lKCk7CiAgIC8qIENhbGN1bGF0ZSBlYWNoIHByb2Nlc3MnIGxvY2FsIGludGVncmFsIHVzaW5nIGxvY2FsIGVuZHBvaW50cyovCiAgIGxvY2FsX2ludCA9IFRyYXAobG9jYWxfYSwgbG9jYWxfYiwgbG9jYWxfbiwgaCk7CiAgIGZpbmlzaCA9IE1QSV9XdGltZSgpOwogICBsb2NfZWxhcHNlZCA9IGZpbmlzaC1zdGFydDsKICAgTVBJX1JlZHVjZSgmbG9jX2VsYXBzZWQsICZlbGFwc2VkLCAxLCBNUElfRE9VQkxFLCBNUElfTUFYLCAwLCBNUElfQ09NTV9XT1JMRCk7CgogICAvKiBBZGQgdXAgdGhlIGludGVncmFscyBjYWxjdWxhdGVkIGJ5IGVhY2ggcHJvY2VzcyAqLwogICBNUElfUmVkdWNlKCZsb2NhbF9pbnQsICZ0b3RhbF9pbnQsIDEsIE1QSV9ET1VCTEUsIE1QSV9TVU0sIDAsCiAgICAgICAgIE1QSV9DT01NX1dPUkxEKTsKCgogICBpZiAobXlfcmFuayA9PSAwKSB7CiAgICAgIHByaW50ZigiV2l0aCBuID0gJS4wZiB0cmFwZXpvaWRzLCBvdXIgZXN0aW1hdGVcbiIsIG4pOwogICAgICBwcmludGYoIm9mIHRoZSBpbnRlZ3JhbCBmcm9tICUuMGYgdG8gJS4wZiA9ICUuMGZcbiIsCiAgICAgICAgICBhLCBiLCB0b3RhbF9pbnQpOwogICAgICBwcmludGYoIkVsYXBzZWQgdGltZSA9ICVmIG1pbGxpc2Vjb25kcyBcbiIsIGVsYXBzZWQgKiAxMDAwKTsKICAgfQoKICAgLyogU2h1dCBkb3duIE1QSSAqLwogICBNUElfRmluYWxpemUoKTsKCiAgIHJldHVybiAwOwp9IC8qICBtYWluICAqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogRnVuY3Rpb246ICAgICBHZXRfaW5wdXQKICogUHVycG9zZTogICAgICBHZXQgdGhlIHVzZXIgaW5wdXQ6IHRoZSBudW1iZXIgb2YgdHJhcGV6b2lkcwogKiBJbnB1dCBhcmdzOiAgIG15X3Jhbms6ICBwcm9jZXNzIHJhbmsgaW4gTVBJX0NPTU1fV09STEQKICogICAgICAgICAgICAgICBjb21tX3N6OiAgbnVtYmVyIG9mIHByb2Nlc3NlcyBpbiBNUElfQ09NTV9XT1JMRAogKiBPdXRwdXQgYXJnczogIG5fcDogIHBvaW50ZXIgdG8gbnVtYmVyIG9mIHRyYXBlem9pZHMKICovCnZvaWQgR2V0X2lucHV0KGludCBhcmdjLCBjaGFyKiBhcmd2W10sIGludCBteV9yYW5rLCBkb3VibGUqIG5fcCl7CglpZiAobXlfcmFuayA9PSAwKSB7CgkJaWYgKGFyZ2MhPSAyKXsKCQkgICAgZnByaW50ZihzdGRlcnIsICJ1c2FnZTogbXBpcnVuIC1ucCA8Tj4gJXMgPG51bWJlciBvZiB0cmFwZXpvaWRzPiBcbiIsIGFyZ3ZbMF0pOwogICAgICAgICAgICBmZmx1c2goc3RkZXJyKTsKICAgICAgICAgICAgKm5fcCA9IC0xOwoJCX0gZWxzZSB7CgkJCSpuX3AgPSBhdG9pKGFyZ3ZbMV0pOwoJCX0KCX0KCS8vIEJyb2FkY2FzdHMgdmFsdWUgb2YgbiB0byBlYWNoIHByb2Nlc3MKCU1QSV9CY2FzdChuX3AsIDEsIE1QSV9ET1VCTEUsIDAsIE1QSV9DT01NX1dPUkxEKTsKCQoJLy8gbmVnYXRpdmUgbiBlbmRzIHRoZSBwcm9ncmFtCiAgICBpZiAoKm5fcCA8PSAwKSB7CiAgICAgICAgTVBJX0ZpbmFsaXplKCk7CiAgICAgICAgZXhpdCgtMSk7CiAgICB9Cn0gIC8qIEdldF9pbnB1dCAqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogRnVuY3Rpb246ICAgICBUcmFwCiAqIFB1cnBvc2U6ICAgICAgU2VyaWFsIGZ1bmN0aW9uIGZvciBlc3RpbWF0aW5nIGEgZGVmaW5pdGUgaW50ZWdyYWwKICogICAgICAgICAgICAgICB1c2luZyB0aGUgdHJhcGV6b2lkYWwgcnVsZQogKiBJbnB1dCBhcmdzOiAgIGxlZnRfZW5kcHQKICogICAgICAgICAgICAgICByaWdodF9lbmRwdAogKiAgICAgICAgICAgICAgIHRyYXBfY291bnQKICogICAgICAgICAgICAgICBiYXNlX2xlbgogKiBSZXR1cm4gdmFsOiAgIFRyYXBlem9pZGFsIHJ1bGUgZXN0aW1hdGUgb2YgaW50ZWdyYWwgZnJvbQogKiAgICAgICAgICAgICAgIGxlZnRfZW5kcHQgdG8gcmlnaHRfZW5kcHQgdXNpbmcgdHJhcF9jb3VudAogKiAgICAgICAgICAgICAgIHRyYXBlem9pZHMKICovCmRvdWJsZSBUcmFwKGRvdWJsZSBsZWZ0X2VuZHB0LCBkb3VibGUgcmlnaHRfZW5kcHQsIGludCB0cmFwX2NvdW50LCBkb3VibGUgYmFzZV9sZW4pIHsKICAgZG91YmxlIGVzdGltYXRlLCB4OwogICBpbnQgaTsKCiAgIGVzdGltYXRlID0gKGYobGVmdF9lbmRwdCkgKyBmKHJpZ2h0X2VuZHB0KSkvMi4wOwogICBmb3IgKGkgPSAxOyBpIDw9IHRyYXBfY291bnQtMTsgaSsrKSB7CiAgICAgIHggPSBsZWZ0X2VuZHB0ICsgaSpiYXNlX2xlbjsKICAgICAgZXN0aW1hdGUgKz0gZih4KTsKICAgfQogICBlc3RpbWF0ZSA9IGVzdGltYXRlKmJhc2VfbGVuOwoKICAgcmV0dXJuIGVzdGltYXRlOwp9IC8qICBUcmFwICAqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIEZ1bmN0aW9uOiAgICBmCiAqIFB1cnBvc2U6ICAgICBDb21wdXRlIHZhbHVlIG9mIGZ1bmN0aW9uIHRvIGJlIGludGVncmF0ZWQKICogSW5wdXQgYXJnczogIHgKICovCmRvdWJsZSBmKGRvdWJsZSB4KSB7CiAgIHJldHVybiB4Kng7Cn0gLyogZiAqLw==