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("data", gras_datadesc_by_name("double"));// send data between sensor
54 /* Function prototypes */
55 int maestro (int argc,char *argv[]);
56 int sensor (int argc,char *argv[]);
58 /* **********************************************************************
60 * **********************************************************************/
62 /* Global private data */
70 /*** Function initilaze matrixs ***/
72 static void initmatrix(matrix_t *X){
75 for(i=0 ; i<(X->rows)*(X->cols); i++)
76 X->data[i]=1.0;//1.0*rand()/(RAND_MAX+1.0);
77 } /* end_of_initmatrixs */
79 /*** Function Scatter Sequentiel ***/
81 static void scatter(){
85 /*** Function: Scatter // ***/
87 static void scatter_parl(){
89 }/* end_of_Scatter // */
91 /*** Function: multiplication ***/
93 static void multiplication(){
95 }/* end_of_multiplication */
97 /*** Function: gather ***/
103 /*** Function: Display Matrix ***/
105 static void display(matrix_t X){
110 for(j=0;j<X.cols;j++)
114 for(j=0;j<X.cols;j++)
118 for(i=0;i<X.rows;i++){
120 for(j=0;j<X.cols;j++)
121 printf("%.3g ",X.data[t++]);
125 for(j=0;j<X.cols;j++)
129 }/* end_of_display */
131 int maestro (int argc,char *argv[]) {
135 int i,port,ask_result,step;
142 /* Init the GRAS's infrastructure */
143 gras_init(&argc, argv);
145 gras_socket_t socket[MATRIX_SIZE*MATRIX_SIZE]; /* sockets for brodcast to other sensor */
147 /* Initialize Matrixs */
149 A.rows=A.cols=MATRIX_SIZE;
150 B.rows=B.cols=MATRIX_SIZE;
151 C.rows=C.cols=MATRIX_SIZE;
153 A.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
154 B.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
155 C.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
160 /* Get arguments and create sockets */
166 /****************************** Init Data Send *********************************/
169 for( i=2;i< argc;i+=3){
172 socket[j]=gras_socket_client(argv[i],port);
174 RETHROW0("Unable to connect to the server: %s");
176 INFO2("Connected to %s:%d.",argv[i],port);
178 mydata.myrow=argv[i+1]; // My row
179 mydata.mycol=argv[i+2]; // My column
180 mydata.a=A.data[(mydata.myrow-1)*MATRIX_SIZE+(mydata.mycol-1)];
181 mydata.b=B.data[(mydata.myrow-1)*MATRIX_SIZE+(mydata.mycol-1)];;
183 gras_msg_send(socket[j],gras_msgtype_by_name("init_data"),&mydata);
185 } // end init Data Send
187 /******************************* multiplication ********************************/
188 INFO0("begin Multiplication");
189 for (step=1; step <= MATRIX_SIZE; step++){
190 for (i=0; i< SENSOR_NBR; i++){
192 gras_msg_send(socket[i], gras_msgtype_by_name("step"), &step); /* initialize Mycol, MyRow, mydataA,mydataB*/
193 // myrow,mycol,mydataA,mydataB
195 gras_socket_close(socket[i]);
196 RETHROW0("Unable to send the msg : %s");
199 INFO1("send to sensor to begin a %d th step",step);
200 /* wait for computing and sensor messages exchange */
202 while ( i< SENSOR_NBR){
204 gras_msg_wait(600,gras_msgtype_by_name("step_ack"),&from,&mydata);
206 RETHROW0("I Can't get a init Data message from Maestro : %s");
209 INFO1("Recive Ack step ack from %s",gras_socket_peer_name(from));
212 /********************************* gather ***************************************/
215 for( i=1;i< argc;i++){
216 gras_msg_send(socket[i],gras_msgtype_by_name("ask_result"),&ask_result);
217 INFO1("Send (Ask Result) message to %s",gras_socket_peer_name(socket[i]));
219 /* wait for results */
220 for( i=1;i< argc;i++){
221 gras_msg_wait(600,gras_msgtype_by_name("result"),&from,&result);
222 C.data[(result.i-1)*MATRIX_SIZE+(result.j-1)]=result.value;
225 INFO0 ("The Result of Multiplication is :");
229 } /* end_of_maestro */
231 /* **********************************************************************
233 * **********************************************************************/
235 int sensor(int argc,char *argv[]) {
239 int step,port,l,result_ack=0;
242 static int myrow,mycol;
243 static double mydataA,mydataB;
248 gras_socket_t from,sock; /* to recive from server for steps */
250 gras_socket_t socket_row[2],socket_column[2]; /* sockets for brodcast to other sensor */
252 /* Init the GRAS's infrastructure */
254 gras_init(&argc, argv);
256 /* Get arguments and create sockets */
260 for (i=1;i<MATRIX_SIZE;i++){
261 socket_row[i]=gras_socket_client(argv[i+1],port);
262 socket_column[i]=gras_socket_client(argv[i+MATRIX_SIZE],port);
264 INFO2("Launch %s (port=%d)",argv[0],port);
266 /* Create my master socket */
267 sock = gras_socket_server(port);
269 /* Register the known messages */
272 /* Recover my initialized Data and My Position*/
274 INFO0("wait for init Data");
276 gras_msg_wait(600,gras_msgtype_by_name("init_data"),&from,&mydata);
278 RETHROW0("I Can't get a init Data message from Maestro : %s");
285 INFO4("Recive MY POSITION (%d,%d) and MY INIT DATA ( A=%.3g | B=%.3g )",
286 myrow,mycol,mydataA,mydataB);
287 do { //repeat until compute Cb
288 step=MATRIX_SIZE+1; // juste intilization for loop
291 gras_msg_wait(600,gras_msgtype_by_name("step"),&from,&step);
293 RETHROW0("I Can't get a Next Step message from Maestro : %s");
296 /* Wait for sensors startup */
299 if (step < MATRIX_SIZE){
302 for (l=1;l < MATRIX_SIZE ;l++){
303 gras_msg_send(socket_row[l], gras_msgtype_by_name("data"), &mydataB);
305 INFO1("send my data B (%.3f) to my (horizontal) neighbors",bB);
311 gras_msg_wait(600,gras_msgtype_by_name("data"),
314 RETHROW0("I Can't get a data message from row : %s");
316 INFO1("Recive data B (%.3f) from my neighbors",bB);
318 /* a column brodcast */
320 for (l=1;l < MATRIX_SIZE ;l++){
321 gras_msg_send(socket_column[l],gras_msgtype_by_name("data"), &mydataA);
323 INFO1("send my data A (%.3f) to my (vertical) neighbors",bA);
329 gras_msg_wait(600,gras_msgtype_by_name("data"),
332 RETHROW0("I Can't get a data message from column : %s");
334 INFO1("Recive data A (%.3f) from my neighbors",bA);
338 /* send a ack msg to Maestro */
340 gras_msg_send(from,gras_msgtype_by_name("step_ack"),&step);
342 INFO1("Send ack to maestro for to end %d th step",step);
344 if(step==MATRIX_SIZE-1) break;
346 } while (step < MATRIX_SIZE);
347 /* wait Message from maestro to send the result */
354 gras_msg_wait(600,gras_msgtype_by_name("ask_result"),
357 RETHROW0("I Can't get a data message from row : %s");
359 /* send Result to Maestro */
361 gras_msg_send(from, gras_msgtype_by_name("result"),&result);
363 // gras_socket_close(from);
364 RETHROW0("Failed to send PING to server: %s");
366 INFO3(">>>>>>>> Result: %.3f sent to %s:%d <<<<<<<<",
368 gras_socket_peer_name(from),gras_socket_peer_port(from));
369 /* Free the allocated resources, and shut GRAS down */
370 gras_socket_close(from);
374 } /* end_of_sensor */