Está en la página 1de 21

Programaci

on Paralela: LU Decomposition usando la


biblioteca de funciones PVM
Raymundo Domnguez Coln

Centro de Investigaci
on y de Estudios Avanzados del IPN
Av. Instituto Politecnico Nacional No. 2508 Col. San Pedro Zacatenco.
Mexico D.F, 07360. Tel.(+52 55) 5061 38000 ext: 3758 y 3756

En este documento se presenta una descripci


on de la versi
on paralela de la Factorizaci
on LU utilizando los m
odulos de la m
aquina virtual PVM. Se d
a una breve descripci
on del funcionamiento de
las rutinas utilizadas y se describe el modelo maestro-escalvo utilizado en esta versi
on, que es diferente
a las entregas anteriores. Se describe el algoritmo utilizado, pruebas, comprobaci
on de resultados y
gr
aficas de rendimiento en las que se muestra que es f
actible realizar paralelismo en algunos segmentos del c
odigo que permiten aumentar su rendimiento y aprovechar la potencia del funcionamiento de
m
ultiples procesadores trabajando al mimso tiempo.
1. Introducci
on

En este documento se presenta una manera de aplicar paralelismo a la Factorizaci


on LU, utilizando
rutinas propias de la biblioteca PVM (Parallel Virtual Machine). Basicamente La Factorizaci
on
LU de una matriz cuadrada A, es la descomposicion de esta en el producto de una matriz diagonal
inferior unitaria L y una matriz superior U . Se considero el metodo de la factorizacion LU por ser
uno de los m
as directos y el que se presta mejor para la paralelizacion debido a la independencia de
los ciclos internos. Este metodo modifica la matriz de entrada Ann realizando substituciones con el
complemento Schur con respecto a la posicion a11 de A. La version paralela fue implementada
usando las rutinas de la biblioteca PVM basaandose en el modelo de comunicacion maestro-esclavo.

Qu
e es c
omputo paralelo?

El computo paralelo consiste en un conjunto de procesos (o procesadores) que trabajan juntos en


la soluci
on de un problema computacional. Este tipo especial de computo comienza a tomar gran
fuerza debido a que la velocidad de los procesadores sencillos ya no puede mejorar, incluso la Ley de
Moore fue rota en 2007 debido a que aumento el consumo de energa de los procesadores [1]. De esa
manera, el desempe
no llegar
a usando m
ultiples procesadores.

PVM

PVM es un software que permite una colleccion heterogenes de computadores Linux y/o Windows
trabajar juntas a traves de una red que act
ua como una gran computadora sencila. De esta manera,
muchos problemas de c
omputo pueden ser resueltos de manera efectiva usando el poder y la memoria
de muchas computadoras. Tiene la ventaja de que es un software portable y de que el codigo es de
libre distribuci
on y que ha sido compilado en todos lados, desde laptops hasta CRAYs []. PVM
permite a los usuarios explotar el hardware existente en sus computadoras para resolver problemas
* Email:

radominguez@cs.cinvestav.mx
n Paralela, Factorizaci
Programacio
on LU

Raymundo Domnguez Coln

grandes con un mnimo cosoto adicional.


Para el dise
no de esta versi
on de la factorizacion LU se uso el modelo maesteo-esclavo que, a diferencia
de las versiones anteriore, en esta ocasion el proceso maestro participa de manera activa tanto en
la distribuci
on de trabajo como en la comunicacion con los procesos esclavos en cada una de la
iteraciones del programa. Todos los procesos tienen su propio bloque de instrucciones y datos, los
procesan y se comunican con el maestro mediante el paso de mensajes logrando de esta manera
modificar, a partir de los datos propios, un mismo bloque de memoria.
En este documento se describe la manera en la que se implemento una version paralela para el
problema de la Factorizaci
on LU, el algoritmo empleado, las graficas de desempe
no de aceleracion
respecto a la versi
on secuencial.

2. Descripci
on del problema: Paralelizaci
on de la Factorizaci
on LU

La Factorizaci
on LU es uno de los principios basicos del algebra lneal y es usada principalmente
para solucionar sistemas de ecuaciones lineales de la forma Ax = b [2] siendo A una matriz no
singular y tambien para calcular el determinante. Aunque es posible resolver estos sistemas usando
la inversa de A, es decir, x = A1 , casi nunca es una buena idea debido principalmente a razones
de eficiencia y en lugar de eso, la factorizacion de A de la forma A = LU donde L y U son matrices
superiores (U solo tiene ceros por encima de la diagonal) e inferiores (L solo tiene ceros debajo de la
diagonal) respectivamente, es m
as eficiente.
A manera de ejemplo, una matriz A33 , se puede factorizar como:

l11
A = LU l21
l31

0
l22
l32


0
u11
0 0
l33
0

u12
u22
0


u13
a11
u23 = a21
u33
a31

a12
a22
a32

a13
a23
a33

