X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/552b831aadcdba9ea4c7abaae26b498815523354..82ef813a5d1cf608e1ae2a80c306a1cee9fceab1:/examples/gras/pmm/pmm.c diff --git a/examples/gras/pmm/pmm.c b/examples/gras/pmm/pmm.c index dc785b4d43..45f427e39b 100755 --- a/examples/gras/pmm/pmm.c +++ b/examples/gras/pmm/pmm.c @@ -1,80 +1,78 @@ -/* pmm - paralel matrix multiplication "double diffusion" */ +/* $Id$ */ +/* pmm - parallel matrix multiplication "double diffusion" */ -/* Copyright (c) 2006- Ahmed Harbaoui. All rights reserved. */ +/* Copyright (c) 2006 Ahmed Harbaoui. */ +/* Copyright (c) 2006 Martin Quinson. */ +/* All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "gras.h" -#define MATRIX_SIZE 3 -#define SENSOR_NBR 9 +#include "xbt/matrix.h" +#define PROC_MATRIX_SIZE 2 +#define SLAVE_COUNT (PROC_MATRIX_SIZE*PROC_MATRIX_SIZE) -XBT_LOG_NEW_DEFAULT_CATEGORY(pmm,"Messages specific to this example"); +#define DATA_MATRIX_SIZE 8 +const int submatrix_size = DATA_MATRIX_SIZE/PROC_MATRIX_SIZE; -GRAS_DEFINE_TYPE(s_matrix,struct s_matrix { - int rows; - int cols; - double *data GRAS_ANNOTE(size, rows*cols); -};) -typedef struct s_matrix matrix_t; +XBT_LOG_NEW_DEFAULT_CATEGORY(pmm,"Parallel Matrix Multiplication"); /* struct for recovering results */ GRAS_DEFINE_TYPE(s_result,struct s_result { - int i; - int j; - double value; + int linepos; + int rowpos; + xbt_matrix_t C GRAS_ANNOTE(subtype,double); }); typedef struct s_result result_t; -/* struct to send initial data to sensor */ -GRAS_DEFINE_TYPE(s_init_data,struct s_init_data { - int myrow; - int mycol; - double a; - double b; +/* struct to send initial data to slave */ +GRAS_DEFINE_TYPE(s_assignment,struct s_assignment { + int linepos; + int rowpos; + xbt_host_t line[PROC_MATRIX_SIZE]; + xbt_host_t row[PROC_MATRIX_SIZE]; + xbt_matrix_t A GRAS_ANNOTE(subtype,double); + xbt_matrix_t B GRAS_ANNOTE(subtype,double); }); -typedef struct s_init_data init_data_t; +typedef struct s_assignment s_assignment_t; /* register messages which may be sent (common to client and server) */ static void register_messages(void) { - gras_datadesc_type_t result_type; - gras_datadesc_type_t init_data_type; - result_type=gras_datadesc_by_symbol(s_result); - init_data_type=gras_datadesc_by_symbol(s_init_data); + gras_datadesc_type_t result_type; + gras_datadesc_type_t assignment_type; + + gras_datadesc_set_const("PROC_MATRIX_SIZE",PROC_MATRIX_SIZE); + result_type=gras_datadesc_by_symbol(s_result); + assignment_type=gras_datadesc_by_symbol(s_assignment); - gras_msgtype_declare("result", result_type); // recieve a final result from sensor - gras_msgtype_declare("init_data", init_data_type); // send from maestro to sensor to initialize data bA,bB + /* receive a final result from slave */ + gras_msgtype_declare("result", result_type); + + /* send from master to slave to assign a position and some data */ + gras_msgtype_declare("assignment", assignment_type); - gras_msgtype_declare("ask_result", gras_datadesc_by_name("int")); // send from maestro to sensor to ask a final result - gras_msgtype_declare("step", gras_datadesc_by_name("int"));// send from maestro to sensor to indicate the begining of step - gras_msgtype_declare("step_ack", gras_datadesc_by_name("int"));//send from sensor to maestro to indicate the end of the current step - gras_msgtype_declare("data", gras_datadesc_by_name("double"));// send data between sensor + /* send data between slaves */ + gras_msgtype_declare("dataA", gras_datadesc_matrix(gras_datadesc_by_name("double"),NULL)); + gras_msgtype_declare("dataB", gras_datadesc_matrix(gras_datadesc_by_name("double"),NULL)); } /* Function prototypes */ -int maestro (int argc,char *argv[]); -int sensor (int argc,char *argv[]); +int slave (int argc,char *argv[]); +int master (int argc,char *argv[]); + /* ********************************************************************** - * Maestro code + * master code * **********************************************************************/ /* Global private data */ typedef struct { - int nbr_col,nbr_row; + int nbr_row,nbr_line; int remaining_step; int remaining_ack; -} maestro_data_t; - +} master_data_t; -/*** Function initilaze matrixs ***/ - -static void initmatrix(matrix_t *X){ -int i; - -for(i=0 ; i<(X->rows)*(X->cols); i++) - X->data[i]=1.0;//1.0*rand()/(RAND_MAX+1.0); -} /* end_of_initmatrixs */ /*** Function Scatter Sequentiel ***/ @@ -100,275 +98,268 @@ static void gather(){ }/* end_of_gather */ -/*** Function: Display Matrix ***/ - -static void display(matrix_t X){ - -int i,j,t=0; - - printf(" "); - for(j=0;jname,grid[i-1]->port); + + INFO2("Connected to %s:%d.",grid[i-1]->name,grid[i-1]->port); + } + xbt_assert2(i-1==SLAVE_COUNT, + "Not enough slaves for this setting (got %d of %d). Change the deployment file", + i-1,SLAVE_COUNT); + /* FIXME: let the surnumerous slave die properly */ + + int row=0, line=0; + INFO0("XXXXXXXXXXXXXXXXXXXXXX begin Multiplication"); + for(i=0 ; i= PROC_MATRIX_SIZE) { + row=0; + line++; + } - gras_msg_send(socket[j],gras_msgtype_by_name("init_data"),&mydata); - j++; - } // end init Data Send - - /******************************* multiplication ********************************/ - INFO0("begin Multiplication"); - for (step=1; step <= MATRIX_SIZE; step++){ - for (i=0; i< SENSOR_NBR; i++){ - TRY { - gras_msg_send(socket[i], gras_msgtype_by_name("step"), &step); /* initialize Mycol, MyRow, mydataA,mydataB*/ - // myrow,mycol,mydataA,mydataB - } CATCH(e) { - gras_socket_close(socket[i]); - RETHROW0("Unable to send the msg : %s"); - } - } - INFO1("send to sensor to begin a %d th step",step); - /* wait for computing and sensor messages exchange */ - i=0; - while ( i< SENSOR_NBR){ - TRY { - gras_msg_wait(600,gras_msgtype_by_name("step_ack"),&from,&mydata); - } CATCH(e) { - RETHROW0("I Can't get a init Data message from Maestro : %s"); - } - i++; - INFO1("Recive Ack step ack from %s",gras_socket_peer_name(from)); - } - } - /********************************* gather ***************************************/ - - ask_result=0; - for( i=1;i< argc;i++){ - gras_msg_send(socket[i],gras_msgtype_by_name("ask_result"),&ask_result); - INFO1("Send (Ask Result) message to %s",gras_socket_peer_name(socket[i])); - } - /* wait for results */ - for( i=1;i< argc;i++){ - gras_msg_wait(600,gras_msgtype_by_name("result"),&from,&result); - C.data[(result.i-1)*MATRIX_SIZE+(result.j-1)]=result.value; - } - /* end of gather */ - INFO0 ("The Result of Multiplication is :"); - display(C); - -return 0; -} /* end_of_maestro */ + gras_msg_send(socket[i],gras_msgtype_by_name("assignment"),&assignment); + xbt_matrix_free(assignment.A); + xbt_matrix_free(assignment.B); + } + // end assignment + + /******************************* multiplication ********************************/ + /* wait for results */ + for( i=0;i< SLAVE_COUNT;i++){ + gras_msg_wait(6000,gras_msgtype_by_name("result"),&from,&result); + xbt_matrix_copy_values(C,result.C, submatrix_size,submatrix_size, + submatrix_size*result.linepos, + submatrix_size*result.rowpos, + 0,0,NULL); + xbt_matrix_free(result.C); + } + /* end of gather */ + if (DATA_MATRIX_SIZE < 50) { + INFO0 ("The Result of Multiplication is :"); + xbt_matrix_dump(C,"C:res",0,xbt_matrix_dump_display_double); + } else { + INFO1("Matrix size too big (%d>50) to be displayed here",DATA_MATRIX_SIZE); + } + + for(i=0; iname)) { + socket_line[j]=gras_socket_client(assignment.line[i]->name, + assignment.line[i]->port); + j++; + } + xbt_host_free(assignment.line[i]); + } + for (i=0,j=0 ; iname)) { + socket_row[j]=gras_socket_client(assignment.row[i]->name, + assignment.row[i]->port); + j++; + } + xbt_host_free(assignment.row[i]); } - /* Wait for sensors startup */ - gras_os_sleep(1); - - if (step < MATRIX_SIZE){ - /* a row brodcast */ - if(myrow==step){ - for (l=1;l < MATRIX_SIZE ;l++){ - gras_msg_send(socket_row[l], gras_msgtype_by_name("data"), &mydataB); - bB=mydataB; - INFO1("send my data B (%.3f) to my (horizontal) neighbors",bB); - } - } - else - { - TRY { - gras_msg_wait(600,gras_msgtype_by_name("data"), - &from,&bB); - } CATCH(e) { - RETHROW0("I Can't get a data message from row : %s"); - } - INFO1("Recive data B (%.3f) from my neighbors",bB); - } - /* a column brodcast */ - if(mycol==step){ - for (l=1;l < MATRIX_SIZE ;l++){ - gras_msg_send(socket_column[l],gras_msgtype_by_name("data"), &mydataA); - bA=mydataA; - INFO1("send my data A (%.3f) to my (vertical) neighbors",bA); - } - } - else - { - TRY { - gras_msg_wait(600,gras_msgtype_by_name("data"), - &from,&bA); - } CATCH(e) { - RETHROW0("I Can't get a data message from column : %s"); - } - INFO1("Recive data A (%.3f) from my neighbors",bA); - } - bC+=bA*bB; - } - /* send a ack msg to Maestro */ - - gras_msg_send(from,gras_msgtype_by_name("step_ack"),&step); + for (step=0; step Myline(%d). Receive data from %s:%d",step,myline, + gras_socket_peer_name(from), gras_socket_peer_port(from)); + } + + /* a row brodcast */ + if (myrow==step) { + INFO2("ROW: step(%d)=myrow(%d). Broadcast my data",step,myrow); + for (l=1;l < PROC_MATRIX_SIZE ;l++) + gras_msg_send(socket_line[l-1],gras_msgtype_by_name("dataA"), &mydataA); + xbt_matrix_free(bA); + bA = xbt_matrix_new_sub(mydataA, + submatrix_size,submatrix_size, + 0,0,NULL); + } else { + TRY { + xbt_matrix_free(bA); + gras_msg_wait(1200,gras_msgtype_by_name("dataA"), &from,&bA); + } CATCH(e) { + RETHROW0("Can't get a data message from row : %s"); + } + INFO3("ROW: step(%d)<>myrow(%d). Receive data from %s",step,myrow, + gras_socket_peer_name(from)); + } + xbt_matrix_double_addmult(bA,bB,bC); + + }; - TRY { - gras_msg_wait(600,gras_msgtype_by_name("ask_result"), - &from,&result_ack); - } CATCH(e) { - RETHROW0("I Can't get a data message from row : %s"); - } - /* send Result to Maestro */ - TRY { - gras_msg_send(from, gras_msgtype_by_name("result"),&result); - } CATCH(e) { - // gras_socket_close(from); - RETHROW0("Failed to send PING to server: %s"); - } - INFO3(">>>>>>>> Result: %.3f sent to %s:%d <<<<<<<<", - bC, - gras_socket_peer_name(from),gras_socket_peer_port(from)); - /* Free the allocated resources, and shut GRAS down */ - gras_socket_close(from); - gras_exit(); - INFO0("Done."); - return 0; -} /* end_of_sensor */ \ No newline at end of file + /* send Result to master */ + result.C=bC; + result.linepos=myline; + result.rowpos=myrow; + + TRY { + gras_msg_send(master, gras_msgtype_by_name("result"),&result); + } CATCH(e) { + RETHROW0("Failed to send PING to server: %s"); + } + INFO2(">>>>>>>> Result sent to %s:%d <<<<<<<<", + gras_socket_peer_name(master),gras_socket_peer_port(master)); + /* Free the allocated resources, and shut GRAS down */ + + xbt_matrix_free(bA); + xbt_matrix_free(bB); + xbt_matrix_free(bC); + + xbt_matrix_free(mydataA); + xbt_matrix_free(mydataB); + gras_socket_close(sock); + gras_socket_close(master); + gras_socket_close(from); + /* FIXME: Some of these sockets are "not known", no idea why * + for (l=0; l < PROC_MATRIX_SIZE-1; l++) { + if (socket_line[l]) + gras_socket_close(socket_line[l]); + if (socket_row[l]) + gras_socket_close(socket_row[l]); + }*/ + + + gras_exit(); + INFO0("Done."); + return 0; +} /* end_of_slave */