1 /* pmm - paralel matrix multiplication "double diffusion" */
3 /* Copyright (c) 2006- Ahmed Harbaoui. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
12 XBT_LOG_NEW_DEFAULT_CATEGORY(pmm,"Messages specific to this example");
14 GRAS_DEFINE_TYPE(s_matrix,struct s_matrix {
17 double *data GRAS_ANNOTE(size, rows*cols);
19 typedef struct s_matrix matrix_t;
21 /* struct for recovering results */
22 GRAS_DEFINE_TYPE(s_result,struct s_result {
27 typedef struct s_result result_t;
29 /* struct to send initial data to sensor */
30 GRAS_DEFINE_TYPE(s_init_data,struct s_init_data {
36 typedef struct s_init_data init_data_t;
38 /* register messages which may be sent (common to client and server) */
39 static void register_messages(void) {
40 gras_datadesc_type_t result_type;
41 gras_datadesc_type_t init_data_type;
42 result_type=gras_datadesc_by_symbol(s_result);
43 init_data_type=gras_datadesc_by_symbol(s_init_data);
45 gras_msgtype_declare("result", result_type); // recieve a final result from sensor
46 gras_msgtype_declare("init_data", init_data_type); // send from maestro to sensor to initialize data bA,bB
48 gras_msgtype_declare("ask_result", gras_datadesc_by_name("int")); // send from maestro to sensor to ask a final result
49 gras_msgtype_declare("step", gras_datadesc_by_name("int"));// send from maestro to sensor to indicate the begining of step
50 gras_msgtype_declare("step_ack", gras_datadesc_by_name("int"));//send from sensor to maestro to indicate the end of the current step
51 gras_msgtype_declare("dataA", gras_datadesc_by_name("double"));// send data between sensor
52 gras_msgtype_declare("dataB", gras_datadesc_by_name("double"));// send data between sensor
55 /* Function prototypes */
56 int sensor (int argc,char *argv[]);
57 int maestro (int argc,char *argv[]);
60 /* **********************************************************************
62 * **********************************************************************/
64 /* Global private data */
72 /*** Function initilaze matrixs ***/
74 static void initmatrix(matrix_t *X){
77 for(i=0 ; i<(X->rows)*(X->cols); i++)
78 X->data[i]=1.0;//*rand()/(RAND_MAX+1.0);
79 } /* end_of_initmatrixs */
81 /*** Function Scatter Sequentiel ***/
83 static void scatter(){
87 /*** Function: Scatter // ***/
89 static void scatter_parl(){
91 }/* end_of_Scatter // */
93 /*** Function: multiplication ***/
95 static void multiplication(){
97 }/* end_of_multiplication */
99 /*** Function: gather ***/
101 static void gather(){
105 /*** Function: Display Matrix ***/
107 static void display(matrix_t X){
112 for(j=0;j<X.cols;j++)
116 for(j=0;j<X.cols;j++)
120 for(i=0;i<X.rows;i++){
122 for(j=0;j<X.cols;j++)
123 printf("%.3g ",X.data[t++]);
127 for(j=0;j<X.cols;j++)
131 }/* end_of_display */
133 int maestro (int argc,char *argv[]) {
137 int i,port,ask_result,step;
144 /* Init the GRAS's infrastructure */
145 gras_init(&argc, argv);
147 gras_socket_t socket[MATRIX_SIZE*MATRIX_SIZE]; /* sockets for brodcast to other sensor */
149 /* Initialize Matrixs */
151 A.rows=A.cols=MATRIX_SIZE;
152 B.rows=B.cols=MATRIX_SIZE;
153 C.rows=C.cols=MATRIX_SIZE;
155 A.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
156 B.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
157 C.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
162 /* Get arguments and create sockets */
169 /****************************** Init Data Send *********************************/
172 gras_os_sleep(60); // MODIFIER LES TEMPS D'ATTENTE 60 c trop normalement
173 for( i=2;i< argc;i+=3){
175 socket[j]=gras_socket_client(argv[i],port);
177 RETHROW0("Unable to connect to the server: %s");
179 INFO2("Connected to %s:%d.",argv[i],port);
181 mydata.myrow=atoi(argv[i+1]); // My row
182 mydata.mycol=atoi(argv[i+2]); // My column
184 mydata.a=A.data[(mydata.myrow-1)*MATRIX_SIZE+(mydata.mycol-1)];
185 mydata.b=B.data[(mydata.myrow-1)*MATRIX_SIZE+(mydata.mycol-1)];;
187 gras_msg_send(socket[j],gras_msgtype_by_name("init_data"),&mydata);
188 INFO3("Send Init Data to %s : data A= %.3g & data B= %.3g",gras_socket_peer_name(socket[j]),mydata.a,mydata.b);
190 } // end init Data Send
192 /******************************* multiplication ********************************/
193 INFO0("begin Multiplication");
195 for (step=1; step <= MATRIX_SIZE; step++){
197 for (i=0; i< SENSOR_NBR; i++){
199 gras_msg_send(socket[i], gras_msgtype_by_name("step"), &step); /* initialize Mycol, MyRow, mydataA,mydataB*/
201 gras_socket_close(socket[i]);
202 RETHROW0("Unable to send the msg : %s");
205 INFO1("send to sensor to begin a %d th step",step);
206 /* wait for computing and sensor messages exchange */
209 while ( i< SENSOR_NBR){
211 gras_msg_wait(1300,gras_msgtype_by_name("step_ack"),&from,&step_ack);
213 RETHROW0("I Can't get a Ack step message from sensor : %s");
216 INFO1("Recive Ack step ack from %s",gras_socket_peer_name(from));
219 /********************************* gather ***************************************/
222 for( i=1;i< argc;i++){
223 gras_msg_send(socket[i],gras_msgtype_by_name("ask_result"),&ask_result);
224 INFO1("Send (Ask Result) message to %s",gras_socket_peer_name(socket[i]));
226 /* wait for results */
227 for( i=1;i< argc;i++){
228 gras_msg_wait(600,gras_msgtype_by_name("result"),&from,&result);
229 C.data[(result.i-1)*MATRIX_SIZE+(result.j-1)]=result.value;
232 INFO0 ("The Result of Multiplication is :");
236 } /* end_of_maestro */
238 /* **********************************************************************
240 * **********************************************************************/
242 int sensor(int argc,char *argv[]) {
246 int step,port,l,result_ack=0;
250 double mydataA,mydataB;
257 gras_socket_t from,sock; /* to recive from server for steps */
259 gras_socket_t socket_row[MATRIX_SIZE-1],socket_column[MATRIX_SIZE-1]; /* sockets for brodcast to other sensor */
261 /* Init the GRAS's infrastructure */
263 gras_init(&argc, argv);
265 /* Get arguments and create sockets */
269 /* Create my master socket */
270 sock = gras_socket_server(port);
271 INFO2("Launch %s (port=%d)",argv[0],port);
272 gras_os_sleep(1); //wait to start all sensor
275 for (i=1;i<MATRIX_SIZE;i++){
276 socket_row[i-1]=gras_socket_client(argv[i+1],port);
277 socket_column[i-1]=gras_socket_client(argv[i+MATRIX_SIZE],port);
280 /* Register the known messages */
283 /* Recover my initialized Data and My Position*/
285 INFO0("wait for init Data");
287 gras_msg_wait(600,gras_msgtype_by_name("init_data"),&from,&mydata);
289 RETHROW0("I Can't get a init Data message from Maestro : %s");
295 INFO4("Recive MY POSITION (%d,%d) and MY INIT DATA ( A=%.3g | B=%.3g )",
296 myrow,mycol,mydataA,mydataB);
299 do { //repeat until compute Cb
300 step=MATRIX_SIZE+1; // just intilization for loop
303 gras_msg_wait(60,gras_msgtype_by_name("step"),&from,&step);
305 RETHROW0("I Can't get a Next Step message from Maestro : %s");
307 INFO1("Recive a step message from maestro: step = %d ",step);
309 if (step < MATRIX_SIZE ){
311 gras_os_sleep(3); // IL FAUT EXPRIMER LE TEMPS D'ATTENTE EN FONCTION DE "SENSOR_NBR"
313 INFO2("step(%d) = Myrow(%d)",step,myrow);
314 for (l=1;l < MATRIX_SIZE ;l++){
315 gras_msg_send(socket_column[l-1], gras_msgtype_by_name("dataB"), &mydataB);
317 INFO1("send my data B (%.3g) to my (vertical) neighbors",bB);
321 INFO2("step(%d) <> Myrow(%d)",step,myrow);
323 gras_msg_wait(600,gras_msgtype_by_name("dataB"),
326 RETHROW0("I Can't get a data message from row : %s");
328 INFO2("Recive data B (%.3g) from my neighbor: %s",bB,gras_socket_peer_name(from));
330 /* a column brodcast */
332 for (l=1;l < MATRIX_SIZE ;l++){
333 gras_msg_send(socket_row[l-1],gras_msgtype_by_name("dataA"), &mydataA);
335 INFO1("send my data A (%.3g) to my (horizontal) neighbors",bA);
341 gras_msg_wait(1200,gras_msgtype_by_name("dataA"),
344 RETHROW0("I Can't get a data message from column : %s");
346 INFO2("Recive data A (%.3g) from my neighbor : %s ",bA,gras_socket_peer_name(from));
349 INFO1(">>>>>>>> My BC = %.3g",bC);
351 /* send a ack msg to Maestro */
353 gras_msg_send(from,gras_msgtype_by_name("step_ack"),&step);
355 INFO1("Send ack to maestro for to end %d th step",step);
357 if(step==MATRIX_SIZE-1) break;
359 } while (step < MATRIX_SIZE);
360 /* wait Message from maestro to send the result */
367 gras_msg_wait(600,gras_msgtype_by_name("ask_result"),
370 RETHROW0("I Can't get a data message from row : %s");
372 /* send Result to Maestro */
374 gras_msg_send(from, gras_msgtype_by_name("result"),&result);
376 // gras_socket_close(from);
377 RETHROW0("Failed to send PING to server: %s");
379 INFO3(">>>>>>>> Result: %.3f sent to %s:%d <<<<<<<<",
381 gras_socket_peer_name(from),gras_socket_peer_port(from));
382 /* Free the allocated resources, and shut GRAS down */
383 gras_socket_close(from);
387 } /* end_of_sensor */