referencia procesos mundo mpi_init hola entre ejercicios definir comunicadores comunicacion aplicaciones multithreading fortran mpi openmp

multithreading - procesos - mpich pdf



vinculaciĆ³n de hilos a ciertos procesos MPI (2)

Puedes enviar tu trabajo usando enlaces a núcleos. Luego, durante la ejecución, puede llamar a sched_setaffinity en su programa ( http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html ) usando ISO_C_BINDINGS porque es una función C.

Tengo la siguiente configuración, un código híbrido MPI / OpenMP que ejecuta procesos M MPI con N subprocesos cada uno. En total, hay hilos MxN disponibles.

Lo que me gustaría hacer, si es posible, es asignar subprocesos solo a algunos procesos MPI, no a todos ellos, mi código sería más eficiente ya que algunos de los hilos solo están haciendo trabajo repetitivo.

Gracias.


Tu pregunta es una versión generalizada de esta . Hay al menos tres soluciones posibles.

Con la mayoría de las implementaciones MPI, es posible iniciar múltiples ejecutables con sus propios entornos (contextos) como parte del mismo trabajo MPI. Se llama modelo MPMD (datos múltiples de programas múltiples) o MIMD (datos múltiples de múltiples instrucciones). La sintaxis generalmente implica : (dos puntos) como un separador:

$ mpiexec <global parameters> -n n1 <local parameters> executable_1 <args1> : -n n2 <local parameters> executable_2 <args2> : ... -n nk <local parameters> executable_k <argsk>

<args1> n1 filas ejecutando executable_1 con argumentos de línea de comandos <args1> , n2 clasifica ejecutando executable_2 con argumentos de línea de comandos <args2> , y así sucesivamente. En total, los procesos n1 + n2 + ... + nk se inician y los rangos se asignan linealmente:

Ranks (from .. to) | Executable ====================|============= 0 .. n1-1 | executable_1 n1 .. n1+n2-1 | executable_2 n1+n2 .. n1+n2+n3-1 | executable_3 ... | ...

Como un caso más restringido, el mismo ejecutable podría especificarse k veces para obtener k contextos diferentes con el mismo ejecutable. <local parameters> podría incluir la configuración de valores de variables de entorno específicas, por ejemplo, en su caso podría ser OMP_NUM_THREADS . El método exacto para especificar el entorno difiere de una implementación a otra. Con Open MPI, uno haría:

mpiexec --hostfile all_hosts / -n 5 -x OMP_NUM_THREADS=2 myprog : / -n 4 -x OMP_NUM_THREADS=4 myprog : / -n 6 -x OMP_NUM_THREADS=1 myprog

Eso iniciará 15 rangos MPI en los hosts especificados en all_hosts (un parámetro global) con los primeros cinco usando dos hilos OpenMP, los siguientes cuatro - cuatro hilos OpenMP, y los últimos seis ejecutando secuencialmente. Con las implementaciones basadas en MPICH, el comando sería ligeramente diferente:

mpiexec --hostfile all_hosts / -n 5 -env OMP_NUM_THREADS 2 myprog : / -n 4 -env OMP_NUM_THREADS 4 myprog : / -n 6 -env OMP_NUM_THREADS 1 myprog

Aunque es ampliamente compatible, el método anterior es un poco inflexible. ¿Qué pasa si a uno le gustaría, por ejemplo, todos los rangos, excepto cada 10ª ejecución secuencialmente? Entonces la línea de comando se convierte en:

mpiexec ... -n 9 -x OMP_NUM_THREADS=1 myprog : / -n 1 -x OMP_NUM_THREADS=N myprog : / -n 9 -x OMP_NUM_THREADS=1 myprog : / -n 1 -x OMP_NUM_THREADS=N myprog : / ...

Una solución más conveniente sería proporcionar un contenedor que establezca OMP_NUM_THREADS según el rango del proceso. Por ejemplo, tal envoltorio para Open MPI se ve así:

#!/bin/bash if [ $((($OMPI_COMM_WORLD_RANK + 1) % 10)) == 0 ]; then export OMP_NUM_THREADS=N else export OMP_NUM_THREADS=1 fi exec "$*"

y se usa simplemente como:

mpiexec -n M ... mywrapper.sh myprog <args>

La tercera y menos flexible opción es simplemente llamar a omp_set_num_threads() desde dentro del programa después de la inicialización de MPI pero antes de cualquier región paralela y establecer un número diferente de subprocesos según el rango:

integer :: provided, rank, ierr call MPI_INIT_THREAD(MPI_THREAD_FUNNELED, provided, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) if (mod(rank, 10) == 0) then call omp_set_num_threads(N) else call omp_set_num_threads(1) end if

Independientemente de la solución que se elija, el proceso y el encuadernado de hilos se vuelven un poco complicados y probablemente deberían apagarse por completo.