2013-07-19 72 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'。該標準分別列出了每項操作的正確用途。 –