Una factorizaci
on LDU es una factorizacion de la forma:
A = LDU
donde D es una matriz diagonal y L y U son matrices triangulares unitarias, lo que significa que
todas las entradas en la diagonal de L y U son 1. Una factorizacion LU P es de la forma
AP = LU
donde L y U son de nuevo matrices inferior y superior y P es una matriz permutaci
on, es decir, una
matriz de ceros y unos que tiene exactamente un 1 en cada fila y columna.
El problema consiste en a partir de un algoritmo secuencial, lograr modificarlo de alguna manera en
algunas de sus partes m
as significativas de modo que las tareas y los datos puedan ser distribuidos en
diferentes procesos que esten comunicados y sincronizados entre si, de tal modo que las operaciones
que realizen no se traslapen o haya corrupcion de datos.

n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

Algoritmo secuencial

El algoritmo secuencial produce una matriz triangular superior U y una matriz triangular unitaria
inferior L. Para facilitar la posterior paralelizacion, se realizaron una serie de modificaciones a este
algoritmo (Doolitle).Debido a que la matriz U tiene solo 0s debajo de la diagonal y debido a que
no se verifican ni modifican esas entradas, el codigo no las modifica; por otro lado, debido a que la
matriz de salida L tiene solo 1s debajo de su respectiva diagonal y 0s sobre la misma, tampoco se
tocan esas entradas. As, el algoritmo 1 computa solo las entradas mas significantes de las matrices
L y U.
Algoritmo 1 Algoritmo secuencial para encontrar la factorizacion LU
Requiere: A
for k 1 to n do
ukk akk
for i k + 1 to n do
lik aik /ukk
uki aki
end for
for i k + 1 to n do
for j k to n do
aij aij lik ukj
end for
end for
end for
return L and U

3. Descripci
on del algoritmo paralelo

El problema principal al momento de dise


nar un algoritmo paralelo consiste en responder a las
preguntas C
omo distribuir los datos?, y cuales datos?. Desde luego que los datos que interesan
son los de la matriz A; la distribuci
on que se haga de estos sumado a una modificacion eficiente del
algoritmo secuencial y a la sincronizacion entre los procesos involucrados, nos daran un programa que
despues de ciertas iteraciones debe superar al algoritmo secuencial, aunque esto no siempre sucede.
La distribuci
on de datos de la matriz A se consigue analizando detenidamente el algoritmo secuencial
mostrado anteriormente (algoritmo 1). La mayor parte del trabajo el este algoritmo secuencial es la
actualizaci
on:
aij := aij aik akj
para el elemento aij de la matriz con i, j, k + 1. As que si distribuimos estos valores aij , aik y akj a
diferentes procesos, se puede actualizar la matriz considerando solo estos elementos, Esto es porque
la actualizaci
on de una fila i se realiza con pocos elementos, es decir solo aik , akj son usados para esta
actualizaci
on y vienen de la columna k o de la fila k de la matriz. As que un hilo puede computar
el nuevo valor de ai j usando la comunicacion entre los valores aik , akj tal como se veen la figura 1.

n Paralela, Factorizaci
Programacio
on LU

Raymundo Domnguez Coln

Figura 1. Se muestra que la fila aij se actualiza con la comunicaci


on de los valores aik , akj

Esquemas de particionamiento

Debido a las especificaciones de PVM, cada procesador tendra sus propios datos, en este caso sera
la matriz A que debe factorizarse. La distribucion de los datos para cada procesador se realiza de la
siguiente manera: las filas de la matriz se van a distribuir entre el n
umero de procesadores que se
vayan a ejecutar, esto es que como tanto el tama
no del problema como el n
umero de procesadores
son din
amicos, se repartir
an tambien dinamicamente. En la figura 2 se muestra la manera en la que
se dividen los datos de la matriz A siendo esta una matriz cuadrada de n n.

Figura 2. Se muestra la segmentaci


on de la matriz A

El vector v es un vector columna de tama


no n 1, wT es un vector fila tambien de tama
no n 1 y A0
0
T
es una submatriz de (n 1) (n 1). El elemento A vw /aa11 es lo que se le llama Complemento
Schur [3] de A con respecto a a11 . Entonces como puede verse que se requieren a lo mas n 1
procesos para que a cada uno le corresponda una fila de la matriz A0 . Esta distribucion se realiza
dividiendo el valor de n 1 entre el n
umero de procesadores -1 tambien, de tal modo que que haya
una correspondencia equivalente entre todos los procesadores, es decir que si tenemos una matriz de
tama
no n = 100 y se ejecutar
a con P = 3 procesos, tenemos que a cada proceso le tocan Pn1
1 filas
para modificar.

n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

Figura 3. Se muestra la distribuci


on de las filas a cada uno de los procesadores

Ahora bien, si se observa bien la forma en la que trabaja el algoritmo, puede apreciarse que hay mas
iteraciones en la parte baja de la matriz que en la parte alta, por lo tanto la distribucion de las filas
entre los procesos no debe ser de filas contiguas pues se cae en un caso llamado mapeo bloqueante. El
problema con este tipo de mapeo es que es una gran carga desbalanceada y provoca muchos tiempos
muertos de los procesos que ya han terminado de procesar las filas que les corresponden. La solucion
a esta carga desbalanceada es el llamado mapeo cclico.
El mapeo cclico divide la filas de la matriz entre n/P (P es el n
umero de procesadores) secciones, y
entonces le asigna a cada procesador una fila de cada seccion. De esta manera se mejora el problema
de la carga desvalanceada. Por ejemplo, suponga a la matriz A de 16 16, y tenemos 4 procesadores
(P = 4), la tabla 1 lista las filas que le son dadas a cada procesador.

