每当我尝试使用mpi_reduce
作为发送缓冲区调用mpi_in_place
时,它就会崩溃。谷歌的一个拖网显示这对于OMPI 1.3.3的Mac OS来说是一个问题 - 但我在使用OMPI 1.6.3的CentOS上(使用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实现吗?
答案 0 :(得分:16)
您错过了就地减少操作在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
作为 sendbuf 和 recvbuf 传递给非根进程,因为MPI_REDUCE
不会写入 recvbuf 在这些过程中。