13

每当我尝试作为发送缓冲区调用mpi_reducempi_in_place,它都会崩溃。谷歌的拖网显示这是 OMPI 1.3.3 在 Mac OS 上的一个问题 - 但我在 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 实现?

4

1 回答 1

24

您错过了 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

您可以在非 root 进程中安全地buffer作为sendbufrecvbufMPI_REDUCE传递,因为在这些进程中不会写入recvbuf

于 2013-07-19T11:17:34.417 回答