Comunicaciones punto a punto P2P En MPI 1.2 solo se permiten comunicaciones que involucran dos...
-
Upload
juan-luis-aranda-barbero -
Category
Documents
-
view
219 -
download
0
Transcript of Comunicaciones punto a punto P2P En MPI 1.2 solo se permiten comunicaciones que involucran dos...
Comunicaciones punto a punto P2P
En MPI 1.2 solo se permiten comunicaciones que involucran dos direcciones: send y receive.MPI 2.0 permite comunicaciones de una sola dirección. get y put, pero no son muy standars aún.Comunicaciones punto a punto (o P2P, point-to-point) son de dos direcciones y en el envío del mensaje participan 2 procesos.Como ya vimos: Un mensaje consiste en un sobre (tags que indican duente y destino) y un cuerpo (Los datos).Fundamental: La mayoria de los MPI comms son construidas con operaciones P2P.
MPI_SEND(buff,count,datatype,dest,tag,comm)MPI_RECV(buff,count,datatype,source,tag,comm,status)
Se pueden usar Wildcards para source y tag, pero no para comunicadorRetorna un error si el buffer de mensaje excede el permitido por el recv. Y eso es responsabilidad del usuario, asi como verificar que los datatypes coincidan
Mas información sobre la recepción del mensaje se encuentra en la estructura status del tipo MPI STATUS que contiene los siguientes campos:
1. MPI SOURCE2. MPI TAG3. MPI ERRORModo de uso status.MPI_Source = ? (Si se uso
MPI_ANY_SOURCE, ahí esta la fuente, etc.)
Además está:MPI_Get_count(MPI_Status* status,MPI_Datatype datatype, int*
contador )Que nos da información del tamaño del mensaje recibido.
Comunicaciones punto a punto P2P
Bloqueantes: No retornan hasta que la operación se completa. Por ejemplo send espera a que el recv este listo y el dato trasnferido seguro para su usoNo bloqueantes: Retorna inmediatamente sin informacion sobre si se completo o no.Usando otras funciones el ususario verifica que se realizo bien la opeacion, entre tanto el proceso es libre de realizar otras tareas.
Comunicaciones punto a punto P2P: Bloqueantes vs. No-Bloqueantes
Modos de comunicación que afectan al send: cuatro (4)standard – Se envia pero no hay garantia de que el receptor este listo
Sincronizado – Se completa cuando el recptor esta listobuffered – Se completa cuando el dato es copiado efectivamente en el buffer local
ready – El usuario se asegura que el recv adecuado esta listo para recibir el mensaje
MPI_Recv – Se completa una vez que llego en cualqueir modo.
dest=size; source =0; i f ( rank == source ) / /inicializo y envio de datos /{ to = dest ; count = 100; tag = 11; for ( i =0; i <=99; i ++) data [ i ]= i ; i e r r = MPI Send ( data , count ,MPI REAL , to , tag,MPICOMMWORLD)} else i f ( rank == dest ) // recepciono y chequeo { tag = MPI ANY TAG; count = 100; from = MPI ANY SOURCE; i e r r = MPI Recv ( data , count ,MPI REAL , from , tag ,MPI COMM WORLD,& s tatus ) ; i e r r = MPI Get count (& status ,MPI REAL,& s t a t c o u n t ) ; statsource = status .MPI SOURCE; s t a t t a g = status .MPI TAG; p r i n t f ( ” Status of receive : dest=%d , source=%d , tag=%d , count=%dnn ” , rank , s tat sour ce , s t a t t a g , s t a t c o u n t ) ;
}
Como vimos: el programador puede tener un control estricto (utilizando modos de envío y seguimiento de los mensajes) del buffering. Como contrapartida, si uno tiene que chequear todo, y asegurarse que hay buffer, etc causa bloqueo.Pero si no se asegura que los P2P son correctom causa deadlock
Entonces..
El implementador puede seguir sus mensajes finamente y lograr programas muy seguros, pero en general todo sistema moderno tiene una política de almacenamiento y el implementador puede independizarse de ese problema. Pero sin relajarse demasiado..
Ejemplo de DeadlockCódigo seguro (sin requerimiento de buffereado):MPI_COMM_RANK(comm,rank)if (rank==0){
MPI_Send(sbuff,count,MPI_REAL,1,tag,comm)MPI_Recv(rbuff,count,MPI_REAL,1,tag,comm,status)}
elseif(rank==1){MPI_Recv(rbuff,count,MPI_REAL,0,tag,comm,status)MPI_Send(sbuff,count,MPI_REAL,0,tag,comm)
}
Deadlock:MPI_COMM_RANK(comm,rank)if(rank==0){
MPI_Recv(rbuff,count,MPI_REAL,1,tag,comm,status)MPI_Send(sbuff,count,MPI_REAL,1,tag,comm)
elseif(rank==1) {MPI_Recv(rbuff,count,MPI_REAL,0,tag,comm,status) MPI_Send(sbuff,count,MPI_REAL,0,tag,comm)
}
Dependencia con el Buffering
MPI_COMM_RANK(comm,rank)if(rank==0) {
MPI_SEND(sbuff,count,MPI_REAL,1,tag,comm) MPI_RECV(rbuff,count,MPI_REAL,1,tag,comm,status)elseif(rank==1) {
MPI_SEND(sbuff,count,MPI_REAL,0,tag,comm)MPI_RECV(rbuff,count,MPI_REAL,0,tag,comm,status)
}
Para este ejemplo, uno de los send debe almacenar y retornarSi el buffer no puede hacerse, ocurre deadlock.Comunicadores No-bloqueantes pueden usarse para evitar este problema e incrementar la performance
Sends & Receives no bloqueantes
Ventajas: 1. Es fácil obtener código que no se cuelgue2. Puede reducir la latencia (requiere una gran atención a la
programación)Desventajas: 1. Código un poco mas complicado2. Mas difícil de seguir los que sucede en el código
MPI_ISEND(buff,count,datatype,dest,tag,comm,request)MPI_IRECV(buff,count,datatype,dest,tag,comm,request)
request manejadorSe utiliza para encolar el estado de la comunicaciónEl usuario no debe sobreescribir el buffer de recepción o utilizar su contenido si no esta seguro de haberlo recibido. (OBVIO!! Pero…)
Funciones complementarias No-Bloqueantes
MPI_WAIT(request,status)request (handle)status MPI_Status
MPI_TEST(request,flag,status) flag true si se completo la operación (logical)El manejador request puede identificar el send o recv anterior
MPI WAIT retorna cuando la operación se completó y puede analizar el status del recv y para el send contiene el error de la operaciónMPI TEST retorna inmediatamente con flag = true si la operación que corresponde al request se completo
Ejemplo No-Bloqueante
MPI Request request ;MPI Status s tatus ;f loa t a [100] , b [ 1 0 0 ] ;..i f ( rank == 0) { MPI I recv ( b ,100 ,MPI REAL,1 ,19 ,MPI COMM WORLD,& request ) ; MPI Send ( a ,100 ,MPI REAL,1 ,17 ,MPI COMMWORLD) ; MPI Wait (&request ,& s tatus ) ; }else i f ( rank == 1) { MPI I recv ( b ,100 ,MPI REAL,0 ,17 ,MPI COMM WORLD,& request ) ; MPI Send ( a ,100 ,MPI REAL,0 ,19 ,MPI COMMWORLD) ; MPI Wait (&request ,& s tatus ) ; }
MPI Get count (& status ,MPI REAL,& s t a t c o u n t ) ;p r i n t f ( ” Exchange complete : process %d of %dnn ” , rank , nprocs ) ;p r i n t f ( ” source %d , tag %d , count %dnn ” , s tatus .MPI SOURCE, s tatus .MPI TAG, s t a t c o u n t ) ;
Modos de comunicación Send: 1 modo receive, 4 modos send
standard – es el mas utilizado, depende de la eleccion en la implmenetacion del buffer (Se supone que MPI y el sistema realizan una eleccion buena a bajo nivel)
Sincronizado- Sincroniaa el proceso de enviar y recibir. Cuando un send sincronizado se completa, el ususrio puede asumir que el receptor ya esta comenzando la recepción
ready – Ya esta el receptor listo antes de enviar. Por lo tanto es indefinido el resultado. Puede ahorrar tiempo y overhead, pero requiere una conociemiento preciso del algoritmo utilizado
buffered – fuerza el almacenado (buffering) – El usuario es responsable por el mantenimeinto del buffer. El resultado es indefinido si el lugar no es suficiente. (MPI BUFFER ATTACH/MPI BUFFER DETACH).
Standard MPI SEND - MPI ISENDSincronizado MPI SSEND - MPI ISSENDReady MPI RSEND - MPI IRSENDBuffered MPI BSEND - MPI IBSEND
MPI Get countMPI_WAITMPI_TEST
MPI INITMPI COMM SIZEMPI COMM RANKMPI SENDMPI RECEIVEMPI FINALIZE
MPI_Barrier
MPI_Broadcast
MPI_Reduce
MPI_ALLReduce
MPI_Scatter
MPI_Gather
MPI_AllGather
MPI_AlltoALL
MPI_Gatherv
MPI_Scatterv
MPI_Wtime
MPI_Wstick
All_Gather_Ring
Genera una serie de bloques de datos y los envia a todos. (allgather) Si se ingresa 0 para.
A la salida cada array que se envio a cada proceso
Los tamaños de array son hardcodeados en MAX y LOCAL_MAX.
12 mensajes 8 mensajes
Comunicadores MPI
Proveen un espacio se comunicación separado dentro del WORLD. Es útil para uso de programas modulares, librerías especiales o cluster heterogéneos.
Si no se desea lidiar con problemas “extras” dados por múltiples topologías, continuar con MPI COMM WORLD es la solución.
Tipos de intercomunicadores:1. intra-comunicadores – Son comms dentro de un grupo de
procesos del WORLD. Apto para construir topologías.2. inter-comunicadores - Son comms entre dos grupos disjuntos de
procesos. No topologías.
Un intra - comunicador se compone de un grupo y un contexto– Grupo: contiene una colección ordenada de procesos– Contexto: un objeto que identifica ese comunicador en forma unica.Cos comunicadores distintos tienen diferente contexto, aunque sean duplicados uno del otro.Cada proceso tiene que tener la información de a que grupo/grupos de proceso pertenece en cada comunicador. Los comunicadores P2P y Colectivos solo envían al comm de un contexto y solo a eseFunciones asociadas al grupo
MPI_COMM_GROUP(MPI_COMM_WORLD, &group_World)La función obtiene el manejador de grupo para un dado comunicador. Nuevos grupos se construyen de otros. Group se utiliza como entrada para MPI GROUP INCL, MPI COMM CREATE and MPI GROUP RANK.
MPI_GROUP_INCL(group, n, ranks, newgroup)MPI_GROUP_EXCL(group, n, ranks, newgroup)
group manejador de grupo (handle) n número de elementos en la lista (tamaño del nuevo grupo) ranks rango del grupo (array de enteros) newgroup se deriva del group ordenado por rango (handle)
MPI_GROUP_INCL incluye un nuevo grupo cuyo proceso iesimo tiene rango ranks[i] en el viejo grupo ( n=0 es un newgroup con el valor MPI GROUP EMPTY)
MPI_GROUP_EXCL excluye de group un newgroup quitando los procesos con rango ranks[0]...ranks[n-1]MPI_GROUP_RANK(group,rank)Retorna el rango de los procesos de group. MPI_GROUP_SIZE(group,size)MPI_GROUP_FREE(group)Libera el conjunto. Group = MPI_GROUP_NULL
MPI_COMM_CREATE(comm,group,&newcomm)comm comunicador (handle)group Subconjunto del grupo del commnewcomm Nuevo comunicador (handle)
Debe ejecutarse por otdos los procesos del comm. Los que no pertenecen al group retornan MPI COMM NULL
MPI_COMM_RANK(newcomm, rank)comm comunicador (handle)rank rango de los procesos del grupo en comm
rank es el rango relativo al grupo asociado con newcomm
MPI_COMM_dup(MPI_COMM_WORLD, &Newcomm)
MPI_COMM_SPLIT(comm, pnew, ranknew, &newcomm) pnew controla el subconjunto a crear (int) ranknew de los procesos del nuevo comm
Particiona al grupo asociado al comm en grupos disjuntos, uno por cada color.
Cada proceso puede tener su porpio color y keyrank en un nuevo comunicador es relativo al rango en el viejo
Es una función muy útil para partir un grupo de comunicadores simple en un numero controlado por el usuario de subgrupos.
Funciones para crear topologías Cartesianas
MPI_CART_CREATE(comm_old, ndims, dims, periods, reorder, comm_cart)
comm_old comunicador (handle)ndims numero de dimensiones en cartesianas (int)dims número de procesos en cada dimensión (int array)periods un arreglo para periodicidad (true) en cada dimensión
(logical array)reorder Reordena los rangos (true) o no (logical)comm_cart comunicador con las nuevas topología cartesiana
(handle)
Esta función colectiva llamada por todos los procesos en el grupo crea un arreglo de procesos en coordenadas cartesianas.
MPI_CART_COORDS(comm,rank,maxdims,coords)comm comunicacor con estructura cartesiana (handle)rank rango de los procesos en el group comm (int)maxdims Tamaño del vector coordenadas llamado por el
programa (int)coords array Contiene las coordinadas cartesianas de los
procesos (int array)
MPI_CART_RANK(comm,coords,rank)comm comunicacor con estructura cartesiana (handle)coords array Contiene las coordinadas cartesianas de los
procesos (int array)rank rango de los procesos (int)
Estas funciones son inversas: la primera trasforma los rangos en coordenadas y viceversa.
All_Gather_Ring
MPI_Comm_dup(MPI_COMM_WORLD, &io_comm);
Cache_io_rank(MPI_COMM_WORLD, io_comm);
Cscanf(io_comm,"Enter the local array size","%d", &blocksize);
#include "cio.h“#include “vsscanf.c”
cio.cvsscanf.c