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. */
11 XBT_LOG_NEW_DEFAULT_CATEGORY(pmm,"Messages specific to this example");
13 GRAS_DEFINE_TYPE(s_matrix,struct s_matrix {
16 double *data GRAS_ANNOTE(size, rows*cols);
18 typedef struct s_matrix matrix_t;
20 /* struct for recovering results */
21 GRAS_DEFINE_TYPE(s_result,struct s_result {
26 typedef struct s_result result_t;
28 /* struct to send initial data to sensor */
29 GRAS_DEFINE_TYPE(s_init_data,struct s_init_data {
35 typedef struct s_init_data init_data_t;
37 /* register messages which may be sent (common to client and server) */
38 static void register_messages(void) {
39 gras_datadesc_type_t result_type;
40 gras_datadesc_type_t init_data_type;
41 result_type=gras_datadesc_by_symbol(s_result);
42 init_data_type=gras_datadesc_by_symbol(s_init_data);
44 gras_msgtype_declare("result", result_type);
45 gras_msgtype_declare("init_data", init_data_type);
47 gras_msgtype_declare("ask_result", gras_datadesc_by_name("int"));
48 gras_msgtype_declare("step", gras_datadesc_by_name("int"));
49 gras_msgtype_declare("step_ack", gras_datadesc_by_name("int"));
50 gras_msgtype_declare("data", gras_datadesc_by_name("int"));
53 /* Function prototypes */
54 int maestro (int argc,char *argv[]);
55 int sensor (int argc,char *argv[]);
57 /* **********************************************************************
59 * **********************************************************************/
61 /* Global private data */
69 static int maestro_cb_data_handler(gras_msg_cb_ctx_t ctx, void *payload) {
72 /* 1. Get the payload into the msg variable */
73 int msg=*(int*)payload_data;
75 gras_socket_t expeditor = gras_msg_cb_ctx_from(ctx);
79 /* 8. Make sure we don't leak sockets */
80 gras_socket_close(expeditor);
82 /* 9. Tell GRAS that we consummed this message */
84 } /* end_of_maestro_cb_data_handler */
86 /*** Function initilaze matrixs ***/
88 static void initmatrix(matrix_t *X){
90 for(i=0 ; i<X.rows*X.cols; i++)
91 X.data[i]=1.0;//1.0*rand()/(RAND_MAX+1.0);
93 } /* end_of_initmatrixs */
95 /*** Function Scatter Sequentiel ***/
97 static void scatter(){
101 /*** Function: Scatter // ***/
103 static void scatter_parl(){
105 }/* end_of_Scatter // */
107 /*** Function: multiplication ***/
109 static void multiplication(){
113 for (step=1; step <= MATRIX_SIZE; step++){
114 for (i=0; i< nbr_sensor; i++){
116 gras_msg_send(proc[(i/3)+1][(i%3)+1], gras_msgtype_by_name("step"), &step); /* initialize Mycol, MyRow, mydataA,mydataB*/
118 myrow,mycol,mydataA,mydataB
120 gras_socket_close(proc[(i/3)+1][(i%3)+1]);
121 RETHROW0("Unable to send the msg : %s");
124 /* wait for computing and sensor messages exchange */
126 gras_msg_wait(600,gras_msgtype_by_name("init_data"),&from,&mydata);
128 RETHROW0("I Can't get a init Data message from Maestro : %s");
132 }/* end_of_multiplication */
134 /*** Function: gather ***/
136 static void gather(){
141 /*** Function: Display Matrix ***/
143 static void display(matrix_t X){
148 for(j=0;j<X.cols;j++)
152 for(j=0;j<X.cols;j++)
156 for(i=0;i<X.rows;i++){
158 for(j=0;j<X.cols;j++)
159 printf("%.3g ",X.data[t++]);
163 for(j=0;j<X.cols;j++)
167 }/* end_of_display */
169 int maestro (int argc,char *argv[]) {
172 int i,ask_result,step;
176 gras_socket_t socket[MATRIX_SIZE*MATRIX_SIZE]; /* sockets for brodcast to other sensor */
179 /* Initialize Matrixs */
181 A.rows=A.cols=MATRIX_SIZE;
182 B.rows=B.cols=MATRIX_SIZE;
183 C.rows=C.cols=MATRIX_SIZE;
185 A.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
186 B.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
187 C.data=xbt_malloc0(sizeof(double)*MATRIX_SIZE*MATRIX_SIZE);
192 /* Init the GRAS's infrastructure */
193 gras_init(&argc, argv);
194 /* Get arguments and create sockets */
196 //scatter();multiplication();gather();
198 /****************************** Init Data Send *********************************/
201 for( i=2;i< argc;i+=3){
204 socket[j]=gras_socket_client(argv[i],port);
207 RETHROW0("Unable to connect to the server: %s");
209 INFO2("Connected to %s:%d.",argv[i],port);
211 mydata.myrow=argv[i+1]; // My rank of row
212 mydata.mycol=argv[i+2]; // My rank of column
213 mydata.a=A.data[(mydata.myrow-1)*MATRIX_SIZE+(mydata.mycol-1)];
214 mydata.b=B.data[(mydata.myrow-1)*MATRIX_SIZE+(mydata.mycol-1)];;
216 gras_msg_send(socket[j],gras_msgtype_by_name("init_data"),&mydata);
218 } // end init Data Send
220 /******************************* multiplication ********************************/
222 for (step=1; step <= MATRIX_SIZE; step++){
223 for (i=0; i< nbr_sensor; i++){
225 gras_msg_send(socket[i], gras_msgtype_by_name("step"), &step); /* initialize Mycol, MyRow, mydataA,mydataB*/
227 myrow,mycol,mydataA,mydataB
229 gras_socket_close(socket[i]);
230 RETHROW0("Unable to send the msg : %s");
234 /* wait for computing and sensor messages exchange */
235 for (i=0; i< nbr_sensor; i++){
237 gras_msg_wait(600,gras_msgtype_by_name(""),&from,&mydata);
239 RETHROW0("I Can't get a init Data message from Maestro : %s");
243 /********************************* gather ***************************************/
246 for( i=1;i< argc;i++){
247 gras_msg_send(socket[i],gras_msgtype_by_name("ask_result"),&ask_result);
249 /* wait for results */
250 for( i=1;i< argc;i++){
251 gras_msg_wait(600,gras_msgtype_by_name("result"),&from,&result);
252 C.data[(result.i-1)*MATRIX_SIZE+(result.j-1)]=result.value;
258 } /* end_of_maestro */
260 /* **********************************************************************
262 * **********************************************************************/
264 int sensor(int argc,char *argv[]) {
269 static int myrow,mycol;
270 static double mydataA,mydataB;
274 gras_socket_t from; /* to recive from server for steps */
276 gras_socket_t socket_row[2],socket_column[2]; /* sockets for brodcast to other sensor */
278 /* Init the GRAS's infrastructure */
280 gras_init(&argc, argv);
282 /* Get arguments and create sockets */
286 for (i=1;i<MATRIX_SIZE;i++){
287 socket_row[i]=gras_socket_client(argv[i+1],port);
288 socket_column[i]=gras_socket_client(argv[i+MATRIX_SIZE],port);
290 INFO2("Launch %s (port=%d)",argv[0],port);
292 /* Create my master socket */
293 sock = gras_socket_server(port);
295 /* Register the known messages */
298 /* Recover my initialized Data and My Position*/
302 gras_msg_wait(600,gras_msgtype_by_name("init_data"),&from,&mydata);
304 RETHROW0("I Can't get a init Data message from Maestro : %s");
311 INFO4("Recover MY POSITION (%d,%d) and MY INIT DATA ( A=%.3g | B=%.3g )",
312 myrow,mycol,mydataA,mydataB);
315 do { //repeat until compute Cb
316 step=MATRIX_SIZE+1; // juste intilization for loop
319 gras_msg_wait(600,gras_msgtype_by_name("step"),&from,&step);
321 RETHROW0("I Can't get a Next Step message from Maestro : %s");
324 /* Wait for sensors startup */
327 if (step < MATRIX_SIZE){
330 for (l=1;l < MATRIX_SIZE ;l++){
331 gras_msg_send(socket_row[l], gras_msgtype_by_name("data"), &mydataB);
338 gras_msg_wait(600,gras_msgtype_by_name("data"),
341 RETHROW0("I Can't get a data message from row : %s");
344 /* a column brodcast */
346 for (l=1;l < MATRIX_SIZE ;l++){
347 gras_msg_send(socket_column[l],gras_msgtype_by_name("data"), &mydataA);
354 gras_msg_wait(600,gras_msgtype_by_name("data"),
357 RETHROW0("I Can't get a data message from column : %s");
362 /* send a ack msg to Maestro */
364 gras_msg_send(from,gras_msgtype_by_name("step_ack"),&step);
366 INFO1("Send ack to maestro for to end %d th step",step);
368 if(step==MATRIX_SIZE-1) break;
370 } while (step < MATRIX_SIZE);
371 /* wait Message from maestro to send the result */
372 /*after finished the bC computing */
374 gras_msg_wait(600,gras_msgtype_by_name("result"),
377 RETHROW0("I Can't get a data message from row : %s");
379 /* 5. send Result to the Maestro */
381 gras_msg_send(from, gras_msgtype_by_name("result"),&bC);
383 gras_socket_close(from);
384 RETHROW0("Failed to send PING to server: %s");
386 INFO3(">>>>>>>> Result: %d sent to %s:%d <<<<<<<<",
388 gras_socket_peer_name(from),gras_socket_peer_port(from));
389 /* Free the allocated resources, and shut GRAS down */
390 gras_socket_close(from);
394 } /* end_of_sensor */