MemoriaSeminario1.pdf

5
Asignatura : Programación Paralela Autor : Rubén Perandrés Gómez Seminario práctico 1. Introducción al desarrollo de programas paralelos usando MPI. 1. Modificar el programa solución del ejercicio 3.2 Send Receive del tutorial para que el proceso 0 difunda su identificador de proceso (0) al resto de procesos con identificadores pares, siguiendo un anillo de procesos pares, y el proceso 1 haga lo mismo con los procesos impares. Se deben tener en cuenta soluciones con cualquier número de procesos. Simplemente modificando las condiciones de entrada al bloque de envio y recepcion de mensaje, conseguiremos esta estructura de mensajes if(rank+2 <= size1){ MPI_Send(&rank //referencia al vector de elementos a enviar ,1 // tamaño del vector a enviar ,MPI_INT // Tipo de dato que envias ,(rank+2) // pid del proceso destino ,0 //etiqueta ,MPI_COMM_WORLD); //Comunicador por el que se manda }if(rank2 >= 0){ MPI_Recv(&contador // Referencia al vector donde se almacenara lo recibido ,1 // tamaño del vector a recibir ,MPI_INT // Tipo de dato que recibe ,(rank2) % size// pid del proceso origen de la que se recibe ,0 // etiqueta ,MPI_COMM_WORLD // Comunicador por el que se recibe ,&estado); // estructura informativa del estado cout<< "Soy el proceso "<<rank<<" y he recibido "<<contador<<endl; } **NOTA : rank es el número de proceso actual El primer if se encarga de que cada uno de los procesos entrante envien el mensaje al proceso situado dos posiciones más adelante (ej. 0 envía al 2, 1 envía al 3 ), la condición del primer if [ if(rank+2 <= size1) ] controla que si hay 4 procesos por ejemplo (0, 1, 2 y 3), el proceso 2 y 3 no entren al bloque del primer if ya que el proceso 2 enviara un mensaje al proceso 4 y el proceso 3 al 5 y el proceso 4 y 5 no existen.

Transcript of MemoriaSeminario1.pdf

Page 1: MemoriaSeminario1.pdf

Asignatura : Programación Paralela Autor : Rubén Perandrés Gómez

Seminario práctico 1. Introducción al desarrollo de programas paralelos usando MPI.

1. Modificar el programa solución del ejercicio 3.2 Send Receive del tutorial para

que el proceso 0 difunda su identificador de proceso (0) al resto de procesos con identificadores pares, siguiendo un anillo de procesos pares, y el proceso 1 haga lo mismo con los procesos impares. Se deben tener en cuenta soluciones con cualquier número de procesos.

Simplemente modificando las condiciones de entrada al bloque de envio y recepcion de mensaje, conseguiremos esta estructura de mensajes

if(rank+2 <= size­1) MPI_Send(&rank //referencia al vector de elementos a enviar ,1 // tamaño del vector a enviar ,MPI_INT // Tipo de dato que envias ,(rank+2) // pid del proceso destino ,0 //etiqueta ,MPI_COMM_WORLD); //Comunicador por el que se manda if(rank­2 >= 0) MPI_Recv(&contador // Referencia al vector donde se almacenara lo recibido ,1 // tamaño del vector a recibir ,MPI_INT // Tipo de dato que recibe ,(rank­2) % size// pid del proceso origen de la que se recibe ,0 // etiqueta ,MPI_COMM_WORLD // Comunicador por el que se recibe ,&estado); // estructura informativa del estado

cout<< "Soy el proceso "<<rank<<" y he recibido "<<contador<<endl;

**NOTA : rank es el número de proceso actual El primer if se encarga de que cada uno de los procesos entrante envien el mensaje al proceso situado dos posiciones más adelante (ej. 0 envía al 2, 1 envía al 3 ), la condición del primer if [ if(rank+2 <= size­1) ] controla que si hay 4 procesos por ejemplo (0, 1, 2 y 3), el proceso 2 y 3 no entren al bloque del primer if ya que el proceso 2 enviara un mensaje al proceso 4 y el proceso 3 al 5 y el proceso 4 y 5 no existen.

Page 2: MemoriaSeminario1.pdf

Asignatura : Programación Paralela Autor : Rubén Perandrés Gómez

El segundo if, controla la recepción de los mensajes, como se nos plantea el ejercicio, ni el proceso 0 ni el 1 esperan recibir mensajes de ningún proceso por lo que la condición del segundo if if(rank­2 >= 0), impedirá que estos procesos entren al bloque y se queden bloqueados esperando la recepción de un mensaje no enviado Ejemplo Gráfico con 5 procesos:

2. Modificar el programa solución del cálculo paralelo del número π (3.3 Cálculo de PI) para que los subintervalos de trabajo sean distribuidos por bloques en lugar de cıclicamente entre los procesos. Por ejemplo, si tuvieramos 3 procesos y n = 11 (número de subintervalos), el proceso 0 deberıa aproximar las integrales numéricas en los primeros 4 subintervalos consecutivos (1,2,3,4), el proceso 1 calcular´ıa las integrales en los siguientes 4 subintervalos (5,6,7,8,) y el proceso 2 calcular´ıa los últimos tres (9,10,11). Se recomienda empezar derivando matem´aticamente un método general para repartir por bloques n subintervalos entre P procesos para cualquier n entero positivo. Modificarlo también la soluci´on para que la aproximaci´on a π se obtenga en todos los procesos.

Para que el trabajo distribuido se realice por bloques, hay que cambiar los indices del bucle for de la siguiente manera

Page 3: MemoriaSeminario1.pdf

Asignatura : Programación Paralela Autor : Rubén Perandrés Gómez

int tam_block = ceil((double)n/size); for (int i =(tam_block* rank)+1; i < (tam_block*(rank+1))+1 && i <= n; i++)

double x = h * ((double)i ­ 0.5); sum += (4.0 / (1.0 + x*x));

Representacion Grafica de la reparticion de un vector de 8 elementos para 3 procesos

**Nota: tomamos la primera posicion como 1 en vez de 0 tam_blok = 3 // ceil(8/3) inicio (tam_block* rank)+1 fin (tam_block*(rank+1))+1 P0 inicio = (3*0)+1 = 1; fin =(3*1)+1 = 4 P1 inicio = (3*1)+1 = 4; fin =(3*2)+1 = 7 P2 inicio = (3*2)+1 = 7; fin =(3*3)+1 = 10 (seria 10 pero hay 8 elementos en el bucle controlamos que no se sale con i <= n )

3. Modificar el programa solución del cálculo del producto escalar de dos vectores (4.1 Producto Escalar) para que cada proceso inicialice por su cuenta su parte correspondiente del vector B de forma local, de tal forma que no haya necesidad de inicializar todo el vector B en el proceso 0 y repartir sus bloques entre los procesos.

Se pide que cada proceso inicialice el vector de forma local

//tama es el tamaño del vector //size es el numero de procesos //rank es el identificador de preoceso int j =0; int ofset = 10*(tama / size); for (long i = ofset*rank +10 ; j <(tama / size); j++,i+=10) VectorBLocal[j] = i;

Page 4: MemoriaSeminario1.pdf

Asignatura : Programación Paralela Autor : Rubén Perandrés Gómez

El for recorrerá cada una de las posiciones del vector de 0 hasta (tama/size), cada proceso inicializará el vector según su rank, calculando cuál es el número por el que empieza he incrementando 10 en cada iteración del bucle.

4. Modificar el programa solución del ejercicio 4.4 Comunicadores para que tambi´en se realice un Scatter de un vector de enteros desde el proceso 1 del comunicador global a todos los procesos impares de dicho comunicador. Los valores de este vector se escogen arbitrariamente en el proceso 0 (ojo, en el proceso con rango 0 del comunicador de rangos impares que es el proceso 1 de MPI Comm World), pero su tamaño debe ser igual número de procesos impares en el comunicador global. El reparto asignar´a un elemento de dicho vector a cada proceso impar del comunicador global. Se recomienda usar el comunicador de impares para realizar esta tarea.

if (color==1) // Sólo para los impares vector<int> Vector; if(rank_nuevo == 0) for(int i = 1 ; i <= size_nuevo ; i++) Vector.push_back(i*100); MPI_Scatter(&Vector[0], // Valores a compartir 1, // Cantidad que se envia a cada proceso MPI_INT, // Tipo del dato que se enviara &valor_impares, // Variable donde recibir los datos 1, // Cantidad que recibe cada proceso MPI_INT, // Tipo del dato que se recibira 0, // proceso principal que reparte los datos comm);

Queremos que la repartición mediante el scatter se realice sólo entre procesos impares, esto lo controlamos con el if principal (if (color==1)) el color sera 1 cuando el rank de un proceso sea impar, el proceso 0 del comunicador de impares (rank_nuevo = 0 ó rank =1) inicializa el vector (tamaño = size_nuevo que es el número de procesos del comunicador de procesos impares) a repartir y seguidamente todos los procesos invocan la llamada de scatter sobre el

Page 5: MemoriaSeminario1.pdf

Asignatura : Programación Paralela Autor : Rubén Perandrés Gómez

comunicador de impares comm ya que solo lo invocan procesos impares, cada proceso recibe 1 dato MPI_INT y lo guarda en valor_impares, el proceso raíz es el proceso 1 del comunicador global ó o del comunicador de impares y envía un elemento tipo MPI_INT a cada proceso del vector Vector