2013-07-19 69 views
7

每当我尝试拨打mpi_reducempi_in_place作为发送缓冲区时,它会崩溃。谷歌拖网揭示这在OMPI 1.3.3的Mac OS上是一个问题 - 但我在CentOS上使用OMPI 1.6.3(使用gfortran 4.4.6)。原地mpi_reduce与OpenMPI崩溃

下面的程序崩溃:

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实现?

回答

14

你缺少的就地减少操作MPI是如何工作的一个非常重要的组成部分(见黑体字):

当沟通是一个intracommunicator,您可以执行减少操作IN-放置(输出缓冲区用作输入缓冲区)。使用变量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

+0

谢谢,修好了!我错误地解释了'MPI_IN_PLACE'文档,因为我认为集体通信必须由所有具有完全相同参数的进程调用。 – Yossarian

+0

哎呀,你确定吗?只是看看我的生产代码,我有很多错误的使用情况,到目前为止我还没有遇到过问题。 –

+0

@VladimirF,有一些集体操作,其中'MPI_IN_PLACE'必须被所有等级指定为发送缓冲区,例如'MPI_ALLTOALL'或'MPI_ALLREDUCE'。该标准分别列出了每项操作的正确用途。 –