forked from pyvawtjzl/CCZU
parent
04c1b04c2d
commit
9d803e155f
@ -0,0 +1,148 @@
|
||||
/* File: mpi_trap3.c
|
||||
* Purpose: Use MPI to implement a parallel version of the trapezoidal
|
||||
* rule. This version uses collective communications to
|
||||
* distribute the input data and compute the global sum.
|
||||
*
|
||||
* Input: The endpoints of the interval of integration and the number
|
||||
* of trapezoids
|
||||
* 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_trap2 mpi_trap2.c
|
||||
* Run: mpiexec -n <number of processes> ./mpi_trap2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Notes:
|
||||
* 1. f(x) is all hardwired.
|
||||
* 2. The number of trapezoids should be evenly divisible by
|
||||
* the number of processes.
|
||||
*
|
||||
* IPP2: Section 3.4.2 (pp. 110 and ff.)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
/* We'll be using MPI routines, definitions, etc. */
|
||||
#include <mpi.h>
|
||||
|
||||
/* Get the input values */
|
||||
void Get_input(int my_rank, int comm_sz, double* a_p, double* b_p,
|
||||
int* n_p);
|
||||
|
||||
/* 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);
|
||||
|
||||
int main(void) {
|
||||
int my_rank, comm_sz, n, local_n;
|
||||
double a, b, h, local_a, local_b;
|
||||
double local_int, total_int;
|
||||
|
||||
/* Let the system do what it needs to start up MPI */
|
||||
MPI_Init(NULL, NULL);
|
||||
|
||||
/* Get my process rank */
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
|
||||
|
||||
/* Find out how many processes are being used */
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
|
||||
|
||||
Get_input(my_rank, comm_sz, &a, &b, &n);
|
||||
|
||||
h = (b-a)/n; /* h is the same for all processes */
|
||||
local_n = n/comm_sz; /* So is the number of trapezoids */
|
||||
|
||||
/* Length of each process' interval of
|
||||
* integration = local_n*h. So my interval
|
||||
* starts at: */
|
||||
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);
|
||||
|
||||
/* Add up the integrals calculated by each process */
|
||||
/* 第2处代码补全开始 */
|
||||
|
||||
/* 第2处代码补全结束 */
|
||||
|
||||
/* Print the result */
|
||||
if (my_rank == 0) {
|
||||
printf("%.3f\n", total_int);
|
||||
}
|
||||
|
||||
/* Shut down MPI */
|
||||
MPI_Finalize();
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* Function: Get_input
|
||||
* Purpose: Get the user input: the left and right endpoints
|
||||
* and 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: a_p: pointer to left endpoint
|
||||
* b_p: pointer to right endpoint
|
||||
* n_p: pointer to number of trapezoids
|
||||
*/
|
||||
void Get_input(int my_rank, int comm_sz, double* a_p, double* b_p,
|
||||
int* n_p) {
|
||||
|
||||
if (my_rank == 0) {
|
||||
scanf("%lf %lf %d", a_p, b_p, n_p);
|
||||
}
|
||||
/* 第1处代码补全开始 */
|
||||
/* 使用MPI_Bcast将a_p、b_p、n_p发送给其他进程 */
|
||||
|
||||
/* 第1处代码补全结束 */
|
||||
} /* 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 */
|
Loading…
Reference in new issue