每当我尝试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既是sendbuf和recvbuf在非根进程,因为MPI_REDUCE不写recvbuf在这些进程.