Mapeo Bloqueante
Mapeo Cclico

P0
0, 1,, 2, 3
0, 4, 8, 12

P1
4, 5, 6, 7
1, 5, 9, 13

P2
8, 9, 10, 11
2, 6, 10, 14

P3
12, 13, 14, 15
3, 7, 11, 15

Cuadro 1. Ejemplo de mapeos bloqueante y cclico

Comunicaci
on

Se implementaron dos diferentes tipos de comunicaciones entre los procesadores. Todas usando la
instrucci
on pvm send() de PVM pero enviando diferentes tipos de datos, un tipo eran enteros simples
y los otros eran buffers de datos de tipo float. Los enteros son mas que nada el tama
no del problema,
ndices que hay que comparar con datos localesde cada procesador entre otros. Para el caso de los
buffer, cuando un procesador ha completada las operaciones sobre las filas que le corresponden,
empaqueta sus datos y los envia al maestro quien, actualiza la matriz de trabajo y vuelve a enviar
las filas a los procesadores. Esto significa que todos los procesadores deben esperar hasta que reciben
sus datos.

Modelo maestro-esclavo

Basicamente, el algoritmo empleado en esta version utiliza una version mejorada del modelo maestroesclavo que se manej
o en las versiones anteriores. Se define un procesador que fungira como maestro
y sera este el que se encargue de repartir el trabajo a los otros procesadores. Ademas de esto, en cada
iteracion este proceso maestro recibe las filas ya procesadas por los demas, actualiza la matriz y vuelve
a enviar las filas para la siguiente iteracion. El algoritmo 2 define el pseudocodigo de instrucciones
que maneja el proceso padre y el siguiente algoritmo define lo realizado por cada uno de los otros
procesos.
n Paralela, Factorizaci
Programacio
on LU

Raymundo Domnguez Coln

Algoritmo 2 Bloque de instrucciones del padre


Requiere: a, n, buf f er
//otros procesos (llenado de matriz, declaraci
on de variables, etc)
if myrank == 0 then
for k 0 to n 1 do
for h 1 to numprocesos do
buf f er f ilapivote(a)// a partir de buffer[0] asigna la fila pivote
buf f er asignaf ilas()// ahora le asignamos la filas que le toca procesar al proceso h
pvm initsend();
pvm send(k)//enva el valor de k; es necesario para los procesos hijos
pvm sed(buffer, h)// enva el buffer al proceso h
end for
// recepcion de filas ya procesadas por los procesos
for i 1 to numproc 1 do
pvmrecv(recvbuf f er, i)// recibe buffer de hijo i
actualizaM atriz(recvbuf f er, a)// actualiza las filas de a con la info del buffer
end for
end for//for de k
else
for iter 0 to n 1 do
//trabajo de los hijos
pcm recv(k 0 , SOU RCE) //recibiendo ndice k y almacenando en k
pcm recv(recvbuf f, SOU RCE) //recibiendo el buffer
subA creaSubM atriz();
cont 1
for i 1 to numT areasHijo[myrank] do
if indiceTarea[cont] k then
// no se debe de tocar la fila pivote k
subAi,k0 subAi,k0 /subAk0 ,k0
for j k 0 + 1 to n do
subAi,j subAi,j subAi,k0 subAk0 ,k0
end for
end if
cont cont + 1
end for
buf f er llenaBuf f er()
pvm initsend(buffer, SOURCE); //enviando el buffer modificado al padre
end for
end if

Mecanismos de coordinaci
on y sincronizaci
on entre procesos

Cada proceso recibe solamente una copia de las filas que le tocan procesar de acuerdo al mapeo cclico
y realizar
a las operaciones s
olo en estas filas. Ademas del trabajo asignado, cada procesador recibe
una copia de la fila pivote, que no es mas que la fila de la matriz principal cuyo ndice es el valor
de k. En cada iteraci
on, los procesos deben conocer las modificaciones realizadas por cada uno de
los otros procesos, as que existe una comunicacion triangular entre ellos en los que se intercambian
la informaci
on de las filas procesadas por cada uno mediante las rutinas PVM de paso de mensajes.
Cada uno de los procesadores empaqueta los datos de sus filas en un buffer y los enva al maestro que
los recibe y los vuelve a enviar para la siguiente iteracion. Entonces a cada proceso le corresponde
una o m
as filas de la matriz, que va a actualizar de manera paralela a los otros procesos como se ve
en la figura 3. En la figura 4 se muestra un esquema del mecanismo de funcionamiento del programa.
n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

Figura 4. Esquema de procesamiento y comunicaci


on de los procesos

4. Resultados
a) Ejemplo(s) y verificaci
on de resultados. A manera de ejemplo, desarrollemos la siguiente
matriz A con la ayuda de 2 procesos de ejecuci
on:

