【问题标题】:In place mpi_reduce crashes with OpenMPI就地 mpi_reduce 与 OpenMPI 崩溃
【发布时间】:2013-07-18 11:20:35
【问题描述】:

每当我尝试使用mpi_in_place 作为发送缓冲区调用mpi_reduce 时,它都会崩溃。谷歌搜索显示这在 Mac OS 上是 OMPI 1.3.3 的问题 - 但我在 CentOS 上使用 OMPI 1.6.3(使用 gfortran 4.4.6)。

以下程序崩溃:

PROGRAM reduce

  USE mpi

  IMPLICIT NONE

  REAL, DIMENSION(2, 3) :: buffer, gbuffer

  INTEGER :: ierr, me_world
  INTEGER :: buf_shape(2), counts

  CALL mpi_init(ierr)
  CALL mpi_comm_rank(mpi_comm_world, me_world, ierr)

  buffer = 1.
  IF (me_world .EQ. 0) PRINT*, "buffer: ", buffer

  buf_shape = SHAPE(buffer)
  counts = buf_shape(1)*buf_shape(2)

  CALL mpi_reduce(MPI_IN_PLACE, buffer, counts, mpi_real, mpi_sum, 0, mpi_comm_world, ierr)
  IF (me_world .EQ. 0) PRINT*, "buffer: ", buffer

  CALL mpi_finalize(ierr)

END PROGRAM reduce

MPI 错误是:

MPI_ERR_ARG: invalid argument of some other kind

这不是很有帮助。

我是否遗漏了应该如何调用 mpi_reduce 的内容?这是否适用于其他编译器/MPI 实现?

【问题讨论】:

    标签: fortran mpi


    【解决方案1】:

    您错过了 MPI 中就地归约操作如何工作的一个非常重要的部分(请参阅粗体文本):

    当通信器是内部通信器时,您可以就地执行reduce操作(输出缓冲区用作输入缓冲区)。使用变量MPI_IN_PLACE 作为根进程 sendbuf 的值。在这种情况下,输入数据从接收缓冲区的根处获取,在那里它将被输出数据替换。

    其他进程仍然需要以 sendbuf 的形式提供它们的本地缓冲区,而不是 MPI_IN_PLACE:

    IF (me_world == 0) THEN
      CALL mpi_reduce(MPI_IN_PLACE, buffer, counts, MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
    ELSE
      CALL mpi_reduce(buffer, buffer, counts, MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
    END IF
    

    您可以在非根进程中安全地将buffer 作为sendbufrecvbuf 传递,因为MPI_REDUCE 不会写入recvbuf在这些过程中。

    【讨论】:

    • 谢谢,解决了!我误解了MPI_IN_PLACE 文档,因为我认为所有进程都必须使用完全相同的参数调用集体通信。
    • 糟糕,你确定吗?刚刚查看了我的生产代码,我有很多错误使用的实例,到目前为止我还没有遇到问题。
    • @VladimirF,有一些集体操作必须将MPI_IN_PLACE 指定为所有等级的发送缓冲区,例如MPI_ALLTOALLMPI_ALLREDUCE。该标准分别列出了每个操作的正确用法。
    • @HristoIliev 谢谢,你是对的!它们大多是 Allreduce,少数几个 Reduce 实例得到了正确处理。
    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2014-01-25
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    相关资源
    最近更新 更多