Titulo Introduccin a MPI Clase 3 Marcelo Rozenberg

  • Slides: 23
Download presentation
Titulo Introducción a MPI Clase 3 Marcelo Rozenberg (agradecimiento: Ruben Weht ruweht@cnea. gov. ar)

Titulo Introducción a MPI Clase 3 Marcelo Rozenberg (agradecimiento: Ruben Weht [email protected] gov. ar)

Ejemplo Quiero calcular como :

Ejemplo Quiero calcular como :

double precision mypi, h, sum, x, f, a integer n, myid, size, i, rc,

double precision mypi, h, sum, x, f, a integer n, myid, size, i, rc, ierr, status c --- funcion a integrar f(a) = 4. d 0 / (1. d 0 + a*a) Pi. f-1/2 c --- Numero de intervalos read(5, *) n c --- tamaño del intervalo h = 1. 0 d 0/n c --- realiza las sum = 0. 0 d 0 do i = 1, n x = h * (dble(i) - 0. 5 d 0) sum = sum + f(x) enddo mypi = h * sum pi=mypi write(6, '(" pi es aproximadamente: ", F 18. 16)') pi end

include 'mpif. h' double precision mypi, h, sum, x, f, a integer n, myid,

include 'mpif. h' double precision mypi, h, sum, x, f, a integer n, myid, size, i, rc, ierr, status Pi. f-1/2 c --- funcion a integrar f(a) = 4. d 0 / (1. d 0 + a*a) call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, myid, ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD, size, ierr ) print *, "Proceso ", myid, " de ", size, " funcionando" if(myid. eq. 0) then read(5, *) n endif if(myid. eq. 0) then do i=1, size-1 call MPI_SEND(n, 1, MPI_INTEGER, i, 1, MPI_COMM_WORLD, ierr) enddo else call MPI_RECV(n, 1, MPI_INTEGER, 0, 1, MPI_COMM_WORLD, status, ierr) endif h = 1. 0 d 0/n

sum = 0. 0 d 0 do i = myid+1, n, size x =

sum = 0. 0 d 0 do i = myid+1, n, size x = h * (dble(i) - 0. 5 d 0) sum = sum + f(x) Pi. f-2/2 enddo mypi = h * sum if(myid. eq. 0) then pi=mypi do i=1, size-1 call MPI_RECV(mypi, 1, MPI_DOUBLE_PRECISION, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, status, ierr) pi=pi+mypi enddo else call MPI_SEND(mypi, 1, MPI_DOUBLE_PRECISION, 0, 99, MPI_COMM_WORLD, ierr) endif if (myid. eq. 0) then write(6, '(" pi es aproximadamente: ", F 18. 16)') pi endif call MPI_FINALIZE(rc) end

0 Pi. f-2/2 0 1 1 0+1+1= 2 0 3 2+3+1= 0 4 2

0 Pi. f-2/2 0 1 1 0+1+1= 2 0 3 2+3+1= 0 4 2 6 1 5 3 En log 2(p) pasos comunique el dato a los p-1 procesos. Si p=1024 gano un factor 10! 7

Con las comunicaciones punto-a-punto puedo hacer (casi) todo!!! aunque se necesitaría algo mejor para

Con las comunicaciones punto-a-punto puedo hacer (casi) todo!!! aunque se necesitaría algo mejor para hacerlo más sencillo. . . Comm. Colectivos Comunicaciones colectivas Ejemplo: Broadcast Datos Procesos Ao Ao Ao MPI_Bcast(datos, tamaño, tipo, origen, comm, error)

En nuestro ejemplo para calcular : Broadcast if(myid. eq. 0) then do i=1, size-1

En nuestro ejemplo para calcular : Broadcast if(myid. eq. 0) then do i=1, size-1 call MPI_SEND(n, 1, MPI_INTEGER, i, 1, MPI_COMM_WORLD, ierr) enddo else call MPI_RECV(n, 1, MPI_INTEGER, 0, 1, MPI_COMM_WORLD, status, ierr) endif call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)

A veces uno está interesado en calcular algo globalmente. En nuestro ejemplo de ,

A veces uno está interesado en calcular algo globalmente. En nuestro ejemplo de , quisieramos simplificar: Reduce ! collect all the partial sums if(myid. eq. 0) then pi=0. d 0 do i=1, size-1 call MPI_RECV(mypi, 1, MPI_DOUBLE_PRECISION, MPI_ANY_SOURCE, , MPI_COMM_WORLD, status, ierr) pi=pi+mypi enddo else call MPI_SEND(mypi, 1, MPI_DOUBLE_PRECISION, 0, 99, MPI_COMM_WORLD, ierr) endif MPI_Reduce (mypi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)

include 'mpif. h' double precision mypi, h, sum, x, f, a integer n, myid,

include 'mpif. h' double precision mypi, h, sum, x, f, a integer n, myid, size, i, rc, ierr, status f(a) = 4. d 0 / (1. d 0 + a*a) Pi. f-2/2 call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, myid, ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD, size, ierr ) if(myid. eq. 0) read(5, *) n call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) h = 1. 0 d 0/n sum = 0. 0 d 0 do i = myid+1, n, size x = h * (dble(i) - 0. 5 d 0) sum = sum + f(x) enddo mypi = h * sum call MPI_REDUCE > (mypi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr) if (myid. eq. 0) write(6, '(" pi es aproximadamente: ", F 18. 16)') pi call MPI_FINALIZE(rc) end

Comunicaciones en más detalle

Comunicaciones en más detalle

Comunicaciones Punto a Punto más comunes MPI_SEND(datos, tamaño, tipo_de_dato, destino, tag, comm, ierror) Ej:

