mpi改变它不应该的变量

时间:2012-12-06 02:07:55

标签: fortran mpi fortran90

我有一些Fortran代码,我正在与MPI并行化,这正在做着真正奇怪的事情。首先,我有一个变量nstartg,我从老板流程向所有工人广播:

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

变量nstartg永远不会在程序中再次更改。稍后,我让老板进程向工作人员发送数组eproc的{​​{1}}元素:

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 非零,则使用匹配的接收语句

。 (为了便于阅读,我省略了其他一些代码;我有一个很好的理由不使用scatterv。)

以下事情变得奇怪:变量me变为nstartg而不是保持其实际值。例如,在进程1上,在mpi_recv,n之后,在进程2上,它等于2,依此类推。此外,如果我将上面的代码更改为

nstartg = 1

并在匹配调用mpi_recv时相应地更改标记,然后在进程1,nstartg = 1234568;在过程2,nstartg = 1234569等

到底是怎么回事?我改变的是mpi_send / recv用于识别消息的标签;如果标签是唯一的,那么消息不会混淆,这不应该改变任何东西,但它改变了一个完全不相关的变量。

在boss过程中,call mpi_send(edge(estart),eproc,mpi_integer,n,n+1234567,mpi_comm_world,ierr) 没有改变,所以我可以通过再次播放来解决这个问题,但这不是一个真正的解决方案。最后,我应该提一下,使用电栅栏编译和运行此代码并没有发现任何缓冲区溢出,也没有--fbounds-check向我抛出任何东西。

1 个答案:

答案 0 :(得分:5)

最可能的原因是您将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