Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
add comments to pmm example & modify pmm_deployment.xml ( Function : Maestro ->...
[simgrid.git] / examples / gras / pmm / pmm.c
1 /* pmm - paralel matrix multiplication "double diffusion"                       */
2
3 /* Copyright (c) 2006- Ahmed Harbaoui. All rights reserved.                  */
4
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. */
7
8 #include "gras.h"
9 #define MATRIX_SIZE 3
10 #define SENSOR_NBR 9
11
12 XBT_LOG_NEW_DEFAULT_CATEGORY(pmm,"Messages specific to this example");
13
14 GRAS_DEFINE_TYPE(s_matrix,struct s_matrix {
15         int rows;
16         int cols;
17         double *data GRAS_ANNOTE(size, rows*cols);
18 };)
19 typedef struct s_matrix matrix_t;
20
21 /* struct for recovering results */
22 GRAS_DEFINE_TYPE(s_result,struct s_result {
23         int i;
24         int j;
25         double value;
26 });
27 typedef struct s_result result_t;
28
29 /* struct to send initial data to sensor */
30 GRAS_DEFINE_TYPE(s_init_data,struct s_init_data {
31         int myrow;
32         int mycol;
33         double a;
34         double b;
35 });
36 typedef struct s_init_data init_data_t;
37
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);
44         
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
47
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
52 }
53
54 /* Function prototypes */
55 int maestro (int argc,char *argv[]);
56 int sensor (int argc,char *argv[]);
57
58 /* **********************************************************************
59  * Maestro code
60  * **********************************************************************/
61
62 /* Global private data */
63 typedef struct {
64   int nbr_col,nbr_row;
65   int remaining_step;
66   int remaining_ack;
67 } maestro_data_t;
68
69
70 /***  Function initilaze matrixs ***/
71
72 static void initmatrix(matrix_t *X){
73 int i;
74
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 */
78
79 /***  Function Scatter Sequentiel ***/
80
81 static void scatter(){
82
83 }/* end_of_Scatter */
84
85 /***  Function: Scatter // ***/
86
87 static void scatter_parl(){
88
89 }/* end_of_Scatter // */
90
91 /***  Function: multiplication ***/
92
93 static void multiplication(){
94
95 }/* end_of_multiplication */
96
97 /***  Function: gather ***/
98
99 static void gather(){
100
101 }/* end_of_gather */
102
103 /***  Function: Display Matrix ***/
104
105 static void display(matrix_t X){
106         
107 int i,j,t=0;
108
109   printf("      ");
110   for(j=0;j<X.cols;j++)
111     printf("%.3d ",j);
112     printf("\n");
113     printf("    __");
114     for(j=0;j<X.cols;j++)
115         printf("____");
116         printf("_\n");
117
118         for(i=0;i<X.rows;i++){
119           printf("%.3d | ",i);
120           for(j=0;j<X.cols;j++)
121             printf("%.3g ",X.data[t++]);
122           printf("|\n");
123         }
124         printf("    --");
125         for(j=0;j<X.cols;j++)
126                 printf("----");
127         printf("-\n");
128
129 }/* end_of_display */
130
131 int maestro (int argc,char *argv[]) {
132
133 xbt_ex_t e;
134
135 int i,port,ask_result,step;
136
137 matrix_t A,B,C;
138 result_t result;
139
140 gras_socket_t from;
141
142         /*  Init the GRAS's infrastructure */
143         gras_init(&argc, argv);
144
145         gras_socket_t socket[MATRIX_SIZE*MATRIX_SIZE]; /* sockets for brodcast to other sensor */
146
147         /*  Initialize Matrixs */
148
149         A.rows=A.cols=MATRIX_SIZE;
150         B.rows=B.cols=MATRIX_SIZE;
151         C.rows=C.cols=MATRIX_SIZE;
152         
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);
156         
157         initmatrix(&A);
158         initmatrix(&B);
159         
160         /*  Get arguments and create sockets */
161         port=atoi(argv[1]);
162         //scatter();
163         //scatter_parl();
164         //multiplication();
165         //gather();
166         /****************************** Init Data Send *********************************/
167         int j=0;
168         init_data_t mydata;
169         for( i=2;i< argc;i+=3){
170                 
171                 TRY {
172                         socket[j]=gras_socket_client(argv[i],port);
173                 } CATCH(e) {
174                         RETHROW0("Unable to connect to the server: %s");
175                 }
176                 INFO2("Connected to %s:%d.",argv[i],port);
177                 
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)];;
182                 
183                 gras_msg_send(socket[j],gras_msgtype_by_name("init_data"),&mydata);
184                 j++;
185         } // end init Data Send
186
187         /******************************* multiplication ********************************/
188         INFO0("begin Multiplication");
189         for (step=1; step <= MATRIX_SIZE; step++){
190                 for (i=0; i< SENSOR_NBR; i++){
191                 TRY {
192                 gras_msg_send(socket[i], gras_msgtype_by_name("step"), &step);  /* initialize Mycol, MyRow, mydataA,mydataB*/
193         //      myrow,mycol,mydataA,mydataB
194                     } CATCH(e) {
195                 gras_socket_close(socket[i]);
196                 RETHROW0("Unable to send the msg : %s");
197                 }
198         }
199         INFO1("send to sensor to begin a %d th step",step);
200         /* wait for computing and sensor messages exchange */
201         i=0;
202         while  ( i< SENSOR_NBR){
203                 TRY {
204                 gras_msg_wait(600,gras_msgtype_by_name("step_ack"),&from,&mydata);
205                 } CATCH(e) {
206                 RETHROW0("I Can't get a init Data message from Maestro : %s");
207                 }
208                 i++;
209                 INFO1("Recive Ack step ack from %s",gras_socket_peer_name(from));
210         }
211         }
212         /*********************************  gather ***************************************/
213         
214         ask_result=0;
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]));
218         }
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;
223         }
224         /*    end of gather   */
225         INFO0 ("The Result of Multiplication is :");
226         display(C);
227
228 return 0;
229 } /* end_of_maestro */
230
231 /* **********************************************************************
232  * Sensor code
233  * **********************************************************************/
234
235 int sensor(int argc,char *argv[]) {
236
237   xbt_ex_t e; 
238
239   int step,port,l,result_ack=0; 
240   double bA,bB;
241
242   static int myrow,mycol;
243   static double mydataA,mydataB;
244   static double bC=0;
245
246   result_t result;
247  
248   gras_socket_t from,sock;  /* to recive from server for steps */
249
250   gras_socket_t socket_row[2],socket_column[2]; /* sockets for brodcast to other sensor */
251
252   /* Init the GRAS's infrastructure */
253
254   gras_init(&argc, argv);
255
256   /* Get arguments and create sockets */
257
258   port=atoi(argv[1]);
259   int i;
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);
263   }
264   INFO2("Launch %s (port=%d)",argv[0],port);
265
266   /*  Create my master socket */
267   sock = gras_socket_server(port);
268
269   /*  Register the known messages */
270   register_messages();
271
272   /* Recover my initialized Data and My Position*/
273   init_data_t mydata;
274   INFO0("wait for init Data");
275   TRY {
276           gras_msg_wait(600,gras_msgtype_by_name("init_data"),&from,&mydata);
277   } CATCH(e) {
278         RETHROW0("I Can't get a init Data message from Maestro : %s");
279   }
280
281   myrow=mydata.myrow;
282   mycol=mydata.mycol;
283   mydataA=mydata.a;
284   mydataB=mydata.b;
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
289
290   TRY {
291         gras_msg_wait(600,gras_msgtype_by_name("step"),&from,&step);
292   } CATCH(e) {
293           RETHROW0("I Can't get a Next Step message from Maestro : %s");
294   }
295
296   /*  Wait for sensors startup */
297   gras_os_sleep(1);
298
299   if (step < MATRIX_SIZE){
300           /* a row brodcast */
301           if(myrow==step){
302                   for (l=1;l < MATRIX_SIZE ;l++){
303                           gras_msg_send(socket_row[l], gras_msgtype_by_name("data"), &mydataB);
304                           bB=mydataB;
305                           INFO1("send my data B (%.3f) to my (horizontal) neighbors",bB);  
306                   }
307           }
308           else
309           {
310                   TRY {
311                           gras_msg_wait(600,gras_msgtype_by_name("data"),
312                                         &from,&bB);
313                   } CATCH(e) {
314                           RETHROW0("I Can't get a data message from row : %s");
315                   }
316                   INFO1("Recive data B (%.3f) from my neighbors",bB);
317           }
318           /* a column brodcast */       
319           if(mycol==step){
320                   for (l=1;l < MATRIX_SIZE ;l++){
321                           gras_msg_send(socket_column[l],gras_msgtype_by_name("data"), &mydataA);
322                           bA=mydataA;
323                           INFO1("send my data A (%.3f) to my (vertical) neighbors",bA);
324                   }
325           }
326           else
327           {
328                   TRY {
329                           gras_msg_wait(600,gras_msgtype_by_name("data"),
330                                         &from,&bA);
331                   } CATCH(e) {
332                           RETHROW0("I Can't get a data message from column : %s");
333                   }
334                   INFO1("Recive data A (%.3f) from my neighbors",bA);
335           }
336           bC+=bA*bB;
337           }
338           /* send a ack msg to Maestro */
339         
340           gras_msg_send(from,gras_msgtype_by_name("step_ack"),&step);
341         
342           INFO1("Send ack to maestro for to end %d th step",step);
343         
344           if(step==MATRIX_SIZE-1) break;
345
346   } while (step < MATRIX_SIZE);
347     /*  wait Message from maestro to send the result */
348  
349         result.value=bC;
350         result.i=myrow;
351         result.j=mycol;
352  
353           TRY {
354                   gras_msg_wait(600,gras_msgtype_by_name("ask_result"),
355                                 &from,&result_ack);
356           } CATCH(e) {
357                   RETHROW0("I Can't get a data message from row : %s");
358           }
359           /* send Result to Maestro */
360           TRY {
361                   gras_msg_send(from, gras_msgtype_by_name("result"),&result);
362           } CATCH(e) {
363                  // gras_socket_close(from);
364                   RETHROW0("Failed to send PING to server: %s");
365           }
366           INFO3(">>>>>>>> Result: %.3f sent to %s:%d <<<<<<<<",
367                 bC,
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);
371           gras_exit();
372           INFO0("Done.");
373           return 0;
374 } /* end_of_sensor */