You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Ejemplo <strong>MPI</strong><br />
Ivar Fernando Gómez Pedraza
Multiplicación de matrices<br />
• Hacer un programa que realice la<br />
multiplicación de dos matrices, tales que el<br />
número de columnas de la matriz A es igual al<br />
número de filas de la matriz B; es decir:
• la multiplicación de A por B, que se denota<br />
A·B, A×B o simplemente AB, está definida<br />
como:<br />
• donde cada elemento c i,j está definido por:
Gráficamente, si<br />
y<br />
Entonces
Procedimiento secuencial<br />
Un solo proceso que ejecuta:<br />
for(i=0; i
Multiplicación de Matrices<br />
Procedimiento paralelo<br />
• Un proceso maestro -> distribuye las distintas<br />
tareas al resto de procesos.<br />
• Varios procesos worker -> calcula un cierto<br />
número de filas de la matriz resultante y<br />
reenvía el resultado parcial al proceso<br />
maestro.<br />
Num_workers = num_procesos -1
Proceso en el MAESTRO<br />
• Conocer las matrices a multiplicar a y b<br />
• Inicialización de las matrices a y b<br />
• Cálculo del número de filas que hay que enviar a cada<br />
proceso worker:<br />
• nfilas = NFA / num_workers<br />
• filas_extra = NFA % num_workers<br />
• ENVIO a cada WORKER:<br />
• Numero de filas de la matriz “a” -> nfilas o nfilas+1<br />
• Elementos de “a” con los que debe operar -> nfilas*NCA<br />
elementos de “a”<br />
• Matriz “b” en su totalidad.<br />
• ESPERAR... (mientras los workers trabajan)
• RECEPCIÓN de cada WORKER<br />
– Subparte de la matriz resultado “c”-> nfilas*NCB<br />
elementos.<br />
• Atención!!! ¿¿¿dónde metemos los elementos<br />
recibidos???<br />
cada worker puede haber calculado un<br />
número de filas distintas, calcular cuántas y<br />
guardar resultado en matriz “c” con el<br />
desplazamiento adecuado.
Fase de envío:<br />
<strong>MPI</strong>_send<br />
Fase<br />
recepción:<br />
<strong>MPI</strong>_recv
Proceso en el WORKER<br />
• Desconoce tanto la matriz a como la b<br />
• Recepción del MAESTRO de:<br />
• Número de filas -> nfilas<br />
• Elementos de a con los que va a calcular -> nfilas*NCA elementos<br />
• Matriz b en su totalidad<br />
• Fase de Cálculo:<br />
for(i=0; i
Código en <strong>MPI</strong><br />
• Se colocan las librerías a usar<br />
#include "mpi.h"<br />
#include <br />
#include <br />
Librería de C que<br />
contiene las<br />
operaciones estándar<br />
de entrada y salida<br />
Librería que contiene<br />
los prototipos de<br />
funciones de C para<br />
gestión de memoria<br />
dinámica, control de<br />
procesos y otras
int main (int argc, char *argv[])<br />
{<br />
int nsize, rank, rc, i, j, k,numworkers, /* number of worker tasks */<br />
source, /* task id of message source */<br />
dest, /* task id of message destination */<br />
mtype, /* message type */<br />
rows, /* rows of matrix A sent to each worker */<br />
averow, extra, offset; /* used to determine rows<br />
sent to each worker */<br />
int NRA=4, NCA=6, NCB=3, MASTER=0;<br />
double a[NRA][NCA], /* matriz A */<br />
b[NCA][NCB], /* matriz B */<br />
c[NRA][NCB]; /* matriz resultado C */<br />
<strong>MPI</strong>_Status status;
<strong>MPI</strong>_Init(&argc,&argv);<br />
<strong>MPI</strong>_Comm_rank(<strong>MPI</strong>_COMM_WORLD,&taskid);<br />
<strong>MPI</strong>_Comm_size(<strong>MPI</strong>_COMM_WORLD,&numtasks);<br />
if (numtasks < 2 ) {<br />
printf("Need at least two <strong>MPI</strong> tasks. Quitting...\n");<br />
<strong>MPI</strong>_Abort(<strong>MPI</strong>_COMM_WORLD, rc);<br />
exit(1);<br />
}<br />
numworkers = numtasks-1;
• /***************** master task ************************/<br />
• if (taskid == MASTER)<br />
• {<br />
• printf("mpi_mm has started with %d tasks.\n",numtasks);<br />
• printf("Initializing arrays...\n");<br />
• for (i=0; i
• /* Send matrix data to the worker tasks */<br />
• averow = NRA/numworkers;<br />
• extra = NRA%numworkers;<br />
• offset = 0;<br />
• mtype = FROM_MASTER;<br />
• for (dest=1; dest
• /* Receive results from worker tasks */<br />
mtype = FROM_WORKER;<br />
for (i=1; i
• /* Print results */<br />
• printf("******************************************************\n");<br />
• printf("Result Matrix:\n");<br />
• for (i=0; i
• /**************************** worker task ************************************/<br />
• if (taskid > MASTER)<br />
• {<br />
• mtype = FROM_MASTER;<br />
• <strong>MPI</strong>_Recv(&offset, 1, <strong>MPI</strong>_INT, MASTER, mtype, <strong>MPI</strong>_COMM_WORLD, &status);<br />
• <strong>MPI</strong>_Recv(&rows, 1, <strong>MPI</strong>_INT, MASTER, mtype, <strong>MPI</strong>_COMM_WORLD, &status);<br />
• <strong>MPI</strong>_Recv(&a, rows*NCA, <strong>MPI</strong>_DOUBLE, MASTER, mtype, <strong>MPI</strong>_COMM_WORLD, &status);<br />
• <strong>MPI</strong>_Recv(&b, NCA*NCB, <strong>MPI</strong>_DOUBLE, MASTER, mtype, <strong>MPI</strong>_COMM_WORLD, &status);<br />
• for (k=0; k