06
BB3
BB1
@4
2

3
9
2
5
1

1
2
2
6
1

4
5
6
1
6

2
1
1
6
7

1
CC
CC
A

El primer paso es dividir el trabajo a cada uno de los procesos. En este caso tenemos un valor de n = 5
y n
umero de procesos p = 3, pero de acuerdo al algoritmo, solo necesitaremos procesar a lo m
as n 1
filas y utilizaremos p 1 procesos debido a que tenemos un proceso maestro. Este proceso hace la
funci
on de un orquestador que inicializa el tama
no de la matriz, reparte el trabajo entre los procesos
y espera los resultados para actualizar la matriz y repetir la operaci
on. El proceso de envo consiste
en preparar un buffer de tama
no n + (n numf ilas); donde n es el tama
no de la matriz y numf ilas
son las filas que le toca a cada proceso. En este caso son dos. Este buffer se llena primero con la fila
pivote y despues con las filas que le corresponden a cada proceso. Por ejemplo, el primer buffer para el
proceso con rank = 1 quedara as: buffer = {6, 3, 1, 4, 2, 3, 9, 2, 5, 1, 4, 5, 6, 1, 6}, que corresponden
a la fila 0, 1 y 3 de la matriz.
Los procesos reciben cada quien su buffer y crean una submatriz de dos dimensiones para poder realizar
n Paralela, Factorizaci
Programacio
on LU

Raymundo Domnguez Coln

las operaciones propias del algoritmo m


as facilmente. Como en este caso son dos procesos, se le asigna
dos filas a cada uno quedando el proceso 1 con las filas 1 y 3, mientras que el proceso 2 se queda con las
filas 2 y 4. Cada hilo actualizar
a sus filas en cada iteraci
on y luego enva esas filas que ha modificado al
proceso maestro. Esta es una fase de sincronizaci
on, es decir, el envo de las filas es bloqueante pues un
proceso no puede continuar hasta que el maestro le enve m
as trabajo, as que si el proceso 1 termina
primero, tendr
a que esperar a que el otro termine.
De acuerdo al algoritmo 2, el valor k 0 nos indica cu
al sera nuestro elemento a11 , el vector v, el vector
wT y la matriz A0 . La fila k 0 = 0 la llamaremos pivote y no se alterar
a durante la actualizaci
on de las
dem
as filas, de hecho, las n 1 filas se actualizan a partir de esta y del elemento aij correspondiente.
Entonces con k 0 = 0 e i = primerf ila del proceso en cuesti
on, si el proceso tiene rank = 1, entonces
i = 1, pues es la primer fila que le corresponde procesar. As que para el proceso 1, el elemento aik0 = 3
se divide con ak0 k0 = 6, mientras que para el proceso 2 los valores son aik0 = 1, pues la primer fila a
procesar de este proceso es la 2, y el ak0 k0 = 6 tambien; se inicializa el valor de j = k 0 + 1 = 1, y se entra
en el primer ciclo de ejecuci
on en el que se actualizar
an todos los valores de la fila i con el incremente
de j hasta n. La matriz A se va modificando con:
aij = aij aik0 a0j
As que despues de este primer ciclo, i primera iteraci
on, estas dos filas modificadas por ambos procesos
deben ser conocidas por el otro, entonces cada proceso prepara un buffer de envo con la informaci
on
de sus dos filas procesadas (la fila pivote no es necesario que la conozca el proceso maestro); el maestro
recibe los paquetes de los procesos y realiza una actualizaci
on de la matriz con estas nuevas filas y se
repite la operaci
on hasta que se cumple las condiciones del ciclo.
Por ejemplo, en esta primera iteraci
on, cuando el proceso padre recibe el paquete del proceso 1, la
matriz queda con los siguientes valores:

06
BB 0,5
BB 1
@0,67
2

0
7,5
2
2,99
1

6
1,5
2
5,33
1

2
3
6
1,68
6

1
CC
CC
A

9
0
1
4,66
7

As que solo resta esperar las filas 2 y 4 (ya procesadas) que del proceso 2. As que al final de la primera
iteraci
on, la matriz queda as:

06
BB 0,5
BB0,16
@0,67
0,33

3
7,5
1,52
2,99
0,01

1
1,5
1,84
5,33
0,67

4
3
5,36
1,68
4,68

1
CC
CC
A

2
0
0,68
4,66
6,34

Entonces el proceso padre ya tiene lo que necesita para envar de nuevo las filas a cada proceso con
los nuevos valores. Ahora con el incremento de k, se vuelve a repetir la operaci
on, solo que ahora el
proceso 1 ya no ejecuta sus dos filas sino solo una, la fila 3, esto es porque en la siguiente iteraci
on
la fila 1 se ha comvertido en fila pivote y no require de modificaci
on alguna por lo que esperar
a hasta
que todos los dem
as procesadores terminen para poder ser liberado. En cambio el hilo 2 a
un le quedan
algunas iteraciones m
as que realizar. Al terminar todos los procesos su ejecuci
on, nos queda la matriz
resultado siguiente:

06
BB 0,5
BB0,17
@0,67
0,33

