Вы находитесь на странице: 1из 6

Prctica 1

Implementacin distribuida de un
algoritmo paralelo de datos usando MPI
En esta prctica se aborda la implementacin paralela del algoritmo de Floyd para el clculo
de todos los caminos ms cortos en un grafo etiquetado. Se desarrollarn dos versiones paralelas
del algoritmo que dieren en el enfoque seguido para distribuir los datos entre los procesos. Por
simplicidad, se asume que las etiquetas de las aristas del Grafo de entrada son nmeros enteros.
Los objetivos de esta prctica son:
Comprender la importancia de la distribucin de los datos en la resolucin paralela de un
problema.
Adquirir experiencia en el uso de las funciones y mecanismos de la interfaz de paso de
mensajes al abordar la paralelizacin de un problema de anlisis de grafos.

1.1. Problema de los caminos ms cortos


Sea un grafo etiquetado G = (V, E, long), donde:
V = {vi } es un conjunto de N vrtices (kV k = N ).
E V V es un conjunto de aristas que conectan vrtices de V .
long : E Z es una funcin que asigna una etiqueta entera a cada arista de E .

Podemos representar un grafo mediante una matriz de adyacencia A tal que:


Ai,j

Si i = j
0
long(vi , vj ) Si (vi , vj ) E
=

En otro caso

En base a esta representacin, podemos denir los siguientes conceptos:

Camino desde un vrtice vi hasta un vrtice vj : secuencia de aristas (vi, vk ), (vk , vl ), . . . , (vm, vj )
donde ningn vrtice aparece ms de una vez.

Camino ms corto entre dos vrtices vi y vj : camino entre dicho par de vrtices cuya suma

de las etiquetas de sus aristas es la menor.

Problema del Camino ms corto sencillo: consiste en encontrar el camino ms corto


desde un nico vrtice a todos los dems vrtices del grafo.

Problema de todos los caminos ms cortos: consiste en encontrar los camino ms corto
desde todos los pares de vrtices del grafo.
El Algoritmo para calcular todos los caminos ms cortos toma como entrada la matriz de
incidencia del Grafo A y calcula una matriz S de tamao N N donde Si,j es la longitud
del camino ms corto desde vi a vj , o un valor si no hay camino entre dichos vrtices.

1.2. Algoritmo de Floyd


El algoritmo de Floyd deriva la matriz S en N pasos, construyendo en cada paso k una matriz
intermedia I(k) con el camino ms corto conocido entre cada par de nodos. Inicialmente:
0
Ii,j
= Aij .

