MPI 梯形积分法(Fortran)
使用MPI分布式接口,Fortran语言实现,梯形积分法实现计算函数积分,下面的代码中示例函数是
y=x^2
,可以在
f(x)
中修改成其他函数。
program main
use mpi
implicit none
! MPI 相关变量
integer :: rank, size, ierr, stat(MPI_STATUS_SIZE), i
! 运算相关变量
real :: a, b, h, local_a, local_b, local_n, local_total, total
integer :: n
! 计算运算时间相关变量
real(8) :: start_time, finish_time
real :: local_elapsed, elapsed
! 函数声明
real, external :: trap
! 初始化
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
! 获取输入
call get_input(rank, size, stat, ierr, a, b, n)
! 同步各进程,各进程开始计时
call MPI_BARRIER(MPI_COMM_WORLD, ierr)
start_time = MPI_WTIME()
! 各进程计算
h = (b - a) / n
local_n = n / size
local_a = a + rank*local_n*h
local_b = local_a + local_n*h
local_total = trap(local_a, local_b, local_n, h)
! 求和并发送到0号进程
call MPI_REDUCE(local_total, total, 1, MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
! 计算最长运行时间
finish_time = MPI_WTIME()
local_elapsed = finish_time - start_time
call MPI_REDUCE(local_elapsed, elapsed, 1, MPI_REAL, MPI_MAX, 0, MPI_COMM_WORLD, ierr)
! 打印结果
if (rank == 0) then
print *, "area:", total, " elapsed:", elapsed
endif
! 结束
call MPI_FINALIZE(ierr)
end program main
! 串行梯形积分法
real function trap(a, b, n, h)
implicit none
real :: a, b, n, h
real :: total
real, external :: f
integer :: i
! area = h[f(a)/2+f(a+h)+f(a+2h)+...+f(a+(n-1)h)+f(b)/2]
total = (f(a) + f(b)) / 2
do i = 1, n-1
total = total + f(a+i*h)
enddo
trap = h * total
return
end function trap
! 计算函数值
real function f(x)
implicit none
real :: x
real, intrinsic :: sin, cos
! y = x^2
f = x**2
return
end function f
! 获取键盘输入
subroutine get_input(rank, size, stat, ierr, a, b, n)
use mpi
implicit none
integer :: rank, size, stat, ierr, n, i
real :: a, b
if (rank == 0) then
print *, "Please input the a,b,n: "
read(*, *) a, b, n
endif
! 数据广播
call MPI_BCAST(a, 1, MPI_REAL, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(b, 1, MPI_REAL, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
end subroutine get_input