2 /* pmm - parallel matrix multiplication "double diffusion" */
4 /* Copyright (c) 2006- Ahmed Harbaoui. All rights reserved. */
6 /* This program is free software; you can redistribute it and/or modify it
7 * under the terms of the license (GNU LGPL) which comes with this package. */
10 #define PROC_MATRIX_SIZE 3
11 #define SLAVE_COUNT (PROC_MATRIX_SIZE*PROC_MATRIX_SIZE)
13 #define DATA_MATRIX_SIZE 3
15 XBT_LOG_NEW_DEFAULT_CATEGORY(pmm,"Parallel Matrix Multiplication");
17 GRAS_DEFINE_TYPE(s_matrix,struct s_matrix {
20 double *data GRAS_ANNOTE(size, lines*rows);
22 typedef struct s_matrix matrix_t;
24 /* struct for recovering results */
25 GRAS_DEFINE_TYPE(s_result,struct s_result {
30 typedef struct s_result result_t;
32 /* struct to send initial data to slave */
33 GRAS_DEFINE_TYPE(s_assignment,struct s_assignment {
36 xbt_host_t line[PROC_MATRIX_SIZE];
37 xbt_host_t row[PROC_MATRIX_SIZE];
41 typedef struct s_assignment assignment_t;
43 /* register messages which may be sent (common to client and server) */
44 static void register_messages(void) {
45 gras_datadesc_type_t result_type;
46 gras_datadesc_type_t assignment_type;
47 gras_datadesc_set_const("PROC_MATRIX_SIZE",PROC_MATRIX_SIZE);
48 result_type=gras_datadesc_by_symbol(s_result);
49 assignment_type=gras_datadesc_by_symbol(s_assignment);
51 /* receive a final result from slave */
52 gras_msgtype_declare("result", result_type);
54 /* send from master to slave to assign a position and some data */
55 gras_msgtype_declare("assignment", assignment_type);
57 /* send from master to slave to ask a final result */
58 gras_msgtype_declare("ask_result", gras_datadesc_by_name("int"));
60 /* send from master to slave to indicate the begining of step */
61 gras_msgtype_declare("step", gras_datadesc_by_name("int"));
62 /* send from slave to master to indicate the end of the current step */
63 gras_msgtype_declare("step_ack", gras_datadesc_by_name("int"));
65 /* send data between slave */
66 gras_msgtype_declare("dataA", gras_datadesc_by_name("double"));
67 /* send data between slave */
68 gras_msgtype_declare("dataB", gras_datadesc_by_name("double"));
71 /* Function prototypes */
72 int slave (int argc,char *argv[]);
73 int master (int argc,char *argv[]);
76 /* **********************************************************************
78 * **********************************************************************/
80 /* Global private data */
88 /*** Function initilaze matrixs ***/
90 static void initmatrix(matrix_t *X){
93 for(i=0 ; i<(X->lines)*(X->rows); i++)
94 X->data[i]=1.0;//*rand()/(RAND_MAX+1.0);
95 } /* end_of_initmatrixs */
97 /*** Function Scatter Sequentiel ***/
99 static void scatter(){
101 }/* end_of_Scatter */
103 /*** Function: Scatter // ***/
105 static void scatter_parl(){
107 }/* end_of_Scatter // */
109 /*** Function: multiplication ***/
111 static void multiplication(){
113 }/* end_of_multiplication */
115 /*** Function: gather ***/
117 static void gather(){
121 /*** Function: Display Matrix ***/
123 static void display(matrix_t X){
128 for(j=0;j<X.rows;j++)
132 for(j=0;j<X.rows;j++)
136 for(i=0;i<X.lines;i++){
138 for(j=0;j<X.rows;j++)
139 printf("%.3g ",X.data[t++]);
143 for(j=0;j<X.rows;j++)
147 }/* end_of_display */
149 int master (int argc,char *argv[]) {
153 int i,port,ask_result,step;
160 /* Init the GRAS's infrastructure */
161 gras_init(&argc, argv);
163 xbt_host_t grid[SLAVE_COUNT]; /* The slaves */
164 gras_socket_t socket[SLAVE_COUNT]; /* sockets for brodcast to slaves */
166 /* Initialize Matrixs */
168 A.lines=A.rows=DATA_MATRIX_SIZE;
169 B.lines=B.rows=DATA_MATRIX_SIZE;
170 C.lines=C.rows=DATA_MATRIX_SIZE;
172 A.data=xbt_malloc0(sizeof(double)*DATA_MATRIX_SIZE*DATA_MATRIX_SIZE);
173 B.data=xbt_malloc0(sizeof(double)*DATA_MATRIX_SIZE*DATA_MATRIX_SIZE);
174 C.data=xbt_malloc0(sizeof(double)*DATA_MATRIX_SIZE*DATA_MATRIX_SIZE);
179 /* Get arguments and create sockets */
186 /************************* Init Data Send *********************************/
190 for( i=1;i< argc;i++){
191 grid[i-1]=xbt_host_from_string(argv[i]);
192 socket[i-1]=gras_socket_client(grid[i-1]->name,grid[i-1]->port);
194 INFO2("Connected to %s:%d.",grid[i-1]->name,grid[i-1]->port);
198 for(i=0 ; i<SLAVE_COUNT; i++){
199 assignment_t assignment;
202 assignment.linepos=line; // My line
203 assignment.rowpos=row; // My row
207 for (j=0; j<PROC_MATRIX_SIZE; j++) {
208 assignment.row[j] = grid[ j*PROC_MATRIX_SIZE+(row-1) ] ;
209 assignment.line[j] = grid[ (line-1)*PROC_MATRIX_SIZE+j ] ;
213 if (row > PROC_MATRIX_SIZE) {
218 assignment.a=A.data[(line-1)*PROC_MATRIX_SIZE+(row-1)];
219 assignment.b=B.data[(line-1)*PROC_MATRIX_SIZE+(row-1)];;
221 gras_msg_send(socket[i],gras_msgtype_by_name("assignment"),&assignment);
222 // INFO3("Send assignment to %s : data A= %.3g & data B= %.3g",
223 // gras_socket_peer_name(socket[i]),mydata.a,mydata.b);
228 /******************************* multiplication ********************************/
229 INFO0("XXXXXXXXXXXXXXXXXXXXXX begin Multiplication");
231 for (step=1; step <= PROC_MATRIX_SIZE; step++){
232 for (i=0; i< SLAVE_COUNT; i++){
234 gras_msg_send(socket[i], gras_msgtype_by_name("step"), &step);
236 gras_socket_close(socket[i]);
237 RETHROW0("Unable to send the msg : %s");
240 INFO1("send to slave to begin a %d th step",step);
242 /* wait for computing and slave messages exchange */
245 while ( i< SLAVE_COUNT) {
247 gras_msg_wait(1300,gras_msgtype_by_name("step_ack"),&from,&step_ack);
249 RETHROW0("Can't get a Ack step message from slave : %s");
252 DEBUG3("Got step ack from %s (got %d of %d)",
253 gras_socket_peer_name(from), i, SLAVE_COUNT);
256 /********************************* gather ***************************************/
259 for( i=1;i< argc;i++){
260 gras_msg_send(socket[i],gras_msgtype_by_name("ask_result"),&ask_result);
261 INFO1("Send (Ask Result) message to %s",gras_socket_peer_name(socket[i]));
263 /* wait for results */
264 for( i=1;i< argc;i++){
265 gras_msg_wait(600,gras_msgtype_by_name("result"),&from,&result);
266 C.data[(result.i-1)*DATA_MATRIX_SIZE+(result.j-1)]=result.value;
269 INFO0 ("The Result of Multiplication is :");
273 } /* end_of_master */
275 /* **********************************************************************
277 * **********************************************************************/
279 int slave(int argc,char *argv[]) {
283 int step,port,l,result_ack=0;
287 double mydataA,mydataB;
292 gras_socket_t from,sock; /* to exchange data with my neighbor */
293 gras_socket_t master; /* for the barrier */
295 /* sockets for brodcast to other slave */
296 gras_socket_t socket_line[PROC_MATRIX_SIZE-1];
297 gras_socket_t socket_row[PROC_MATRIX_SIZE-1];
299 /* Init the GRAS's infrastructure */
301 gras_init(&argc, argv);
303 /* Get arguments and create sockets */
307 /* Create my master socket */
308 sock = gras_socket_server(port);
311 /* Register the known messages */
314 /* Recover my initialized Data and My Position*/
315 assignment_t assignment;
316 INFO2("Launch %s (port=%d); wait for my enrole message",argv[0],port);
318 gras_msg_wait(600,gras_msgtype_by_name("assignment"),&master,&assignment);
320 RETHROW0("Can't get my assignment from master : %s");
322 myline = assignment.linepos;
323 myrow = assignment.rowpos;
324 mydataA = assignment.a;
325 mydataB = assignment.b;
326 INFO4("Receive my pos (%d,%d) and assignment ( A=%.3g | B=%.3g )",
327 myline,myrow,mydataA,mydataB);
329 /* Get my neighborhood from the assignment message */
331 for (i=0,j=0 ; i<PROC_MATRIX_SIZE ; i++){
332 if (strcmp(gras_os_myname(),assignment.line[i]->name)) {
333 socket_line[j]=gras_socket_client(assignment.line[i]->name,
334 assignment.line[i]->port);
336 //INFO3("Line neighbour %d: %s:%d",j,mydata.line[i]->name,mydata.line[i]->port);
338 xbt_host_free(assignment.line[i]);
340 for (i=0,j=0 ; i<PROC_MATRIX_SIZE ; i++){
341 if (strcmp(gras_os_myname(),assignment.row[i]->name)) {
342 socket_row[j]=gras_socket_client(assignment.row[i]->name,
343 assignment.row[i]->port);
344 //INFO3("Row neighbour %d : %s:%d",j,mydata.row[i]->name,mydata.row[i]->port);
347 xbt_host_free(assignment.row[i]);
352 do { //repeat until compute Cb
353 step=PROC_MATRIX_SIZE+1; // just intilization for loop
356 gras_msg_wait(200,gras_msgtype_by_name("step"),NULL,&step);
358 RETHROW0("Can't get a Next Step message from master : %s");
360 INFO1("Receive a step message from master: step = %d ",step);
362 if (step < PROC_MATRIX_SIZE ){
363 /* a line brodcast */
364 gras_os_sleep(3); // IL FAUT EXPRIMER LE TEMPS D'ATTENTE EN FONCTION DE "SLAVE_COUNT"
366 INFO2("step(%d) = Myline(%d)",step,myline);
367 for (l=1;l < PROC_MATRIX_SIZE ;l++){
368 gras_msg_send(socket_row[l-1], gras_msgtype_by_name("dataB"), &mydataB);
370 INFO1("send my data B (%.3g) to my (vertical) neighbors",bB);
374 INFO2("step(%d) <> Myline(%d)",step,myline);
376 gras_msg_wait(600,gras_msgtype_by_name("dataB"),&from,&bB);
378 RETHROW0("Can't get a data message from line : %s");
380 INFO2("Receive data B (%.3g) from my neighbor: %s",bB,gras_socket_peer_name(from));
384 for (l=1;l < PROC_MATRIX_SIZE ;l++){
385 gras_msg_send(socket_line[l-1],gras_msgtype_by_name("dataA"), &mydataA);
387 INFO1("send my data A (%.3g) to my (horizontal) neighbors",bA);
393 gras_msg_wait(1200,gras_msgtype_by_name("dataA"), &from,&bA);
395 RETHROW0("Can't get a data message from row : %s");
397 INFO2("Receive data A (%.3g) from my neighbor : %s ",bA,gras_socket_peer_name(from));
400 INFO1(">>>>>>>> My BC = %.3g",bC);
402 /* send a ack msg to master */
404 gras_msg_send(master,gras_msgtype_by_name("step_ack"),&step);
406 INFO1("Send ack to master for to end %d th step",step);
408 if(step==PROC_MATRIX_SIZE-1) break;
410 } while (step < PROC_MATRIX_SIZE);
411 /* wait Message from master to send the result */
418 gras_msg_wait(600,gras_msgtype_by_name("ask_result"),
419 &master,&result_ack);
421 RETHROW0("Can't get a data message from line : %s");
423 /* send Result to master */
425 gras_msg_send(master, gras_msgtype_by_name("result"),&result);
427 // gras_socket_close(from);
428 RETHROW0("Failed to send PING to server: %s");
430 INFO3(">>>>>>>> Result: %.3f sent to %s:%d <<<<<<<<",
432 gras_socket_peer_name(master),gras_socket_peer_port(master));
433 /* Free the allocated resources, and shut GRAS down */
434 gras_socket_close(master);
435 gras_socket_close(from);