El k-simo paso del algoritmo considera cada Iij y determina si el camino ms corto conocido
desde vi a vj es mayor que las longitudes combinadas de los caminos desde vi a vk y desde vk a
vj , en cuyo caso se actualizar la entrada Iij . La operacin de comparacin se realiza un total de
N 3 veces, por lo que aproximamos el coste secuencial del algoritmo como tc N 3 siendo tc el coste
de una operacin de comparacin.
procedure floyd secuencial
begin
Ii,j = A
for k := 0 to N-1
for i := 0 to N-1
for j := 0 to N-1
k+1
k , Ik + Ik }
Ii,j
= min{Ii,j
k,j
i,k
end;

1.3. Algoritmo de Floyd Paralelo 1. Descomposicin unidimensional


(por bloques de las)
Asumimos que el nmero de vrtices N es mltiplo del nmero de procesos P .
En esta versin, las las de la matriz I se distribuyen entre los procesos por bloques contiguos
de las, por lo que cada proceso almacena N/P las de I y de la matriz de salida S .
Se podrn utilizar hasta N procesos como mximo. Cada proceso es responsable de una o ms
las adyacentes de I y ejecutar el siguiente algoritmo:
procedure floyd paralelo 1
begin
Ii,j = A
for k := 0 to N-1
for i := local_i_start to local_i_start
for j := 0 to N-1
k+1
k , Ik + Ik }
Ii,j
= min{Ii,j
i,k
k,j

end;

En la iteracin k, cada proceso, adems de sus datos locales, necesita los valores Ik,0 , Ik,1 , . . . , Ik,N 1 ,,
es decir, la la k de I (vase gura 1.1). Por ello, el proceso que tenga asignada dicha la k debe
difundirla a todos los dems procesos (usando MPI_Bcast).

(a) Datos asignados a cada proceso

(b) Datos requeridos por un proceso en la etapa

Figura 1.1: Distribucin 1D de la matriz I entre 4 procesos


Para distribuir la matriz A entre los procesos basta con utilizar la operacin colectiva MPI_Scatter.

1.4. Algoritmo de Floyd Paralelo 2. Descomposicin bidimensional


(por bloques 2D)
Por simplicidad, se asume que el nmero de vrtices N es mltiplo de la raz del nmero de
procesos P .
Esta versin del algoritmo de Floyd utiliza una distribucin por bloques bidimensionales de
la matriz I , pudiendo utilizar hasta N 2 procesos. Suponemos que los procesos se organizan lgicamente como una malla cuadrada con sqrtP procesos en cada la y sqrtP procesos en cada
columna.

Cada proceso trabaja


con
un
bloque
de
N/
P sublas alineadas (cubren las mismas columnas

contiguas) con N/ P elementos cada uno (vase gura 1.2) y ejecuta el siguiente algoritmo:
procedure floyd paralelo 2
begin
Ii,j = A
for k := 0 to N-1
for i := local_i_start to local_i_end
for j := local_j _start to local_j _end
k+1
k , Ik + Ik }
Ii,j
= min{Ii,j
i,k
k,j
end;

En cada paso, adems de los datos locales, cada proceso necesita N/ P valores de dos procesos localizados en la misma la y columna respectivamente (vase gura 1.2). Por tanto, los
requerimientos de comunicacin en la etapa k son dos operaciones de broadcast:
3

Desde el proceso en cada la (de la malla de procesos) que contiene parte de la columna k
al resto de procesos en dicha la.
Desde el proceso en cada columna (de la malla de procesos) que contiene parte de la la k
al resto de procesos en dicha columna.

En cada uno de los N pasos, N/ P valores deben difundirse a los P procesos en cada la y
en cada columna d ela malla de procesos. Ntese que cada proceso debe servir de origen (root)
para al menos un broadcast a cada proceso en la misma la y a cada proceso en la misma columna
del malla lgica 2D de procesos.

(a) Datos asignados a cada proceso

(b) Datos requeridos por un proceso en la etapa

Figura 1.2: Distribucin 2D de la matriz I entre 16 procesos

Cada uno de los P procesosalmacena una submatriz de I de tamao N/ P N/ P (por


simplicidad, supondremos que P divide a N ).
Inicialmente
el proceso

P0 contiene la matriz completa, y a cada proceso le correspondern


N/ P elementos de N/ P las de dicha matriz.
Para permitir que la matriz I pueda ser repartida con una operacin colectiva entre los procesos,
podemos denir un tipo de datos para especicar submatrices. Para ello, es necesario considerar
que los elementos de una matriz bidimensional se almacenan en posiciones consecutivas de memoria
por orden de la, en primer
de columna en segundo lugar. As cada submatriz
lugar, y por orden
ser un conjunto de N/ P bloques de N/ P elementos cada uno, con un desplazamiento de N
elementos entre cada bloque.
La funcin MPI_Type_vector permite asociar una submatriz cuadrada de una matriz como un
tipo de datos de MPI. De esta manera, el proceso P0 podr enviar bloques no contiguos de datos
a los dems procesos en un solo mensaje. Tambin es necesario calcular, para cada proceso, la
posicin de comienzo de la submatriz que le corresponde.
Para poder alojar de forma contigua y ordenada los elementos del nuevo tipo creado (las submatrices cuadradas), con objeto de poder repartirlos con MPI_Scatter entre los procesos, podemos
utilizar la funcin MPI_Pack. Utilizando esta funcin, se empaquetan las submatrices de forma
4

consecutiva, de tal forma que al repartirlas (usando el tipo MPI_PACKED, se le asigna una submatriz cuadrada a cada proceso. A continuacin, se muestra la secuencia de operaciones necesarias
para empaquetar todos los bloques de una matriz N N de forma ordenada y repartirlos con un
MPI_Scatter entre los procesos:
MPI_Datatype MPI_BLOQUE;
......
......
raiz_P=sqrt(P);
tam=N/raiz_P;
/*Creo buffer de envo para almacenar los datos empaquetados*/
buf_envio=reservar_vector(N*N);
if (rank==0)
{
/* Obtiene matriz local a repartir*/
Inicializa_matriz(N,N,matriz_I);
/*Defino el tipo bloque cuadrado */
MPI_Type_vector (tam, tam, N, MPI_INT, &MPI_BLOQUE);
/* Creo el nuevo tipo */
MPI_Type_commit (&MPI_BLOQUE);
/* Empaqueta bloque a bloque en el buffer de envo*/
for (i=0, posicion=0; i<size; i++)
{
/* Calculo la posicion de comienzo de cada submatriz */
fila_P=i/raiz_P;
columna_P=i%raiz_P;
comienzo=(columna_P*tam)+(fila_P*tam*tam*raiz_P);
MPI_Pack (matriz_I(comienzo), 1, MPI_BLOQUE,
buf_envio,sizeof(int)*N*N, &posicion, MPI_COMM_WORLD);
}

/*Destruye la matriz local*/


free(matriz_I);
/* Libero el tipo bloque*/
MPI_Type_free (&MPI_BLOQUE);

/*Creo un buffer de recepcion*/


buf_recep=reservar_vector(tam*tam);
/* Distribuimos la matriz entre los procesos */
MPI_Scatter (buf_envio, sizeof(int)*tam*tam, MPI_PACKED,
buf_recep, tam*tam, MPI_INT, 0, MPI_COMM_WORLD);

Para obtener la matriz resultado en el proceso P0 se utiliza la funcin MPI_Gather seguida de

MPI_Unpack

1.5. Ejercicios propuestos.


1. Implementar los algoritmos de clculo de todos los caminos ms cortos que han sido descritos previamente. Se proporcionar en la web de documentacin de la asignatura una
versin secuencial en C++ del algoritmo de Floyd, que se puede utilizar como plantilla para
programar los diferentes algoritmos paralelos. Se aconseja realizar cambios sobre la clase
Graph, que encapsula la gestin del grafo etiquetado, para implementar todas las operaciones de comunicacin dentro de dicha clase. Por tanto, la nueva clase Graph encapsulara
toda la funcionalidad asociada a la gestin de la matriz de incidencia distribuida entre los
procesos (por bloques de las en el caso 1D o por bloques cuadrados en el caso 2D). En la
carpeta input, se encuentran varios archivos de descripcin de grafos que se pueden utilizar
como entradas del programa. Tambin se proporciona un programa (creaejemplo.cpp) para
crear archivos de entrada pasando como argumento el nmero de vrtices del Grafo. Este
programa permnitir realizr pruebas con grafos de diferentes nmeros de vrtices (600, 800,
1000, 1200, etc.).
Se debe crear una carpeta diferente para cada versin paralela (Floyd-1 y Floyd-2). Cada
carpeta mantendr los mismos archivos que se usan en la versin secuencial pero con diferente
cdigo. De esa forma el Makefile se puede reutilizar y se percibe claramente la diferencia
entre las versiones secuencial y paralela.
2. Realizar medidas de tiempo de ejecucin sobre los algoritmos implementados. Para medir
tiempos de ejecucin, podemos utilizar la funcin MPI_Wtime. Para asegurarnos de que todos
los procesos comienzan su computacin al mismo tiempo podemos utilizar MPI_Barrier. Las
medidas debern excluir las fases de e/s. Debern realizarse las siguientes medidas:
a ) Medidas para el algoritmo secuencial (P = 1).
b ) Medidas para el algoritmo paralelo (P = 4). Para los algoritmos de multiplicacin

matriz-vector, las medidas debern excluir las fases de entrada/salida, as como la fase
de distribucin inicial de la matriz A desde el proceso P0 y la fase de reunin de la
matriz resultado en P0 .
Las medidas debern realizarse para diferentes tamaos de problema, para as poder
comprobar el efecto de la granularidad sobre el rendimiento de los algoritmos.
Se presentar una tabla con el siguiente formato:

Tiempo

P = 1 (secuencial)

P =4

Ganancia

n = 60
n = 240
n = ...
n = 1200

La ganancia en velocidad se calcula dividiendo el tiempo de ejecucin del algoritmo


secuencial entre el tiempo de ejecucin del algoritmo paralelo.

Вам также может понравиться