Multithreading 当4处理器计算机上有2个以上的线程时,Fortran 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

我正在研究一个并行动态编程问题。我对MPI的奇怪问题是,当我并行使用两个以上的处理器时,会出现错误

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.