2011-07-11 8 views
5

Al llamar a MPI_BCAST, ¿hay alguna sincronización implícita? Por ejemplo, si el proceso del remitente llegara al MPI_BCAST antes que a otros, ¿podría hacer el BCAST y luego continuar sin ningún agradecimiento? Algunas pruebas recientes con código como:Sincronización implícita con MPI_BCAST para el emisor y los receptores?

program test 
include 'mpif.h' 

integer ierr, tid, tmp 

call MPI_INIT(ierr) 
call MPI_COMM_RANK(MPI_COMM_WORLD, tid, ierr) 

tmp = tid 

if(tid.eq.0) then 
    call MPI_BCAST(tmp,1,MPI_INTEGER,MPI_ROOT,MPI_COMM_WORLD, ierr) 
else 

endif 

write(*,*) tid,'done' 
call MPI_FINALIZE(ierr) 

end 

muestra que con dos hilos que ambos llegan a la terminación, a pesar de sólo el remitente haciendo una llamada a MPI_BCAST.

Salida:

1 done   0 
0 done   0 

Podría ser esto un problema con la instalación MPI Estoy trabajando con (MPICH), o se trata de un comportamiento estándar de MPI?

Respuesta

1

Bcast es una llamada de comunicación colectiva, y como tales bloques. Más precisamente, bloquea hasta que todos los procesos en el comunicador especificado hayan hecho una llamada coincidente al Bcast, en cuyo punto se produce la comunicación y la ejecución continúa.

Su código está demasiado simplificado para la depuración. ¿Puedes publicar un ejemplo mínimo de trabajo que demuestre el problema?

+0

Bien, he puesto el programa completo con el que estoy trabajando. Esperaría que bloqueara indefinidamente esperando que otros llamaran a MPI_BCAST si mpirun se inicia con más de 1 procesador, pero en mi máquina sale con ambos procesos haciendo la llamada para escribir, con el valor 0 en tmp – agrippa

+0

No necesita bloque: la raíz no necesita ninguna respuesta de los otros rangos para continuar, por lo tanto, es posible que no los espere. En particular, en un protocolo de mensaje ansioso, la raíz enviará su mensaje inmediatamente y se ubicará en un búfer en (algunos de) los otros rangos hasta que llamen a 'MPI_Bcast'. –

+1

@Jeremiah: no es cierto. El estándar MPI requiere que para cuando 'Bcast' regrese, el contenido del buffer de la raíz ha sido copiado a todos los procesos. @ user631027: en su programa, procese 0 bloques en 'Bcast', pero el proceso 1 llega inmediatamente a' Finalize', reduciendo el tamaño de MPI_COMM_WORLD a 1. Como tal, el proceso 0 ahora es libre de completar 'Bcast' ya que él es el único para transmitir a. Si el proceso 1 llamara a un 'Bcast' que no coincide con el del proceso 0, el programa se bloqueará. – suszterpatt

0

Puedo certificar que MPI_Bcast hace NO bloque, al menos para el proceso de enrutamiento (envío). Debería llamar al MPI_Barrier inmediatamente después si quiere estar seguro de que su programa se bloquea. Lo sé porque hace poco llamé accidentalmente al MPI_Bcast para el proceso raíz solo (en lugar de hacerlo colectivamente) y la ejecución del programa continuó normalmente hasta mucho más tarde cuando la siguiente llamada no relacionada al MPI_Bcast, en la que se recibió el nuevo buffer en el nuevo buffers. Esta falta de coincidencia en el tipo/longitud de datos del buffer produjo datos basura y me tomó un tiempo encontrar ese error.

+1

Hola MasterHD, creo que las razones del comportamiento que observaste y el comportamiento que me hizo publicar la pregunta originalmente son las mismas. MPI_Bcast es una operación colectiva MPI, lo que significa que el estándar MPI dice que todos los rangos deben participar. Si lo hacen, entonces MPI_Bcast es una operación de bloqueo. Si no lo hacen, entonces el programa MPI no cumple con el estándar y verá un comportamiento indefinido. En ambos casos, ese comportamiento indefinido fue que el programa avanzó alegremente en su camino como si nada hubiera estado mal. – agrippa

+0

El punto que estaba tratando de plantear es que si 'MPI_Bcast' era realmente un método ** de bloqueo **, al llamarlo SÓLO el proceso de raíz colgaría inmediatamente ese proceso raíz sin permitir que continuara. ¿Esa era tu pregunta o algo más? – MasterHD

+1

Además, @MasterHD, si su llamada 'MPI_Bcast' tenía almacenamientos intermedios suficientemente grandes que intentaba enviar, probablemente también se habría bloqueado en el proceso raíz. Solo se completó porque probablemente enviaba pequeñas cantidades de datos almacenados temporalmente en el búfer. –

Cuestiones relacionadas