我正在研究一种并行的动态编程问题。我对MPI的一个奇怪的问题是,当我并行使用2个以上的处理器时,会出现错误。
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
当我使用2个处理器时,代码可以在结果中运行时遇到一些问题(我将在可以复制问题的代码之后指定)。这是一个编译器列表,操作系统信息:
OS: Linux Ubuntu 14.04
Fortran compiler: gfortran 4.8.4 + OpenMPI(mpif90) 1.10.0
简化代码:main:
PROGRAM main
USE UPDATE_VFUN
IMPLICIT NONE
INTEGER, PARAMETER :: nz=2,nb=2,nk=2,nxi=2,nnb=2,nnk=2,nnb_b=2,nnk_b=2,itmax=4
INTEGER:: myid, extra,numprocs,chunksize,indtop,indbot
INTEGER,PARAMETER:: N=2*nb*nk*nxi*nz*nz
REAL(8):: vc_ub(N), vc_b(N),vx(N),dist
CALL MPI_INIT(ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr)
chunksize=int(real(N)/real(numprocs))
extra=N-chunksize*numprocs
IF (myid<extra) THEN
indtop=myid*(chunksize+1)+1
indbot=(myid+1)*(chunksize+1)
ELSE
indtop=extra*(chunksize+1)+(myid-extra)*chunksize+1
indbot=extra*(chunksize+1)+(myid-extra+1)*chunksize
END IF
DO i=1,itmax
IF (dist>stp_rule) THEN
CALL vupdate(vc_ub,vc_b,vx,dist,indtop,indbot)
PRINT *, "Current Iteration", i, "in thread", myid
PRINT *, "DISTANCE",dist
ELSE
EXIT
END IF
END DO
CALL MPI_FINALIZE(ierr)
END PROGRAM main
外部MODULE UPDATE_VFUN:
MODULE UPDATE_VFUN
USE MPI
IMPLICIT NONE
CONTAINS
SUBROUTINE vupdate(vc_ub,vc_b,vx,dist,indtop,indbot)
REAL(8), INTENT(INOUT):: vc_ub(:), vc_b(:), vx(:)
INTEGER, INTENT(IN) :: indtop,indbot
REAL(8), INTENT(OUT) :: dist
INTEGER :: mychunk,N
REAL(8) :: vc_ub_temp(size(vc_ub)),vc_b_temp(size(vc_b)),&
vx_temp(size(vx))
REAL(8),DIMENSION(indbot-indtop+1) :: myvc_ub,myvc_b,myvx
N=size(vc_ub)
mychunk=indbot-indtop+1
myvc_ub=1.0d3
myvc_b=1.2d4
myvx=1.2d2
CALL MPI_ALLGATHER(myvc_ub,mychunk,MPI_REAL,vc_ub_temp,N,MPI_REAL,&
MPI_COMM_WORLD,ierr)
CALL MPI_ALLGATHER(myvc_b,mychunk,MPI_REAL,vc_b_temp,N,MPI_REAL,&
MPI_COMM_WORLD,ierr)
CALL MPI_ALLGATHER(myvx,mychunk,MPI_REAL,vx_temp,N,MPI_REAL,&
MPI_COMM_WORLD,ierr)
!Calculate distance
dist=max(maxval(abs(vc_ub-vc_ub_temp)),maxval(abs(vc_b- &
vc_b_temp)),maxval(abs(vx-vx_temp)))
!Updating
vc_ub=vc_ub_temp
vc_b=vc_b_temp
vx=vx_temp
END SUBROUTINE vupdate
END MODULE UPDATE_VFUN
如果我指定
mpirun -np 4
在makefile中,发生上述错误。如果我指定-np 2
,则程序可以运行。但是在打印输出中:
vc_ub vc_b vx
[1] 1000 12000 120
[2] 1000 12000 120
... ... ...
[16] 1000 12000 120
[17] machine zero machine zero machine zero
... ... ...
[32] machine zero machine zero machine zero
SAME PATTERN FOR 33-48, AND 49-64.
计算机似乎需要chunksize=16
,好像有4个处理器。但是-np 2
,那不应该是32吗?
总结一下,我的两个问题是:
(1)为什么在这种情况下,-np 4
无效,而-np 2
可以?
(2)为什么-np 2
会产生如此愚蠢的结果?
非常感谢您的想法和评论!