2011-03-03 8 views
7

I que tienen algunos problemas de sincronización utilizando la aplicación de OpenMPI MPI_Barrier:problemas OpenMPI MPI_Barrier

int rank; 
int nprocs; 

int rc = MPI_Init(&argc, &argv); 

if(rc != MPI_SUCCESS) { 
    fprintf(stderr, "Unable to set up MPI"); 
    MPI_Abort(MPI_COMM_WORLD, rc); 
} 

MPI_Comm_size(MPI_COMM_WORLD, &nprocs); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 


printf("P%d\n", rank); 
fflush(stdout); 

MPI_Barrier(MPI_COMM_WORLD); 

printf("P%d again\n", rank); 

MPI_Finalize(); 

para mpirun salida -n 2 ./a.out

deben ser: P0 P1 .. .

salida es a veces : P0 P0 nuevo P1 P1 nuevamente

¿Qué está pasando?

Respuesta

13

El orden en que aparecen sus líneas de impresión en su terminal no es necesariamente el orden en que se imprimen las cosas. Está utilizando un recurso compartido (stdout) para eso, por lo que siempre debe haber un problema de pedido. (Y fflush no ayuda aquí, stdout es buffer de línea de todos modos.)

Puede intentar prefijar su salida con una marca de tiempo y guardar todo esto en diferentes archivos, uno por proceso MPI.

Luego, para inspeccionar su registro, puede unir los dos archivos y ordenar de acuerdo con la marca de tiempo.

Tu problema debería desaparecer, entonces.

+1

Confiar en las marcas de tiempo puede no ser ideal si los procesos MPI se ejecutan en nodos diferentes a menos que pueda garantizar que los relojes estén sincronizados. –

+1

@Shawn: Hay MPI_Wtime() para eso. – suszterpatt

+3

@suszterpatt: 'MPI_Wtime()' NO suele ser un reloj global/sincronizado. (Solo lo es si 'MPI_WTIME_IS_GLOBAL' está definido y es verdadero) – Zulan

10

No hay nada de malo con MPI_Barrier().

Como Jens mentioned, la razón por la que no está viendo la salida que esperaba es porque stdout está almacenado temporalmente en cada proceso. No hay garantía de que las impresiones de múltiples procesos se muestren en el proceso de llamada en orden. (Si la salida estándar de cada proceso se transfiere al proceso principal para imprimir en tiempo real, eso generará mucha comunicación innecesaria)

Si quiere convencerse de que la barrera funciona, puede intentar escribir en un archivo en su lugar. Tener múltiples procesos escribiendo en un solo archivo puede llevar a complicaciones adicionales, por lo que puede hacer que cada proceso escriba en un archivo, luego, después de la barrera, intercambie los archivos en los que escriben. Por ejemplo:

Proc-0   Proc-1 
     |     | 
f0.write(..)  f1.write(...) 
     |     | 
     x ~~ barrier ~~ x 
     |     | 
f1.write(..)  f0.write(...) 
     |     | 
    END    END 

aplicación de la muestra:

#include "mpi.h" 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) { 
    char filename[20]; 
    int rank, size; 
    FILE *fp; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    if (rank < 2) { /* proc 0 and 1 only */ 
     sprintf(filename, "file_%d.out", rank); 
     fp = fopen(filename, "w"); 
     fprintf(fp, "P%d: before Barrier\n", rank); 
     fclose(fp); 
    } 

    MPI_Barrier(MPI_COMM_WORLD); 

    if (rank < 2) { /* proc 0 and 1 only */ 
     sprintf(filename, "file_%d.out", (rank==0)?1:0); 
     fp = fopen(filename, "a"); 
     fprintf(fp, "P%d: after Barrier\n", rank); 
     fclose(fp); 
    } 

    MPI_Finalize(); 
    return 0; 

} 

Después de ejecutar el código, usted debe obtener los siguientes resultados:

[[email protected]]$ cat file_0.out 
P0: before Barrier 
P1: after Barrier 

[[email protected]]$ cat file_1.out 
P1: before Barrier 
P0: after Barrier 

para todos los archivos, los estados "después de Barrera" se siempre aparece más tarde.

+0

Excelente explicación ... :) – RoboAlex

3

El orden de salida no está garantizado en los programas MPI.

Esto no está relacionado con MPI_Barrier en absoluto.

Además, no dedicaría demasiado tiempo a preocuparme por el orden de salida con programas MPI.

La forma más elegante de lograr esto, si realmente lo desea, es dejar que los procesos envíen sus mensajes a un rango, digamos, rango 0, y dejar que el rango 0 imprima el resultado en el orden en que los recibió o lo ordenó por rangos

De nuevo, no dedique demasiado tiempo a tratar de pedir la salida de programas MPI. No es práctico y es de poca utilidad.

Cuestiones relacionadas