就地,mpi_reduce与OpenMPI崩溃

Yos*_*ian 8 fortran mpi

每当我尝试mpi_reduce使用mpi_in_place发送缓冲区进行调用时,它都会崩溃.谷歌的一个拖网显示这对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
Run Code Online (Sandbox Code Playgroud)

MPI错误是:

MPI_ERR_ARG: invalid argument of some other kind
Run Code Online (Sandbox Code Playgroud)

这不是很有帮助.

我错过了mpi_reduce应该如何调用的内容吗?这适用于其他编译器/ MPI实现吗?

Hri*_*iev 18

您错过了就地减少操作在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
Run Code Online (Sandbox Code Playgroud)

您可以安全地传递buffer既是sendbufrecvbuf在非根进程,因为MPI_REDUCE不写recvbuf在这些进程.

  • @VladimirF,有一些集体操作必须将`MPI_IN_PLACE` 指定为所有等级的发送缓冲区,例如`MPI_ALLTOALL` 或`MPI_ALLREDUCE`。该标准分别列出了每个操作的正确使用方法。 (3认同)