Comunicaciones Punto a Punto más comunes MPI_SEND(datos, tamaño, tipo_de_dato, destino, tag, comm, ierror) Ej: MPI_SEND(n, 1, MPI_INTEGER, i, 1, MPI_COMM_WORLD, ierr) envia 1 numero entero “n” al proceso i de comm_world MPI_SEND(a, 5, MPI_REAL, 4, 1, MPI_COMM_WORLD, ierr) envia los 5 numeros reales del vector “a(5)” al proceso 4 de comm_world MPI_RECV(datos, tamaño, tipo_de_dato, origen, tag, comm, status, ierror) Ej: MPI_RECV(n, 1, MPI_INTEGER, 0, 1, MPI_COMM_WORLD, status, ierr)

Para recordar: MPI_SEND y MPI_RECV estándar son bloqueantes!! Comunic. Punto a Punto 2 size

Para recordar: MPI_SEND y MPI_RECV estándar son bloqueantes!! Comunic. Punto a Punto 2 size es el tamaño de los datos threshold es el espacio de buffer disponible Cualquiera de las 2 Situaciones puede ocurrir

Supongamos que: MPI_Send(n, 0) MPI_Recv(n, 1) Que pasa si el proceso 1 no esta

Supongamos que: MPI_Send(n, 0) MPI_Recv(n, 1) Que pasa si el proceso 1 no esta listo para recibir? • P 0 para y espera hasta que P 1 le da el OK • P 0 guarda el dato en un buffer y continua y lo envia luego cuando P 1 le da el OK • El programa falla

3 variantes de Send (y Recv): Sincrónico: MPI_Ssend(. . . ) Comunic. Punto a

3 variantes de Send (y Recv): Sincrónico: MPI_Ssend(. . . ) Comunic. Punto a Punto 3 Permite hacer programas “seguros” ya que no utiliza espacios de buffer. Portabilidad del codigo. Buffered: MPI_Bsend(. . . ) S guarda en un buffer el mensaje y lo envia cuando R lo pida. Hay que reservar espacio de buffer con la rutina MPI_Buffer_attach(. . ) Ready: MPI_Rsend(. . . ) Puede usarse cuando S esta seguro que ya le enviaron el aviso que R esta listo. Si R no estaba listo el comportamiento esta indefinido y es un error de programacion

Comm. Colectivos 1 Comunicaciones Colectivas • Involucran comunicación coordinada dentro de un grupo de

Comm. Colectivos 1 Comunicaciones Colectivas • Involucran comunicación coordinada dentro de un grupo de procesos identificados por un comunicador (ej. MPI_comm_world) • Todas las rutinas son bloqueantes • No hay tags involucrados

Tres tipos de comunicaciones colectivas: Comm. Colectivos 2 • De sincronización • De transferencia

Tres tipos de comunicaciones colectivas: Comm. Colectivos 2 • De sincronización • De transferencia de datos • De cálculo 1) Rutinas de sincronización: call MPI_Barrier(comm, ierror) Todos los procesos del comunicador comm esperan al llegar a la barrera hasta la llegada de todos. Luego continuan todos al mismo tiempo.

2) Rutinas de transferencia de datos: Broadcast, Gatherv, Scatterv Allgather, Allgatherv, Alltoallv Broadcast Datos

2) Rutinas de transferencia de datos: Broadcast, Gatherv, Scatterv Allgather, Allgatherv, Alltoallv Broadcast Datos Proces. Ao Ao Ao MPI_Bcast(datos, tamaño, tipo, origen, comm, error)

En nuestro ejemplo para calcular : Broadcast : ej. if(myid. eq. 0) then do

En nuestro ejemplo para calcular : Broadcast : ej. if(myid. eq. 0) then do i=1, size-1 call MPI_SEND(n, 1, MPI_INTEGER, i, 1, MPI_COMM_WORLD, ierr) enddo else call MPI_RECV(n, 1, MPI_INTEGER, 0, 1, MPI_COMM_WORLD, status, ierr) endif call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)

Datos Proces. Ao A 1 A 2 A 3 Scatter /gather scatter gather Ao

Datos Proces. Ao A 1 A 2 A 3 Scatter /gather scatter gather Ao A 1 A 2 A 3 MPI_Scatter(datos-o, tam-o, tipo-o, datos-r, tam-r, tipo-r, raíz, comm, error) MPI_Gather(datos-o, tam-o, tipo-o, datos-r, tam-r, tipo-r, raíz, comm, error)

Ejemplo de MPI_Gather: multiplicación de una matriz por un vector C=A*B, A(100, 00) B(100)

Ejemplo de MPI_Gather: multiplicación de una matriz por un vector C=A*B, A(100, 00) B(100) C(100) con 4 procesos Ejemplo de gather dimension aloc(25, 100), b(100), cloc(25), ctotal(100) integer root data root/0/ do i=1, 25 cloc(i)=0. do k=1, 100 cloc(i)=cloc(i) + aloc(i, k)*b(k) enddo call MPI_GATHER(cloc, 25, MPI_REAL, ctotal, 25, MPI_REAL, root, MPI_COMM_WORLD, ierr) Nota: sólo “root” junta (recibe) los datos

P 0 C A Cloc Aloc B P 1 P 2 P 3 MPI_Gather

P 0 C A Cloc Aloc B P 1 P 2 P 3 MPI_Gather P 0 (root) C

A P 0 Aloc P 1 P 2 P 3 MPI_Scatter P 0 reparte

A P 0 Aloc P 1 P 2 P 3 MPI_Scatter P 0 reparte (dispersa) la matriz A P 0 (root)