n Paralela, Factorizaci
Programacio
on LU

3
7,5
0,2
0,4
0,0

1
1,5
1,53
3,09
0,43

4
3
4,73
17,48
0,15

1
CC
CC
A

2
0
0,67
2,61
6,43

Factorizaci
on LU usando rutinas de PVM

Esta matriz se divide para obtener finalmente las matrices L y U buscadas y se muestran como sigue:

01
B
B0,50
0,17
L=B
B
@0,67
0,33

0
1
0,20
0,40
0,00

0
0
1
3,09
0,43

0
0
0
1
0,15

1
CC
CC
A

0
0
0 U =
0
1

06,00
BB 0
BB 0
@0
0

3,00
7,50
0
0
0

1,00
1,50
1,53
0
0

4,00
3,00
4,73
17,48
0

1 06
CC BB3
CC = BB1
A @4

2,00
0,00
0,67
2,61
6,43

3
9
2
5
1

1
2
2
6
1

4
5
6
1
6

La salida del programa nos muestra (por razones de legibilidad) solo la matriz inicial y la matriz final
resultante. Si el tama
no de la matriz es mayor a 15, el programa imprime solo el tiempo de ejecuci
on
que tard
o el programa en realizar la ejecuci
on.

Figura 5. Salida del programa.

b) Gr
afica de tiempos de ejecuci
on vs. N
umero de procesadores PVM

# Procesos
1
2
4
6
7

n100
0.38
0.18
0.48
0.06
0.05

n200
0.44
0.36
0.38
0.38
0.35

n500
6.73
6.66
6.72
6.89
5.72

n1000
40.32
55.13
58.34
50.01
59.13

Cuadro 2. Tabla de resultados

n Paralela, Factorizaci
Programacio
on LU

2
1
1
6
7

1
CC
CC
A

10

Raymundo Domnguez Coln

Figura 6. Matriz de 100 100 con diferentes proceso de ejecuci


on

Figura 7. Matriz de 200 200 con diferentes proceso de ejecuci


on

Figura 8. Matriz de 500 500 con diferentes proceso de ejecuci


on

n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

11

Figura 9. Matriz de 1000 1000 con diferentes proceso de ejecuci


on

c) An
alisis de complejidad del algoritmo con procesos PVM
Para este an
alisis, hay que tomar en cuenta adem
as del tiempo de c
omputo que toma el algoritmo, el
costo de comunicaci
on. Como el algoritmo hace uso de la eliminaci
on Gaussiana, esto le toma O(n3 )
operaciones. Asumiendo que cada operaci
on de punto flotante toma unidades de tiempo y que n es
suficientemente grande, el tiempo de c
omputo es T (1, n) = 23 n3 + costo de comunicaci
on.
La computaci
on y comunicaci
on en el desarrollo del algoritmo y paso de mensajes es lo que cuesta m
as
en esta versi
on paralela de la factorizaci
on LU. Con
d) Ajuste de curvas: expresi
on matem
atica
e) Gr
afica de aceleraci
on (tiempo secuencial/tiempo paralelo)

n Paralela, Factorizaci
Programacio
on LU

12

n Paralela, Factorizaci
Programacio
on LU

Raymundo Domnguez Coln

Factorizaci
on LU usando rutinas de PVM

13

5. Conclusiones

En este momento el tiempo de la version paralela ya esta muy cerca del tiempo de la version secuencial de PVM, sin embargo estamos ya muy cerca de lograrlo. La distribucion de datos que se
implement
o en est
a versi
on mejor
o en gran medida los tiempos vistos en las anteriores entregas. Se
esta considerando una manera de reducir la longitud de los buffers de comunicacion entre el proceso
maestro contra los otros procesos. Esto es porque a medida que aumenta el valor de k, hay columnas que ya no se modifican, entonces ya no es necesario envar el tama
no del buffer completo sino
solamente la parte que en realidad le va a servir al proceso receptor. De igual manera, los procesos
receptores reducir
an el tama
no del buffer de respuesta al maestro lo cual reducira tiempos de comunicaci
on y es posible que se supere los tiempo dados por la version secuencial. De hecho como
puede verse en las gr
aficas de aceleracion, ya lo hace en algunos casos pero comienza a dispararse
para valores de n = 1000.
Se pretende realizar estas modificaciones para la entrega final y aplicarlo tambien a la version de
MPI y threads.
5.0.1 Anexo: C
odigo del programa
1
2

/*
FActorizacion LU version PVM

3
4

*/

5
6
7

/* defines and prototypes for the PVM library */


#include "funciones.h"

8
9
10
11
12
13
14
15
16

