1 / 23

Titulo

Titulo. Introducción a MPI Clase 3. Marcelo Rozenberg (agradecimiento: Ruben Weht ruweht@cnea.gov.ar). Ejemplo. Ejemplo Quiero calcular como :. Pi.f-1/2. double precision mypi, pi, h, sum, x, f, a integer n, myid, size, i, rc, ierr, status c --- funcion a integrar

gotzon
Télécharger la présentation

Titulo

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Ejemplo Ejemplo Quiero calcular como :

  3. Pi.f-1/2 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

  4. Pi.f-1/2 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

  5. Pi.f-2/2 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

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

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

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

  9. Reduce 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)

  10. Pi.f-2/2 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

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

  14. Que pasa si el proceso 1 no esta listo para recibir? Supongamos que: MPI_Send(n,0) MPI_Recv(n,1) • 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

  15. Comunic. Punto a Punto 3 3 variantes de Send (y Recv): Sincrónico:MPI_Ssend(.....) 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

  16. 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

  17. Comm. Colectivos 2 • 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.

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

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

  20. Scatter/gather Datos scatter Proces. gather 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)

  21. Ejemplo de gather 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) Nota: sólo “root” junta (recibe) los datos

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

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

More Related