MPI改变一个变量它不应该[重复](mpi alters a variable it shouldn

2019-07-04 15:46发布

这个问题已经在这里有一个答案:

  • MPI_RECV覆盖部分内存不应该访问 1个回答

我有我与MPI这是做真正奇怪的事情有些并行Fortran代码。 首先,有,我从老板过程中所有的工人广播变量nstartg:

call mpi_bcast(nstartg,1,mpi_integer,0,mpi_comm_world,ierr)

变量nstartg是从来没有在节目中再次改变。 后来,我有老板进程发送eproc数组元素edge的工人:

if (me==0) then
    do n=1,ntasks-1
        (determine the starting point estart and the number eproc
         of values to send)
        call mpi_send(edge(estart),eproc,mpi_integer,n,n,mpi_comm_world,ierr)
    enddo
endif

与匹配的接收声明,如果me不为零。 (我已经离开了的可读性一些其他的代码;还有就是我没有使用scatterv一个很好的理由。)

这就是事情变得怪异:变量nstartg被改变,以n而不是保持其实际值。 例如,在流程1,MPI_RECV后, nstartg = 1 ,并在过程2是等于2,等等。 此外,如果我更改上面的代码

call mpi_send(edge(estart),eproc,mpi_integer,n,n+1234567,mpi_comm_world,ierr)

并相应地改变所述标签在匹配调用MPI_RECV,然后在处理1中,nstartg = 1234568; 工艺2,nstartg = 1234569等

这到底是怎么回事? 所有我改变的是MPI_SEND / recv的使用,以确定该消息的标签; 只要标签是唯一的,这样的消息不会被弄混了,这不应该改变什么,可是它改变一个完全无关的变量。

在老板的过程, nstartg是不变的,所以我可以再次广播发送它解决此问题,但几乎没有一个真正的解决方案。 最后,我要指出,编制和使用电围栏运行这段代码并没有拿起任何缓冲区溢出,也没有-fbounds检查我扔东西。

Answer 1:

最可能的原因是,你传递一个INTEGER标量和实际status参数MPI_RECV时应该真的声明为具体实现的大小的数组,可作为MPI_STATUS_SIZE常数:

INTEGER, DIMENSION(MPI_STATUS_SIZE) :: status

要么

INTEGER status(MPI_STATUS_SIZE)

消息标签写入由接收操作状态的领域之一(其具体实现的指标可作为MPI_TAG常数和字段的值可以为被访问status(MPI_TAG)如果你的status是一个简单的标量INTEGER ,那么其他的一些局部变量将被覆盖。 在你的情况下,它只是碰巧让nstartg正好落在上述status中的堆栈。

如果你不关心的接收状态,你可以通过特殊常量MPI_STATUS_IGNORE代替。



文章来源: mpi alters a variable it shouldn't [duplicate]