int main(int argc, char* argv[]){


int i, j, blk, rec, numfil, residuo, valor, fila, band, inf;
int mult =0, indice;
int *tareas, *hilos;
float **array, *aux = NULL, *results = NULL;
int lista[MAXPROC][MAXTAREAS] = {0};
float *aux2 = NULL, *filas = NULL, **subA = NULL;//arreglos de los hijos
clock_t comienzo, final;

17

n Paralela, Factorizaci
Programacio
on LU

14

18
19
20
21
22

Raymundo Domnguez Coln

float promedio;
struct timeval tinicial, tfinal, tdiferencia;
struct timezone zone;
long
totalsec=0,totalmic=0;
long ajustesec=0,ajustemicro=0;

23
24

srand((unsigned int)time((time_t *)NULL));

25
26
27

/* find out my task id number */


mytid = pvm_mytid();

28
29
30
31
32

mygid = pvm_joingroup(GRUPO);
if (mygid < 0){
pvm_perror(argv[0]); pvm_exit(); return -1;
}

33
34

ntids = pvm_siblings(&tids);

35
36
37
38
39
40

for(i=0; i< ntids; i++){


if(tids[i] == mytid){
myrank = i;
break;
}

41
42

43
44
45
46
47
48
49
50
51
52

blk = atoi(argv[1]);
if( blk < ntids){
if(myrank ==0){
printf("Valores incorrectos\n ");
printf("1. El tamanio de la matriz debe ser mayor o
igual al numero de procesadores\n");
}
pvm_exit(); return -1;
}

53
54
55
56
57
58
59

if (myrank == 0){//maestro
totalsec=0;
totalmic=0;
ajustesec=0;
ajustemicro=0;

60
61
62
63
64
65

if(blk <=15)
band = 1;
else
band = 0;
//comienzo = clock();

66
67
68
69
70
71
72

//gettimeofday (&tinicial, &zone);


array = creaMatrizDoble(blk);
llenaMatrizDoble(array, blk);
if(band)
imprimeMatrixDoble(array, blk, blk);
//fflush(stdout);
n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

15

73
74
75
76
77

/* enviando el tamao de la matrix*/


pvm_initsend(PvmDataDefault);
pvm_pkint(&blk, 1, 1);
pvm_mcast(tids, ntids, TAG);

78
79
80
81

//reparticion de trabajo
numfil = (blk -1) / (ntids-1);
residuo = (blk-1) % (ntids-1);

82
83
84
85
86
87
88
89
90
91
92

fila = 1;
indice = 1;
for(i=1; i < ntids; i++){//inicia ciclo para repartir las tareas entre
if(residuo > 0){
//todos los hijos
valor = numfil +1;
residuo--;
}
else{
valor = numfil;
}

93

tareas = (int*) realloc ( tareas, sizeof(int) * (valor + 1) );


tareas[0] = valor;
//numero de tareas del hijo
lista[i-1][0] = valor;
for(j = 1; j<= valor; j++){
tareas[j] = fila;
lista[i-1][j] = fila;
fila += ntids-1;

94
95
96
97
98
99
100
101
102

103

//tareas[indice] = valor;
pvm_initsend(PvmDataDefault);//enviando el valor del vector de tareas
pvm_pkint(&valor, 1, 1);
pvm_send(tids[i], TAG);

104
105
106
107

pvm_initsend(PvmDataDefault);//enviando el vector de tareas para


pvm_pkint(tareas, (valor + 1), 1);//cada uno de los hijos
pvm_send(tids[i], TAREAS);

108
109
110
111

mult = mult + valor;


indice++;
fila = indice;

112
113
114
115

116
117
118
119
120
121
122
123
124

int k, hijo, pos, y, cont, row, p, res, formula, block;


float *aux = NULL, *results = NULL;
//clock_t comienzo = clock();
gettimeofday (&tinicial, &zone);
for(k=0; k< blk-1; k++){//bucle principal
for(hijo = 1; hijo < ntids; hijo++){//reparto de tareas
formula = blk + (blk * lista[hijo -1][0]);
// printf("hijo %d iteraciom %d tamanio de vector %d \n", hijo, k, formula);

125
126
127

aux = (float*) realloc ( aux, sizeof(float) * formula);


for(pos = 0; pos < blk; pos++)//llenando la fila pivote
n Paralela, Factorizaci
Programacio
on LU

16

Raymundo Domnguez Coln

aux[pos] = array[k][pos];//-->llenando con la fila pivote k


cont = 1;//-->para escoger la primera fila
for(j=0; j< lista[hijo-1][0]; j++){
row = lista[hijo-1][cont];
for(y=0; y< blk; y++, pos++)
aux[pos] = array[row][y];
cont++;
}

128
129
130
131
132
133
134
135
136

pvm_initsend(PvmDataDefault);//enviando el valor de k
pvm_pkint(&k, 1, 1);
pvm_send(tids[hijo], TAG);

137
138
139
140

pvm_initsend(PvmDataDefault);//enviando el buffer
pvm_pkfloat(aux, formula, 1);
pvm_send(tids[hijo], FILAS);

141
142
143
144

145
146
147
148
149
150
151

//recibiendo los resultados de los hijos!!


for(res = 1; res < ntids; res++){
block = blk * lista[res-1][0];//memoria para el buffer de recepcion
results = (float*) realloc ( results, sizeof(float) * block );
pvm_recv(tids[res], RESULTS);
pvm_upkfloat(results, block, 1);

152

//metiendo el buffer a la matriz original


cont=1;

153
154
155

for(p=0; p< lista[res-1][0]; p++ ){


row = lista[res-1][cont];
for(y=0; y < blk; y++){
array[row][y] = results[ p * blk + y ];
}
cont++;
printf("\n ");
}

156
157
158
159
160
161
162
163
164

165
166

} //end over bucle principal sobre k

167
168
169
170

}//end over if
else {//trabajo de los hijos
int res, n, tam, k2, size, cont, band, info, iter, virtualk, kill;

171
172
173

pvm_recv(tids[SOURCE], TAG);//recibe el tamao del problema


pvm_upkint(&n, 1, 1);

174
175
176

pvm_recv(tids[SOURCE], TAG);//tamao del vector de tareas


pvm_upkint(&tam, 1, 1);

177
178
179
180

hilos = (int*) realloc (hilos, sizeof(int) * tam + 1);


pvm_recv(tids[SOURCE], TAREAS);//# tareas de cada hilo y desgloce
pvm_upkint(hilos, tam + 1, 1);

181
182

for(iter =0; iter < n-1; iter ++){//ciclo de recepcion de los hijos
n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

17

pvm_recv(tids[SOURCE], TAG);//recibiendo el valor de la fila pivote k


pvm_upkint(&k2, 1, 1);

183
184
185
186
187

size = n + ( n * hilos[0]);//calculando el tamao del buffer de recepcion


aux2 = (float*) realloc ( aux2, sizeof(float) * size);//del hijo myrank

188
189
190

pvm_recv(tids[SOURCE], FILAS);
pvm_upkfloat(aux2, size, 1);

//recibiendo el buffer

191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

//printf("\nhijo %d creando submatriz iteracion %d \n", myrank, k2);


subA = creaSubMatriz( (hilos[0] + 1), n);
//
printf("\n\nhijo [%d] imprimo mis filas \n", myrank);
uneArregloMatriz(aux2, subA, hilos[0] + 1, n);
//imprimeMatrixDoble(subA, hilos[0] + 1, n);
cont=1;
//desarrollo de la elimincion gaussian
for(i=1; i< hilos[0]+1; i++ ){
if(hilos[cont] > k2){//evaluando si estamos en la columna
if( (subA[virtualk][k2] == 0 )){//|| ( subA[virtualk][k2] < 0.05 ) ){
printf("--- La matriz es singular. No tiene solucion --abortando programa..");
for(kill= 0; kill < ntids; kill++){
if(myrank != kill)
pvm_kill( tids[kill]);

206

}
pvm_exit();
return -1;

207
208
209
210
211
212
213
214

}
subA[i][k2] = subA[i][k2] / subA[virtualk][k2]; //pivote
for(j = k2 +1; j< n; j++)
subA[i][j] = subA[i][j] - subA[i][k2] * subA[virtualk][j];

215

}
cont++;

216
217
218

219
220
221
222
223

//reservando memoria
int pos = 0, tambuff;
tambuff = n * hilos[0];
filas = (float*) realloc ( filas, sizeof(float) * tambuff);

224
225

formaBuffer(filas, subA, hilos[0], n);

226
227
228
229
230

//enviando los resultados al padre


pvm_initsend(PvmDataDefault);
pvm_pkfloat(filas, tambuff, 1);//empaketando el buffer
pvm_send(tids[SOURCE], RESULTS);

231
232
233

}//end over for de iter


}//end over else

234
235
236
237

if(myrank == 0 && band ){


printf("---- RESULTADO------\n");
//imprimeMatrices(array, blk);
n Paralela, Factorizaci
Programacio
on LU

18

Raymundo Domnguez Coln

238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

if( pvm_barrier(GRUPO, ntids) == 0){


//final = clock();
gettimeofday (&tfinal, &zone);
if(myrank == 0){ //libearcion de memoria
//printf("El proceso ejecutado con %d procesadores duro %.8f segundos", ntids-1,
//(double)((final - comienzo)/(double) (CLOCKS_PER_SEC)) );
//fflush(stdout);
//gettimeofday (&tfinal, &zone);
tdiferencia=calcular_deltat (tinicial, tfinal);
totalsec=totalsec+tdiferencia.tv_sec;
totalmic=totalmic+tdiferencia.tv_usec;
ajustesec=totalmic/1000000;
ajustemicro=totalmic -(ajustesec*1000000);
promedio=(((totalsec*1000000)+totalmic) / blk * blk);
printf("El tiempo de procesamiento fue de %.4f microsegundos = %.4f segundos",
promedio,promedio/1000000);

257
258
259
260
261
262
263
264
265
266

freematrix(array, blk);
}
free(aux);
free(tareas);
free(results);
free(hilos);
free(aux2);
}
pvm_exit();

267
268
269

printf("its done!");
fflush(stdout);

270
271

return 0;

272
273
274
275
276
277

//**********************************************************************************
//biblioteca de funciones funciones.h
#include <pvm3.h> #include <stdio.h> #include <stdlib.h> #include <time.h>
//#include "funciones.h"
/* Maximum number of children this program will spawn */ #define MAXNTIDS
32 #define MAXROW

10

278
279

#define MAXPROC 32 #define MAXTAREAS 1000

280
281
282
283
284

/* Message tags */ #define SOURCE 0 #define TAG


5 //para transmitir un solo valor (int) #define ARRA
de matrices y arreglos (float) #define TAREAS 11 //transmicion de las tareas de cada proceso (int) #define
FILAS 20 #define RESULTS 21 #define GRUPO "pvmLU"

285
286

extern unsigned _floatconvert; #pragma extref _floatconvert

287
288

int *tids; int ntids; int mytid, mygid; //variables globales int myrank;

289
290

void imprimeMatrices(float **matriz, int tam){ int i,j;

291
292

printf("---------- Matriz L ------------\n");


n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

19

for(i=0; i< tam; i++){


for(j=0; j< tam; j++){
if(i==j)
printf(" 1 ");
else if(i>j)
printf(" %2.2f ", matriz[i][j]);
else
printf(" 0 ");
}
printf("\n ");

293
294
295
296
297
298
299
300
301
302
303

}
printf("---------- Matriz U ------------\n");
for(i=0; i< tam; i++){
for(j=0; j< tam; j++){
if(i>j)
printf(" 0 ");
else
printf(" %2.2f ", matriz[i][j]);
}
printf("\n ");
}

304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321

void uneArregloMatriz(float *aux, float **matA, int subtam, int tam){ int i,j, desp;
for(i=0; i< subtam; i++)
for(j=0; j< tam; j++)
matA[i][j] = aux[i * tam + j];
}

322
323
324
325
326
327
328
329

float ** creaSubMatriz(int subtam, int tam){ float **m; int i;


m = (float**) malloc (sizeof(float*) * subtam );
for(i = 0; i< subtam; i++){
m[i] = (float*) malloc (sizeof(float) * tam);
//
printf("reservando...\n");
}
return m; }

330
331
332
333
334
335
336
337
338
339

void formaBuffer(float *filas, float **subA, int subtam, int tam){ int i,j;
for(i=0; i< subtam; i++){
for(j=0; j< tam; j++){
filas[i * tam + j] = subA[i+1][j];
//
printf(" %.2f ", filas[i * tam + j]);
//
fflush(stdout);
}//printf("\n ");
}
}

340
341
342
343

float * creaMatriz(int blk){ float *m;


m = (float*)malloc(sizeof(float)*blk * blk);
return m; }

344
345
346
347

float ** creaMatrizDoble(int blk){ int i; float **aux;


aux = (float**) malloc (blk * sizeof(float*));
for(i=0; i<blk; i++)
n Paralela, Factorizaci
Programacio
on LU

20

348
349

Raymundo Domnguez Coln

aux[i] = (float*) malloc(blk * sizeof(float));


return aux; }

350
351
352
353
354
355
356
357

void llenaMatriz(float *m, int blk){ int i, len;


len = blk * blk;
len = blk*blk;
for (i = 0; i < len; i++){
m[i] = (float)(rand()%9)+1;
}
}

358
359

void imprimeMatriz(float *matriz, int blk){ int i,j;

360

for(i=0; i < blk; i++){


for(j=0; j<blk; j++){
printf(" %.2f ", matriz[i*blk + j]);
fflush(stdout);
}
printf("\n ");
}

361
362
363
364
365
366
367
368

369
370
371
372
373

void uneMatrices(float *aux, float **matA, int tam){ int i,j, desp;
for(i=0; i< tam; i++)
for(j=0; j< tam; j++)
matA[i][j] = aux[i * tam + j];

374
375

376
377
378
379
380
381
382
383
384
385

void imprimeMatrixDoble(float **m, int subtam, int tam){ int i,j;


for(i=0; i< subtam; i++){
for(j=0; j < tam; j++){
printf(" %2.2f ", m[i][j]);
fflush(stdout);
}
printf("\n ");
}
printf("\n "); }

386
387
388
389
390
391
392
393
394
395
396
397
398
399

void llenaMatrizDoble(float **mat, int tam){ int i, j, val, cont=0;


for(i=0; i< tam; i++){//llenando la matriz
for(j=0; j< tam; j++){
val = (rand() % 9) + 1;
if(i==j)
mat[i][j] = (float) val;
else{
mat[i][j] = (float) val;
mat[j][i] = mat[i][j];
}
}
}
}

400
401
402

void freematrix(float **mat, int tam){ int i;


for( i=0; i<tam; i++ )
n Paralela, Factorizaci
Programacio
on LU

Factorizaci
on LU usando rutinas de PVM

free(mat[i]);
free(mat);

403
404
405

21

406

Referencias
[1] Rob Bisseling. the bulk synchronus parallel model, 2008. Online in http://www.math.uu.nl/people/
bisselin/PSC/psc2 3.pdf. Accessed 24-Febrero-2008.
[2] Mattwb. Lu decomposition, 2000. Online in http://everything2.com/index.pl?node id=701232. Consultada el 22-Enero-2008.
[3] Wikipedia. Schur complement wikipedia, the free encyclopedia, 2008. Online in http://en.
wikipedia.org/w/index.php?title=Schur complement&oldid=185516241. Accessed 28-Febrero-2008.

n Paralela, Factorizaci
Programacio
on LU

También podría gustarte