Multithreading 当4处理器计算机上有2个以上的线程时,Fortran MPI会失败
我正在研究一个并行动态编程问题。我对MPI的奇怪问题是,当我并行使用两个以上的处理器时,会出现错误Multithreading 当4处理器计算机上有2个以上的线程时,Fortran MPI会失败,multithreading,ubuntu,fortran,mpi,openmpi,Multithreading,Ubuntu,Fortran,Mpi,Openmpi,我正在研究一个并行动态编程问题。我对MPI的奇怪问题是,当我并行使用两个以上的处理器时,会出现错误 Program received signal SIGSEGV: Segmentation fault - invalid memory reference. 当我使用2个处理器时,代码运行时可能会出现一些结果问题(我将在代码后面指定可以复制问题的代码)。以下是编译器列表,操作系统信息: OS: Linux Ubuntu 14.04 Fortran compiler: gfortran 4.8
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
如果我指定
mpirun -np 4
在makefile中,会发生上述错误。如果我指定-np2
,程序可以运行。但在打印输出中:
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个处理器一样。但是对于-np2
,这不是应该是32吗
总而言之,我的两个问题是:
(1) 为什么在这种情况下,-np4
不能工作,而-np2
可以工作?
(2) 为什么-np2
会产生如此愚蠢的结果
非常感谢您的想法和评论 我们怀念gfortran和openmpi版本。模块中N的值是多少,因为它不是共享的,是吗?最后,应用程序是否生成核心?当使用where命令时,gdb sy会做什么?谢谢你的评论,@redcrash。我现在在问题中添加了版本号。关于
N
你是对的,它在另一个GLOBVAR模块中,我在这里抽象了它。我将相应地修改代码。关于你的最后两个问题,我不确定我是否理解……你能更具体一点吗?谢谢您的输出与程序中的任何IO都不匹配?您的allgathers肯定是错误的,请参阅:“请注意,根目录下的recvcount参数表示它从每个进程接收的项目数,而不是它接收的项目总数。”此外,请注意,在分发remainde时,您不能使用MPI_AllGathere,而应使用MPI_allgatherV,尽管在extra=0的示例中,这并不重要。为了计算额外的元素,我会避免使用实数,并坚持使用模和整数除法。到目前为止,我还没有试图理解代码,但是由于您对您的类型使用real(8)
(顺便说一句,这是一个坏主意),因此您(很可能)需要使用MPI\u DOUBLE\u PRECISION
而不是MPI\u real
。先试试这个。什么是extra
初始化为?我们错过了gfortran和openmpi版本。模块中N的值是多少,因为它不是共享的,是吗?最后,应用程序是否生成核心?当使用where命令时,gdb sy会做什么?谢谢你的评论,@redcrash。我现在在问题中添加了版本号。关于N
你是对的,它在另一个GLOBVAR模块中,我在这里抽象了它。我将相应地修改代码。关于你的最后两个问题,我不确定我是否理解……你能更具体一点吗?谢谢您的输出与程序中的任何IO都不匹配?您的allgathers肯定是错误的,请参阅:“请注意,根目录下的recvcount参数表示它从每个进程接收的项目数,而不是它接收的项目总数。”此外,请注意,在分发remainde时,您不能使用MPI_AllGathere,而应使用MPI_allgatherV,尽管在extra=0的示例中,这并不重要。为了计算额外的元素,我会避免使用实数,并坚持使用模和整数除法。到目前为止,我还没有试图理解代码,但是由于您对您的类型使用real(8)
(顺便说一句,这是一个坏主意),因此您(很可能)需要使用MPI\u DOUBLE\u PRECISION
而不是MPI\u real
。先试试这个。什么是extra
初始化为?
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.