La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Introducción a MPI Clase 3 Marcelo Rozenberg (agradecimiento: Ruben Weht Titulo.

Presentaciones similares


Presentación del tema: "Introducción a MPI Clase 3 Marcelo Rozenberg (agradecimiento: Ruben Weht Titulo."— Transcripción de la presentación:

1 Introducción a MPI Clase 3 Marcelo Rozenberg (agradecimiento: Ruben Weht ruweht@cnea.gov.ar) Titulo

2 Ejemplo Quiero calcular  como : Ejemplo

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

4 include 'mpif.h' double precision mypi, pi, h, sum, x, f, a integer n, myid, size, i, rc, ierr, status c --- funcion a integrar f(a) = 4.d0 / (1.d0 + 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.0d0/n Pi.f-1/2

5 sum = 0.0d0 do i = myid+1, n, size x = h * (dble(i) - 0.5d0) sum = sum + f(x) 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:", F18.16)') pi endif call MPI_FINALIZE(rc) end Pi.f-2/2

6 0 1 0 10 3 73516 240 2 En log 2 (p) pasos comunique el dato a los p-1 procesos. Si p=1024 gano un factor 10! 0+1+1= 2+3+1=

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

8 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) En nuestro ejemplo para calcular  : Broadcast

9 A veces uno está interesado en calcular algo globalmente. En nuestro ejemplo de , quisieramos simplificar: ! collect all the partial sums if(myid.eq.0) then pi=0.d0 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, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD,ierr) Reduce

10 include 'mpif.h' double precision mypi, pi, h, sum, x, f, a integer n, myid, size, i, rc, ierr, status f(a) = 4.d0 / (1.d0 + a*a) 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.0d0/n sum = 0.0d0 do i = myid+1, n,size x = h * (dble(i) - 0.5d0) sum = sum + f(x) enddo mypi = h * sum call MPI_REDUCE > (mypi,pi,1,MPI_DOUBLE_PRECISION,MPI_SUM,0, MPI_COMM_WORLD,ierr) if (myid.eq. 0) write(6, '(" pi es aproximadamente:", F18.16)') pi call MPI_FINALIZE(rc) end Pi.f-2/2

11 Comunicaciones en más detalle

12 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)

13 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

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

15 3 variantes de Send (y Recv): Comunic. Punto a Punto 3 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 Sincrónico:MPI_Ssend(.....) Permite hacer programas “seguros” ya que no utiliza espacios de buffer. Portabilidad del codigo.

16 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 Comm. Colectivos 1

17 Tres tipos de comunicaciones colectivas: 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. Comm. Colectivos 2

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

19 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) En nuestro ejemplo para calcular  : Broadcast: ej.

20 AoAo A1A1 A2A2 A3A3 Datos Proces. AoAo A1A1 A2A2 A3A3 MPI_Scatter(datos-o, tam-o, tipo-o, datos-r, tam-r, tipo-r, raíz, comm, error) scatter gather MPI_Gather(datos-o, tam-o, tipo-o, datos-r, tam-r, tipo-r, raíz,comm, error) Scatter/gather

21 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 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 enddo call MPI_GATHER(cloc, 25, MPI_REAL, ctotal, 25, MPI_REAL, root, MPI_COMM_WORLD, ierr) Ejemplo de gather Nota: sólo “root” junta (recibe) los datos

22 A B C P0 P1 P2 P3 Cloc Aloc C P0 (root) MPI_Gather

23 A P0 P1 P2 P3 Aloc P0 (root) MPI_Scatter P0 reparte (dispersa) la matriz A


Descargar ppt "Introducción a MPI Clase 3 Marcelo Rozenberg (agradecimiento: Ruben Weht Titulo."

Presentaciones similares


Anuncios Google