kor*_*rok 1 fortran mpi fortran90
我有一些Fortran代码,我正在与MPI并行化,这正在做着真正奇怪的事情.首先,我有一个变量nstartg,我从老板流程向所有工人广播:
call mpi_bcast(nstartg,1,mpi_integer,0,mpi_comm_world,ierr)
Run Code Online (Sandbox Code Playgroud)
该程序中的变量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
Run Code Online (Sandbox Code Playgroud)
如果me非零,则匹配的receive语句.(为了便于阅读,我遗漏了一些其他代码;我有一个很好的理由不使用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)
Run Code Online (Sandbox Code Playgroud)
并在匹配调用mpi_recv时相应地更改标记,然后在进程1,nstartg = 1234568; 在过程2,nstartg = 1234569等
到底是怎么回事?我改变的是mpi_send/recv用于识别消息的标签; 如果标签是唯一的,那么消息不会混淆,这不应该改变任何东西,但它改变了一个完全不相关的变量.
在老板的过程中,nstartg没有改变,所以我可以通过再次播放来解决这个问题,但这不是一个真正的解决方案.最后,我应该提一下,使用电栅编译和运行此代码并没有发现任何缓冲区溢出,也没有--fbounds-check向我抛出任何东西.
最可能的原因是您将INTEGER标量作为实际status参数传递给MPI_RECV它应该真正声明为具有特定于实现的大小的数组,可用作MPI_STATUS_SIZE常量:
INTEGER, DIMENSION(MPI_STATUS_SIZE) :: status
Run Code Online (Sandbox Code Playgroud)
要么
INTEGER status(MPI_STATUS_SIZE)
Run Code Online (Sandbox Code Playgroud)
消息标记由接收操作写入其中一个状态字段(其特定于实现的索引可用作MPI_TAG常量,字段值可以作为访问status(MPI_TAG)),如果您status只是标量INTEGER,那么其他几个局部变量将被获取覆盖.在你的情况下,它只是发生在堆栈中的nstartg上方status.
如果您不关心接收状态,则可以传递特殊常量MPI_STATUS_IGNORE.
| 归档时间: |
|
| 查看次数: |
475 次 |
| 最近记录: |