Descargar

Modularidad y Topologías Virtuales

Enviado por Pablo Turmero


Partes: 1, 2, 3

    edu.red Modularidad MPI permite definir grupos de procesos. Un grupo es una colección de procesos, y define un espacio de direcciones (desde 0 hasta el tamaño del grupo menos 1).

    Los miembros del grupo tienen asignada una dirección dentro de él. Un proceso puede pertenecer simultáneamente a varios grupos, y tener una dirección distinta en cada uno de ellos.

    Un comunicador es un universo de comunicación. Básicamente consiste en un grupo de procesos, y un contexto de comunicación. Las comunicaciones producidas en dos comunicadores diferentes nunca interfieren entre sí.

    edu.red Modularidad El concepto de comunicador se introdujo para facilitar la elaboración de bibliotecas de programas: el programa de un usuario se ejecuta en un comunicador, y las funciones de la biblioteca en otro diferente (posiblemente, con el mismo grupo de procesos, pero con un contexto diferente).

    Así no hay riesgo de que se mezclen mensajes del usuario con mensajes privados de las funciones de la biblioteca.

    Además, así tampoco hay problemas a la hora de usar etiquetas.

    Dos de las funciones sobre comunicadores ya han sido presentadas: MPI_Comm_size() para averiguar el tamaño (número de procesos) de un comunicador int MPI_Comm_size(MPI_Comm comm, int *size);

    edu.red Modularidad MPI_Comm_rank() para que un proceso obtenga su identificación dentro del comunicador.

    int MPI_Comm_rank(MPI_Comm comm, int *rank);

    La función MPI_Comm_dup() permite crear un nuevo comunicador, con el mismo grupo de procesos, pero diferente contexto. Se puede usar antes de llamar a una función de una biblioteca.

    int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm);

    edu.red Modularidad La Figura muestra cómo puede ocurrir que un mensaje del usuario (flecha fina) interfiera con los mensajes propios de una función de biblioteca (flechas gruesas). Si la biblioteca trabaja en un comunicador diferente (derecha) entonces no hay problemas de interferencia.

    edu.red Modularidad La operación MPI_Comm_dup(), así como todas las demás que crean comunicadores, son operaciones colectivas: tienen que ser invocadas por todos los procesos implicados, con argumentos compatibles.

    MPI_Comm_free() destruye un comunicador que ya no se va a emplear.

    … MPI_Comm_dup (MPI_COMM_WORLD, &newcomm); /* llamada a función, que se ejecutará dentro de newcomm */ MPI_Comm_free (&newcomm); …

    edu.red Modularidad Por su parte, MPI_Comm_split() crea, a partir de un comunicador inicial, varios comunicadores diferentes, cada uno con un conjunto disjunto de procesos. La variable color determina en qué comunicador queda cada uno de los procesos.

    int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm);

    edu.red Modularidad. Ejemplo Veamos un ejemplo de creación de comunicadores con MPI_Comm_split().

    Partiendo del comunicador universal, definimos dos comunicadores: uno con aquellos procesos que tienen dirección par en el comunicador MPI_COMM_WORLD, y otro con los procesos impares. Cada proceso pertenecerá a dos comunicadores: al universal y al recién creado, y tendrá por lo tanto dos direcciones, una por comunicador.

    int myglobalid, myotherid, color; MPI_Comm newcom; MPI_Comm_rank (MPI_COMM_WORLD, &myglobalid); if (myglobalid%2 == 0) color = 0; else color = 1; MPI_Comm_split (comm, color, myglobalid, &newcom); MPI_Comm_rank (newcom, &myotherid); /* operaciones entre pares e impares, por separado */ MPI_Comm_free (&newcom);

    edu.red Modularidad. Ejemplo La Figura muestra una colección de seis procesos que forman inicialmente parte del comunicador universal y que, tras MPI_Comm_split() pasan a formar dos nuevos comunicadores disjuntos.

    edu.red Modularidad. La función MPI_Intercomm_create() nos permite crear un intercomunicador.

    int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm);

    Los procesos que se encuentran en dos grupos diferentes no pueden comunicarse entre sí, a no ser que se cree un intercomunicador (los comunicadores vistos hasta ahora se denominan intracomunicadores).

    edu.red Modularidad. Todos los procesos de los dos comunicadores que quieren interconectarse deben hacer una llamada a MPI_Intercomm_create() con argumentos compatibles.

    Interpretar los argumentos de esta función no es trivial. En primer lugar, cada proceso tiene que facilitar el comunicador ( local_comm), y nombrar a un proceso local como lider del intercomunicador (local_leader). Luego hay que facilitar un comunicador que englobe a los dos comunicadores que queremos intercomunicar (peer_comm; MPI_COMM_WORLD siempre resulta válido), y la dirección de un proceso del otro comunicador que va a actuar como líder (remote_leader), teniendo en cuenta que esa dirección corresponde al comunicador global.

    Con esto ya se tiene tendido un “puente” entre los dos comunicadores. También hay que facilitar un número de etiqueta (tag) que esté libre y que el programador no debe emplear para ningún otro propósito.

    El intercomunicador lo obtenemos en newintercomm. Una vez que se tiene un intercomunicador, se puede usar para acceder al comunicador que está “al otro lado”. Las direcciones de los procesos receptores que hay que facilitar en las funciones de envío, o las de los procesos emisores que se obtienen tras una función de recepción, hacen referencia a ese “otro lado”.

    Partes: 1, 2, 3
    Página siguiente