|
program main
implicit none
include 'mpif.h'
integer totalsize,mysize,steps
parameter (totalsize=16)
parameter (mysize=totalsize/4,steps=10)
integer n, myid, numprocs, i, j,rc
real a(totalsize,mysize+2),b(totalsize,mysize+2)
integer begin_col,end_col,ierr
integer left,right,tag1,tag2
integer status(MPI_STATUS_SIZE,4)
integer req(4)
call MPI_INIT( ierr )
call MPI_COMM_RANK( MPI_COMM_WORLD, myid, ierr )
call MPI_COMM_SIZE( MPI_COMM_WORLD, numprocs, ierr )
print *, "Process ", myid, " of ", numprocs,
" is alive"
C 数组初始化
do j=1,mysize+2
do i=1,totalsize
a(i,j)=0.0
end do
end do
do i=1,totalsize
a(i,1)=8.0
a(i,mysize+2)=8.0
end do
C 边界元素赋初值
if (myid .eq. 0) then
do i=1,totalsize
a(i,2)=8.0
end do
end if
if (myid .eq. 3) then
do i=1,totalsize
a(i,mysize+1)=8.0
end do
end if
do i=1,mysize+2
a(1,i)=8.0
a(totalsize,i)=8.0
end do
tag1=3
tag2=4
C 设置当前进程左右两侧的进程
if (myid .gt. 0) then
left=myid-1
else
left=MPI_PROC_NULL
end if
if (myid .lt. 3) then
right=myid+1
else
right=MPI_PROC_NULL
end if
C 设置迭代的开始和终止列
begin_col=2
end_col=mysize+1
if (myid .eq. 0) then
begin_col=3
endif
if (myid .eq. 3) then
end_col=mysize
endif
C 初始化重复非阻塞通信
call MPI_SEND_INIT(b(1,end_col),totalsize,MPI_REAL,right,tag1,
*MPI_COMM_WORLD,req(1),ierr)
call MPI_SEND_INIT(b(1,begin_col),totalsize,MPI_REAL,left,tag2,
*MPI_COMM_WORLD,req(2),ierr)
call MPI_RECV_INIT(a(1,1),totalsize,MPI_REAL,left,tag1,
* MPI_COMM_WORLD,req(3),ierr)
call MPI_RECV_INIT(a(1,mysize+2),totalsize,MPI_REAL,right,tag2,
* MPI_COMM_WORLD,req(4),ierr)
C 执行迭代
do n=1,steps
C 先计算需要通信的部分
do i=2,totalsize-1
b(i,begin_col)=(a(i,begin_col+1)+a(i,begin_col-1)+
* a(i+1,begin_col)+a(i-1,begin_col))*0.25
b(i,end_col)=(a(i,end_col+1)+a(i,end_col-1)+
*a(i+1,end_col)+a(i-1,end_col))*0.25
end do
C 激活非阻塞通信对象,启动4个非阻塞通信
call MPI_STARTALL(4,req,ierr)
C 计算剩余的迭代部分
do j=begin_col+1,end_col-1
do i=2,totalsize-1
b(i,j)=(a(i,j+1)+a(i,j-1)+a(i+1,j)+a(i-1,j))*0.25
end do
end do
do j=begin_col,end_col
do i=2,totalsize-1
a(i,j)=b(i,j)
end do
end do
C 完成非阻塞通信,非阻塞通信对象变为非活动态
call MPI_WAITALL(4,req,status,ierr)
end do
do i=2,totalsize-1
print *, myid,(a(i,j),j=begin_col,end_col)
end do
C 释放非阻塞通信对象
do i=1,4
CALL MPI_REQUEST_FREE(req(i),ierr)
end do
call MPI_FINALIZE(rc)
end
|