¿Cómo puedo inicializar MPI en una función?

Quiero usar multiprocesos en una función y cómo puedo hacerlo.

Como sabe, MPI_Init necesita dos parámetros: "int argc, char **argv". ¿Significa que debo agregar estos dos parámetros en la definición de la función?

Mi requisito es que quiero paralelizar un paso en función en lugar del paso en el programa principal.

Por ejemplo, los servicios administrativos de

func(mat &A, vec &x) {
  some computation on A;
  auto B = sub_mat(A, 0, 10);
  B*x; // I want to parallelize this computation
}
main(){
  mat A;
  vec x;
  func(A, x);
}

Solo quiero usar MPI en B*x, pero no sé cómo iniciar MPI. Por cierto, si puedo iniciar MPI int func, ¿existe A en todos los procesos en este momento?

¡Ayúdame y gracias!

preguntado el 28 de julio de 12 a las 13:07

Parece que tiene un malentendido fundamental sobre lo que es MPI. MPI proporciona un mecanismo de comunicación y sincronización entre rangos (es decir, donde un rango is un proceso... al menos en todas las implementaciones interesantes). En particular, será necesario duplicar todo el ejecutable en cada rango, tanto "main" como "func". El tipo de paralelismo que está intentando probablemente se logre mejor con subprocesos, tal vez usando OpenMP. -

2 Respuestas

No necesitas pasar argc y argv desde que MPI-2 eliminó la restricción en MPI-1 de que las implementaciones compilantes puede requieren argumentos para MPI_Init ser lo mismo que los argumentos para main:

En las implementaciones MPI-2 no se permite imponer este requisito. Se requieren implementaciones conformes de MPI para permitir que las aplicaciones pasen NULL tanto para el argc y argv argumentos de main.

Pero aún tiene que probar si MPI ya está inicializado desde MPI_Init() (o MPI_Init_thread()) no debe llamarse más de una vez. Esto se hace usando MPI_Initialized(), por lo que su código debería verse así:

int initialized, finalized;

MPI_Initialized(&initialized);
if (!initialized)
   MPI_Init(NULL, NULL);

// Perform work in parallel
...

// You also need this when your program is about to exit
MPI_Finalized(&finalized);
if (!finalized)
   MPI_Finalize();

Tenga en cuenta que MPI se puede inicializar y luego finalizar solo una vez durante toda la vida útil de la aplicación. Eso está rodeando un bloque de código de función con MPI_Init() ... MPI_Finalize() no funcionará si la función se va a llamar varias veces, es decir, MPI no funciona de la misma manera que OpenMP con sus regiones paralelas.

Por cierto, si puedo iniciar MPI int func, ¿existe A en todos los procesos en este momento?

Un programa MPI en ejecución consta de múltiples en costes con sus propios espacios privados de direcciones. Por lo general, se trata de varias copias del mismo código de programa (el llamado paradigma de datos múltiples de programa único o SPMD), pero también pueden ser copias múltiples de varios programas, escritos para trabajar juntos (también llamados datos múltiples de programas múltiples o MPMD). SPMD es el caso más simple y común en el que todos los procesos ejecutan exactamente el mismo código hasta el punto en que su rango MPI se usa para bifurcar la ejecución en múltiples direcciones. Entonces sí, A existe en cada proceso y si no hay números/eventos (pseudo-)aleatorios involucrados en los cálculos anteriores, entonces A tendría el mismo valor en todos los procesos MPI antes de la inicialización de la biblioteca MPI. Tenga en cuenta que MPI_Init() es solo una llamada de biblioteca regular como cualquier otra llamada de biblioteca. No cambia el contenido de la memoria del usuario: solo hace que la multitud de procesos MPI en ejecución se conozcan entre sí y les permite comunicarse entre sí, lo que les permite trabajar colectivamente para resolver el problema en particular.

Respondido 28 Jul 12, 15:07

Si quieres usar MPI_Init en una subfunción, tienes que pasar int argc, char **argv a la función, para transmitirla.

Pero incluso si solo desea paralelizar una parte de una subfunción, puede (y debe para un código más transparente) usar MPI_Init temprano en el programa. Por ejemplo, después de que terminen otras cosas de inicialización, o si desea usarlo cerca de su función paralelizada, inmediatamente antes de llamar a la función.

En principio, la función no tiene que saber acerca de argc y argv, ¿lo hace?

Respondido 28 Jul 12, 13:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.