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,"Parallel Matrix Multiplication");
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 slave */
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 slave
46 gras_msgtype_declare("init_data", init_data_type); // send from master to slave to initialize data bA,bB
48 gras_msgtype_declare("ask_result", gras_datadesc_by_name("int")); // send from master to slave to ask a final result
49 gras_msgtype_declare("step", gras_datadesc_by_name("int"));// send from master to slave to indicate the begining of step
50 gras_msgtype_declare("step_ack", gras_datadesc_by_name("int"));//send from slave to master to indicate the end of the current step
51 gras_msgtype_declare("dataA", gras_datadesc_by_name("double"));// send data between slave
52 gras_msgtype_declare("dataB", gras_datadesc_by_name("double"));// send data between slave
55 /* Function prototypes */
56 int slave (int argc,char *argv[]);
57 int master (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 master (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 slave */
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< SLAVE_COUNT; 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 slave to begin a %d th step",step);
206 /* wait for computing and slave messages exchange */
209 while ( i< SLAVE_COUNT){
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 slave : %s");
216 INFO3("Receive Ack step ack from %s (got %d of %d)",
217 gras_socket_peer_name(from),
221 /********************************* gather ***************************************/
224 for( i=1;i< argc;i++){
225 gras_msg_send(socket[i],gras_msgtype_by_name("ask_result"),&ask_result);
226 INFO1("Send (Ask Result) message to %s",gras_socket_peer_name(socket[i]));
228 /* wait for results */
229 for( i=1;i< argc;i++){
230 gras_msg_wait(600,gras_msgtype_by_name("result"),&from,&result);
231 C.data[(result.i-1)*MATRIX_SIZE+(result.j-1)]=result.value;
234 INFO0 ("The Result of Multiplication is :");
238 } /* end_of_master */
240 /* **********************************************************************
242 * **********************************************************************/
244 int slave(int argc,char *argv[]) {
248 int step,port,l,result_ack=0;
252 double mydataA,mydataB;
259 gras_socket_t from,sock; /* to recive from server for steps */
261 gras_socket_t socket_row[MATRIX_SIZE-1],socket_column[MATRIX_SIZE-1]; /* sockets for brodcast to other slave */
263 /* Init the GRAS's infrastructure */
265 gras_init(&argc, argv);
267 /* Get arguments and create sockets */
271 /* Create my master socket */
272 sock = gras_socket_server(port);
273 INFO2("Launch %s (port=%d)",argv[0],port);
274 gras_os_sleep(1); //wait to start all slaves
277 for (i=1;i<MATRIX_SIZE;i++){
278 socket_row[i-1]=gras_socket_client(argv[i+1],port);
279 socket_column[i-1]=gras_socket_client(argv[i+MATRIX_SIZE],port);
282 /* Register the known messages */
285 /* Recover my initialized Data and My Position*/
287 INFO0("wait for init Data");
289 gras_msg_wait(600,gras_msgtype_by_name("init_data"),&from,&mydata);
291 RETHROW0("I Can't get a init Data message from master : %s");
297 INFO4("Recive MY POSITION (%d,%d) and MY INIT DATA ( A=%.3g | B=%.3g )",
298 myrow,mycol,mydataA,mydataB);
301 do { //repeat until compute Cb
302 step=MATRIX_SIZE+1; // just intilization for loop
305 gras_msg_wait(200,gras_msgtype_by_name("step"),&from,&step);
307 RETHROW0("I Can't get a Next Step message from master : %s");
309 INFO1("Recive a step message from master: step = %d ",step);
311 if (step < MATRIX_SIZE ){
313 gras_os_sleep(3); // IL FAUT EXPRIMER LE TEMPS D'ATTENTE EN FONCTION DE "SLAVE_COUNT"
315 INFO2("step(%d) = Myrow(%d)",step,myrow);
316 for (l=1;l < MATRIX_SIZE ;l++){
317 gras_msg_send(socket_column[l-1], gras_msgtype_by_name("dataB"), &mydataB);
319 INFO1("send my data B (%.3g) to my (vertical) neighbors",bB);
323 INFO2("step(%d) <> Myrow(%d)",step,myrow);
325 gras_msg_wait(600,gras_msgtype_by_name("dataB"),
328 RETHROW0("I Can't get a data message from row : %s");
330 INFO2("Recive data B (%.3g) from my neighbor: %s",bB,gras_socket_peer_name(from));
332 /* a column brodcast */
334 for (l=1;l < MATRIX_SIZE ;l++){
335 gras_msg_send(socket_row[l-1],gras_msgtype_by_name("dataA"), &mydataA);
337 INFO1("send my data A (%.3g) to my (horizontal) neighbors",bA);
343 gras_msg_wait(1200,gras_msgtype_by_name("dataA"),
346 RETHROW0("I Can't get a data message from column : %s");
348 INFO2("Recive data A (%.3g) from my neighbor : %s ",bA,gras_socket_peer_name(from));
351 INFO1(">>>>>>>> My BC = %.3g",bC);
353 /* send a ack msg to master */
355 gras_msg_send(from,gras_msgtype_by_name("step_ack"),&step);
357 INFO1("Send ack to master for to end %d th step",step);
359 if(step==MATRIX_SIZE-1) break;
361 } while (step < MATRIX_SIZE);
362 /* wait Message from master to send the result */
369 gras_msg_wait(600,gras_msgtype_by_name("ask_result"),
372 RETHROW0("I Can't get a data message from row : %s");
374 /* send Result to master */
376 gras_msg_send(from, gras_msgtype_by_name("result"),&result);
378 // gras_socket_close(from);
379 RETHROW0("Failed to send PING to server: %s");
381 INFO3(">>>>>>>> Result: %.3f sent to %s:%d <<<<<<<<",
383 gras_socket_peer_name(from),gras_socket_peer_port(from));
384 /* Free the allocated resources, and shut GRAS down */
385 gras_socket_close(from);