【问题标题】:mpi alters a variable it shouldn't [duplicate]mpi 改变了它不应该的变量[重复]
【发布时间】:2012-11-24 00:34:13
【问题描述】:

我有一些 Fortran 代码正在与 MPI 进行并行处理,这些代码确实很奇怪。首先,有一个变量 nstartg,我从 boss 进程向所有工人广播:

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

变量nstartg 在程序中不再更改。稍后,我让老板进程将数组edgeeproc 元素发送给工人:

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 用来识别消息的标签;如果标签是唯一的,这样消息就不会混淆,这不应该改变任何东西,但它会改变一个完全不相关的变量。

在boss进程中,nstartg没有改变,所以我可以通过再次广播来解决这个问题,但这几乎不是一个真正的解决方案。最后,我应该提一下,使用电子围栏编译和运行这段代码并没有发现任何缓冲区溢出,-fbounds-check 也没有向我抛出任何东西。

【问题讨论】:

  • 能否请您发布重现此行为的最简洁的代码版本?
  • 你确定,你的 eproc 给出的整数个数是正确的吗?

标签: fortran mpi fortran90


【解决方案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_status_ignore修复它,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 2021-01-08
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 2014-05-28
相关资源
最近更新 更多