fork download
  1. /* File: mpi_trap1.c
  2.  * Purpose: Use MPI to implement a parallel version of the trapezoidal
  3.  * rule. In this version the endpoints of the interval and
  4.  * the number of trapezoids are hardwired.
  5.  *
  6.  * Input: None.
  7.  * Output: Estimate of the integral from a to b of f(x)
  8.  * using the trapezoidal rule and n trapezoids.
  9.  *
  10.  * Compile: mpicc -g -Wall -o mpi_trap1 mpi_trap1.c
  11.  * Run: mpiexec -n <number of processes> ./mpi_trap1
  12.  *
  13.  * Algorithm:
  14.  * 1. Each process calculates "its" interval of
  15.  * integration.
  16.  * 2. Each process estimates the integral of f(x)
  17.  * over its interval using the trapezoidal rule.
  18.  * 3a. Each process != 0 sends its integral to 0.
  19.  * 3b. Process 0 sums the calculations received from
  20.  * the individual processes and prints the result.
  21.  *
  22.  * Note: f(x), a, b, and n are all hardwired.
  23.  *
  24.  * IPP: Section 3.2.2 (pp. 96 and ff.)
  25.  */
  26. #include <stdio.h>
  27.  
  28. /* We'll be using MPI routines, definitions, etc. */
  29. #include <mpi.h>
  30.  
  31. /* Calculate local integral */
  32. double Trap(double left_endpt, double right_endpt, int trap_count,
  33. double base_len);
  34.  
  35. /* Function we're integrating */
  36. double f(double x);
  37.  
  38. void bcs211002(int my_rank, int comm_sz, double* a, double* b,
  39. int* n);
  40.  
  41. int main(void) {
  42. int my_rank, comm_sz, n, local_n;
  43. double a, b, h, local_a, local_b;
  44. double local_int, total_int;
  45. int source;
  46.  
  47. /* Initialize MPI */
  48. MPI_Init(NULL, NULL);
  49. MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  50. MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
  51.  
  52. /* Get input values */
  53. bcs211002(my_rank, comm_sz, &a, &b, &n);
  54.  
  55. h = (b - a) / n; /* Width of trapezoids */
  56. local_n = n / comm_sz; /* Number of trapezoids for each process */
  57.  
  58. /* Calculate local interval */
  59. local_a = a + my_rank * local_n * h;
  60. local_b = local_a + local_n * h;
  61. local_int = Trap(local_a, local_b, local_n, h);
  62.  
  63. /* Collect and print results */
  64. if (my_rank != 0) {
  65. MPI_Send(&local_int, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
  66. } else {
  67. total_int = local_int;
  68. printf("The trapezoid area calculated by Process %d of %d is %.15e\n", my_rank, comm_sz, local_int);
  69.  
  70. for (source = 1; source < comm_sz; source++) {
  71. MPI_Recv(&local_int, 1, MPI_DOUBLE, source, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  72. printf("The trapezoid area received by Process %d of %d is %.15e\n", source, comm_sz, local_int);
  73. total_int += local_int;
  74. }
  75.  
  76. printf("With n = %d trapezoids, our estimate\n", n);
  77. printf("of the integral from %f to %f = %.15e\n", a, b, total_int);
  78. }
  79.  
  80. /* Finalize MPI */
  81. MPI_Finalize();
  82.  
  83. return 0;
  84. }
  85. /* main */
  86.  
  87.  
  88. void bcs211002(int my_rank, int comm_sz, double* a, double* b,
  89. int* n) {
  90. int dest;
  91.  
  92. if (my_rank == 0) {
  93.  
  94. printf("Enter the value of a(starting value):\n");
  95. scanf("%lf", a);
  96. printf("Enter the value of b (ending value):\n");
  97. scanf("%lf", b);
  98. printf("Enter the value of n(no of trapezoids):\n");
  99. scanf("%d", n);
  100.  
  101. for (dest = 1; dest < comm_sz; dest++) {
  102. MPI_Send(a, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
  103. MPI_Send(b, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
  104. MPI_Send(n, 1, MPI_INT, dest, 0, MPI_COMM_WORLD);
  105. }
  106. } else { /* my_rank != 0 */
  107. MPI_Recv(a, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD,
  108. MPI_STATUS_IGNORE);
  109. MPI_Recv(b, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD,
  110. MPI_STATUS_IGNORE);
  111. MPI_Recv(n, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
  112. MPI_STATUS_IGNORE);
  113. }
  114. } /* Get_input */
  115.  
  116. /*------------------------------------------------------------------
  117.  * Function: Trap
  118.  * Purpose: Serial function for estimating a definite integral
  119.  * using the trapezoidal rule
  120.  * Input args: left_endpt
  121.  * right_endpt
  122.  * trap_count
  123.  * base_len
  124.  * Return val: Trapezoidal rule estimate of integral from
  125.  * left_endpt to right_endpt using trap_count
  126.  * trapezoids
  127.  */
  128. double Trap(
  129. double left_endpt /* in */,
  130. double right_endpt /* in */,
  131. int trap_count /* in */,
  132. double base_len /* in */) {
  133. double estimate, x;
  134. int i;
  135.  
  136. estimate = (f(left_endpt) + f(right_endpt))/2.0;
  137. for (i = 1; i <= trap_count-1; i++) {
  138. x = left_endpt + i*base_len;
  139. estimate += f(x);
  140. }
  141. estimate = estimate*base_len;
  142.  
  143. return estimate;
  144. } /* Trap */
  145.  
  146.  
  147. /*------------------------------------------------------------------
  148.  * Function: f
  149.  * Purpose: Compute value of function to be integrated
  150.  * Input args: x
  151.  */
  152. double f(double x) {
  153. return x*x;
  154. } /* f */
  155.  
Success #stdin #stdout #stderr 0.24s 40840KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected '/' in "/"
Execution halted