2013-07-19 11 views
7

Ogni volta che provo a chiamare mpi_reduce con mpi_in_place come buffer di invio si blocca. Una rete di google rivela che si è verificato un problema su Mac OS per OMPI 1.3.3 - ma sono su CentOS con OMPI 1.6.3 (con gfortran 4.4.6).In posto mpi_reduce si blocca con OpenMPI

Il programma va in crash seguenti:

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 

L'errore MPI è:

MPI_ERR_ARG: invalid argument of some other kind 

, che non è molto utile.

Mi manca qualcosa su come chiamare mpi_reduce? Funziona con altri compilatori/implementazioni MPI?

risposta

14

Ti manca una parte molto importante di come l'operazione di riduzione sul posto lavora in MPI (vedi il testo in grassetto):

Quando il communicator è un intracommunicator, è possibile eseguire un'operazione di ridurre in- posto (il buffer di uscita viene utilizzato come buffer di input). Utilizzare la variabile MPI_IN_PLACE come valore del processo root sendbuf. In questo caso, i dati di input sono presi alla radice dal buffer di ricezione, dove verrà sostituito dai dati di output.

Gli altri processi devono ancora fornire i buffer locali come sendbuf, non 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 

È possibile passare sicuro buffer sia come sendbuf e recvbuf in processi non root poiché MPI_REDUCE non scrive in recvbuf in tali processi.

+0

Grazie, è stato risolto! Ho interpretato erroneamente la documentazione di 'MPI_IN_PLACE' perché pensavo che le comunicazioni collettive dovevano essere chiamate da tutti i processi con esattamente gli stessi argomenti. – Yossarian

+0

Oops, sei proprio sicuro? Ho appena esaminato il mio codice di produzione e ho molti esempi di utilizzo errato e non ho riscontrato alcun problema finora. –

+0

@VladimirF, ci sono alcune operazioni collettive in cui 'MPI_IN_PLACE' deve essere specificato come buffer di invio da tutti i ranghi, ad esempio' MPI_ALLTOALL' o 'MPI_ALLREDUCE'. Lo standard elenca l'uso corretto per ogni operazione separatamente. –