bc_domboss.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include "eg_mempool.h"
00003 
00004 //#include "tsp.h"
00005 
00006 #ifndef CCtsp_DOMINO_PORT
00007 #define CCtsp_DOMINO_PORT ((unsigned short) 24869)
00008 #endif
00009 
00010 #ifndef CCtsp_DOMINO_WORK
00011 #define CCtsp_DOMINO_WORK        'A'
00012 #endif
00013 #ifndef CCtsp_DOMINO_GRAPH
00014 #define CCtsp_DOMINO_GRAPH       'G'
00015 #endif
00016 #ifndef CCtsp_DOMINO_NO
00017 #define CCtsp_DOMINO_NO          'N'
00018 #endif
00019 #ifndef CCtsp_DOMINO_RECEIVE
00020 #define CCtsp_DOMINO_RECEIVE     'R'
00021 #endif
00022 #ifndef CCtsp_DOMINO_SEND
00023 #define CCtsp_DOMINO_SEND        'S'
00024 #endif
00025 #ifndef CCtsp_DOMINO_WAIT
00026 #define CCtsp_DOMINO_WAIT        'W'
00027 #endif
00028 #ifndef CCtsp_DOMINO_YES
00029 #define CCtsp_DOMINO_YES         'Y'
00030 #endif
00031 #ifndef CCtsp_DOMINO_EXIT
00032 #define CCtsp_DOMINO_EXIT        'X'
00033 #endif
00034 
00035 #include "bc_util.h"
00036 #include "eg_util.h"
00037 
00038 #include "eg_mempool.h"
00039 #include "eg_list.h"
00040 #include "eg_dgraph.h"
00041 
00042 #include "dp_config.h"
00043 
00044 #include "eg_ddomino.h"
00045 #include "eg_nettype.h"
00046 #include "eg_util.h"
00047 
00048 #define DOM_STAT_OPEN 0
00049 #define DOM_STAT_DONE 1
00050 #define DOM_STAT_WORK 2
00051 
00052 int main (int ac,
00053           char **av)
00054 {
00055   int id,
00056     gid,
00057     domino_k;
00058   unsigned int i,
00059     nremain,
00060     curloc,
00061     try;
00062   int rval = 0,
00063     ndominoes;
00064   CC_SPORT *lport = (CC_SPORT *) NULL;
00065   CC_SFILE *s;
00066   double rtime,
00067     cumtime = 0.0,
00068     graph_time = 0.0;
00069   unsigned int *status = (unsigned int *) NULL;
00070   char request;
00071 
00072   int new_id = -1,
00073     current_g_id = -1;
00074   unsigned int nnodes = 0,
00075     nedges = 0,
00076    *edges = 0;
00077   double *weight = 0;
00078   double ddp_heuristic_maxtime;
00079 
00080   EGlist_t *D;
00081   EGlistNode_t *l_it;
00082   EGmemPool_t *mem;
00083   EGnetDdom_t *net_ddom;
00084 
00085   mem = EGnewMemPool (8192, EGmemPoolNewSize, EGmemPoolNewSize (1));
00086   D = EGnewList (mem);
00087 
00088   if (ac != 1)
00089   {
00090     fprintf (stderr, "Usage: %s (no arguments)\n", av[0]);
00091     rval = 1;
00092     goto CLEANUP;
00093   }
00094 
00095   printf ("BEGINNING DOMINO NET PROCESSING\n\n");
00096   fflush (stdout);
00097 
00098   lport = CCutil_snet_listen (CCtsp_DOMINO_PORT);
00099   if (lport == (CC_SPORT *) NULL)
00100   {
00101     fprintf (stderr, "CCutil_snet_listen failed\n");
00102     rval = 1;
00103     goto CLEANUP;
00104   }
00105 
00106   while (1)
00107   {
00108 
00109     /* First, wait until we receive a request of type CCtsp_DOMINO_GRAPH.
00110      * or, until we are told to shut down.                                */
00111 
00112     request = 0;
00113     do
00114     {
00115       s = CCutil_snet_receive (lport);
00116       if (!s)
00117       {
00118         fprintf (stderr, "CCutil_snet_receive failed, ignoring\n");
00119         continue;
00120       }
00121 
00122       if (CCutil_sread_char (s, &request))
00123       {
00124         fprintf (stderr, "CCutil_sread_char failed, abort con\n");
00125         CCutil_sclose (s);
00126         continue;
00127       }
00128 
00129       switch (request)
00130       {
00131       case CCtsp_DOMINO_RECEIVE:
00132         rval = CCutil_swrite_char (s, CCtsp_DOMINO_NO);
00133         CCcheck_rval (rval, "CCutil_swrite_char failed (NO)");
00134         CCutil_sclose (s);
00135         break;
00136       case CCtsp_DOMINO_EXIT:
00137         printf ("Shutting down the domino boss\n");
00138         fflush (stdout);
00139         CCutil_sclose (s);
00140         rval = 1;
00141         goto CLEANUP;
00142       case CCtsp_DOMINO_GRAPH:
00143         break;
00144       case CCtsp_DOMINO_SEND:
00145         rval = CCutil_swrite_char (s, CCtsp_DOMINO_NO);
00146         CCcheck_rval (rval, "CCutil_swrite_char failed (NO)");
00147         CCutil_sclose (s);
00148         break;
00149         //fprintf (stderr, "No graph, cannot send dominos\n");
00150         //CCutil_sclose (s);
00151         //rval = 1;  goto CLEANUP;
00152       default:
00153         fprintf (stderr, "Invalid request %c\n", request);
00154       }
00155     } while (request != CCtsp_DOMINO_GRAPH);
00156 
00157     /* A request to send us a graph has come in. Receive the graph.       */
00158 
00159     /* Get the graph number:                                              */
00160 
00161     rval = CCutil_sread_int (s, &new_id);
00162     CCcheck_rval (rval, "receive_current_g_id failed");
00163 
00164     if (new_id <= current_g_id)
00165       new_id = current_g_id + 1;
00166 
00167     current_g_id = new_id;
00168 
00169     fprintf (stdout, "Domboss: New graph id = %d.\n", current_g_id);
00170     fflush (stdout);
00171 
00172     rval = CCutil_sread_int (s, &domino_k);
00173     CCcheck_rval (rval, "receive_domino_k failed");
00174 
00175     rval = CCutil_sread_double (s, &ddp_heuristic_maxtime);
00176     CCcheck_rval (rval, "receive_heuristic_maxtime failed");
00177 
00178     rval = EGreceiveNetGraph (s, &nnodes, &nedges, &edges, &weight, mem);
00179     CCcheck_rval (rval, "receive_graph failed");
00180 
00181     fprintf (stdout, "Domboss: nnodes = %d   nedges = %d.\n", nnodes, nedges);
00182     fflush (stdout);
00183 
00184     /* For each node we maintain a status (to keep track of if 
00185      * the cycle corresponding to it has been obtained                    */
00186 
00187     status = CC_SAFE_MALLOC (nnodes, unsigned int);
00188     CCcheck_NULL (status, "out of memory for status array");
00189 
00190     for (i = 0; i < nnodes; i++)
00191       status[i] = DOM_STAT_OPEN;
00192 
00193     nremain = nnodes;
00194     curloc = 0;
00195 
00196     /* We wait until all of the node problems have been solved.          */
00197 
00198     while (nremain)
00199     {
00200       request = 0;
00201       do
00202       {
00203 
00204         /* Open up a port                                            */
00205 
00206         s = CCutil_snet_receive (lport);
00207         if (!s)
00208         {
00209           fprintf (stderr, "CCutil_snet_receive failed, ignoring\n");
00210           continue;
00211         }
00212 
00213         /* Get the next request.                                     */
00214 
00215         if (CCutil_sread_char (s, &request))
00216         {
00217           fprintf (stderr, "CCutil_sread_char failed, abort con\n");
00218           CCutil_sclose (s);
00219           continue;
00220         }
00221 
00222         /* We wait for the grunts to ask for some work or for them to
00223          * send us dominoes. That is, we wait for the signal 
00224          * DOMINO_RECEIVE.                                          */
00225 
00226         switch (request)
00227         {
00228         case CCtsp_DOMINO_RECEIVE:
00229           rval = CCutil_swrite_char (s, CCtsp_DOMINO_YES);
00230           CCcheck_rval (rval, "CCutil_swrite_char failed (YES)");
00231           break;
00232         case CCtsp_DOMINO_EXIT:
00233           printf ("Shutting down the domino boss\n");
00234           fflush (stdout);
00235           CCutil_sclose (s);
00236           rval = 1;
00237           goto CLEANUP;
00238         case CCtsp_DOMINO_GRAPH:
00239           fprintf (stderr, "Cannot receive new graph\n");
00240           CCutil_sclose (s);
00241           rval = 1;
00242           goto CLEANUP;
00243         case CCtsp_DOMINO_SEND:
00244           rval = CCutil_swrite_char (s, CCtsp_DOMINO_NO);
00245           CCcheck_rval (rval, "CCutil_swrite_char failed (NO)");
00246           CCutil_sclose (s);
00247           break;
00248         default:
00249           fprintf (stderr, "Invalid request %c\n", request);
00250         }
00251       } while (request != CCtsp_DOMINO_RECEIVE);
00252 
00253       /* We ask what graph id it has in memory.                         */
00254 
00255       rval = CCutil_sread_int (s, &gid);
00256       if (rval)
00257       {
00258         fprintf (stderr, "CCutil_sread_int failed, abort con\n");
00259         rval = 0;
00260         goto CLOSE_CONN;
00261       }
00262 
00263       /* We ask what node the grunt is solving the problem for.         */
00264 
00265       rval = CCutil_sread_int (s, &id);
00266       if (rval)
00267       {
00268         fprintf (stderr, "CCutil_sread_int failed, abort con\n");
00269         rval = 0;
00270         goto CLOSE_CONN;
00271       }
00272 
00273       /* If the grunt replies '-1' it means that he is not solving any */
00274 
00275       if (id != -1)
00276       {
00277 
00278         rval = CCutil_sread_double (s, &rtime);
00279 
00280         if (rval)
00281         {
00282           fprintf (stderr, "CCutil_sread_double failed, abort con\n");
00283           rval = 0;
00284           goto CLOSE_CONN;
00285         }
00286 
00287         /* If the grunt has a graph different than what we have.     */
00288         if (gid != current_g_id)
00289         {
00290           printf ("Finished node with graph %d, ignoring\n", gid);
00291           fflush (stdout);
00292 
00293           rval = CCutil_swrite_char (s, CCtsp_DOMINO_NO);
00294           CCcheck_rval (rval, "CCutil_swrite_char failed (NO)");
00295         }
00296 
00297         /* If the grunt solved a node which has already been solved. */
00298         else if (status[id] == DOM_STAT_DONE)
00299         {
00300           rval = CCutil_swrite_char (s, CCtsp_DOMINO_NO);
00301           CCcheck_rval (rval, "CCutil_swrite_char failed (NO)");
00302 
00303           printf ("Finished completed node %d, ignoring\n", id);
00304           fflush (stdout);
00305         }
00306 
00307         /* We accept the dominoes that the grunt has.                */
00308         else
00309         {
00310           rval = CCutil_swrite_char (s, CCtsp_DOMINO_YES);
00311           CCcheck_rval (rval, "CCutil_swrite_char failed (YES)");
00312 
00313           rval = CCutil_sread_int (s, &ndominoes);
00314           CCcheck_rval (rval, "receive_ndominoes failed");
00315 
00316           for (i = 0; i < (unsigned) ndominoes; i++)
00317           {
00318             rval = EGreceiveNetDomino (s, &net_ddom, mem);
00319             CCcheck_rval (rval, "receive_dominoes failed");
00320             EGlistPushBack (D, net_ddom);
00321           }
00322 
00323           status[id] = DOM_STAT_DONE;
00324           cumtime += rtime;
00325           graph_time += rtime;
00326           nremain--;
00327 
00328           printf
00329             ("\rDONE %5d:  %6.2f sec, %9.2f graph, %9.2f total, %5d remaining.",
00330              id, rtime, graph_time, cumtime, nremain);
00331           fflush (stdout);
00332         }
00333       }
00334 
00335       /* We must determine which job is to be assigned to the grunt. We 
00336        * will assign the one with lowest cardinality which is still
00337        * available. We loop around so as to re-assign ids.              */
00338 
00339       try = 0;
00340       while (status[curloc % nnodes] == DOM_STAT_DONE && try < nnodes)
00341       {
00342         curloc++;
00343         try++;
00344       }
00345 
00346       /* If there is some job which is not done, assign it.             */
00347 
00348       if (try < nnodes)
00349       {
00350         if (gid != current_g_id)
00351         {
00352           rval = CCutil_swrite_char (s, CCtsp_DOMINO_GRAPH);
00353           CCcheck_rval (rval, "CCutil_swrite_char failed (GRAPH)");
00354                     /*** SEND GRAPH ***/
00355           rval = CCutil_swrite_int (s, current_g_id);
00356           CCcheck_rval (rval, "send_graph_id failed");
00357           rval = EGsendNetGraph (s, nnodes, nedges, edges, weight);
00358           CCcheck_rval (rval, "send_graph failed");
00359           rval = CCutil_swrite_int (s, domino_k);
00360           CCcheck_rval (rval, "send_domino_k failed");
00361           rval = CCutil_swrite_double (s, ddp_heuristic_maxtime);
00362           CCcheck_rval (rval, "send_ddp_heuristic_maxtime failed");
00363         }
00364         else
00365         {
00366           rval = CCutil_swrite_char (s, CCtsp_DOMINO_WORK);
00367           CCcheck_rval (rval, "CCutil_swrite_char failed");
00368         }
00369 
00370         rval = CCutil_swrite_int (s, (int) (curloc % nnodes));
00371         CCcheck_rval (rval, "CCutil_swrite_int failed");
00372 
00373         status[curloc % nnodes] = DOM_STAT_WORK;
00374 
00375         // printf ("  New = %u\n", curloc % nnodes); fflush (stdout);
00376 
00377         curloc++;
00378       }
00379 
00380       /* If all jobs are done, tell the grunt to wait.                  */
00381 
00382       else
00383       {
00384         printf ("\n");
00385         fflush (stdout);
00386         rval = CCutil_swrite_char (s, CCtsp_DOMINO_WAIT);
00387         CCcheck_rval (rval, "CCutil_swrite_char failed (WAIT)");
00388       }
00389 
00390     CLOSE_CONN:
00391 
00392       //printf ("  Closing connection (1).\n"); fflush (stdout);
00393       CCutil_sclose (s);
00394     }
00395 
00396     printf ("FINISHED Graph %d: %.2f seconds.\n\n", current_g_id, graph_time);
00397     fflush (stdout);
00398 
00399     /* We now communicate with concorde.                                  */
00400 
00401     request = 0;
00402     do
00403     {
00404 
00405       /* open the port                                                  */
00406 
00407       //printf ("  Opening Port (2).\n"); fflush (stdout);
00408 
00409       s = CCutil_snet_receive (lport);
00410       if (!s)
00411       {
00412         fprintf (stderr, "CCutil_snet_receive failed, ignoring\n");
00413         continue;
00414       }
00415 
00416       /* wait for request                                               */
00417 
00418       if (CCutil_sread_char (s, &request))
00419       {
00420         fprintf (stderr, "CCutil_sread_char failed, abort con\n");
00421         CCutil_sclose (s);
00422         continue;
00423       }
00424 
00425       /* wait until we get the 'DOMINO_SEND' request.                   */
00426 
00427       switch (request)
00428       {
00429       case CCtsp_DOMINO_RECEIVE:
00430         rval = CCutil_swrite_char (s, CCtsp_DOMINO_NO);
00431         CCcheck_rval (rval, "CCutil_swrite_char failed (NO)");
00432         CCutil_sclose (s);
00433         break;
00434       case CCtsp_DOMINO_EXIT:
00435         printf ("Shutting down the domino boss\n");
00436         fflush (stdout);
00437         CCutil_sclose (s);
00438         rval = 1;
00439         goto CLEANUP;
00440       case CCtsp_DOMINO_GRAPH:
00441         fprintf (stderr, "Cannot receive new graph\n");
00442         CCutil_sclose (s);
00443         rval = 1;
00444         goto CLEANUP;
00445       case CCtsp_DOMINO_SEND:
00446         break;
00447       default:
00448         fprintf (stderr, "Invalid request %c\n", request);
00449       }
00450     } while (request != CCtsp_DOMINO_SEND);
00451 
00452     /* send the dominoes back to concorde                                 */
00453 
00454     printf ("Sending %u dominos ... ", D->size);
00455     fflush (stdout);
00456 
00457     rval = CCutil_swrite_char (s, CCtsp_DOMINO_SEND);
00458     CCcheck_rval (rval, "send DOMINO_SEND failed");
00459 
00460     rval = CCutil_swrite_int (s, (int) D->size);
00461     CCcheck_rval (rval, "send ndominoes failed");
00462 
00463     for (l_it = D->begin; l_it; l_it = l_it->next)
00464     {
00465       net_ddom = (EGnetDdom_t *) (l_it->this);
00466       rval = EGsendNetDomino (s, net_ddom);
00467       CCcheck_rval (rval, "send_dominos failed");
00468     }
00469 
00470     printf ("done.\n");
00471     fflush (stdout);
00472 
00473     CCutil_sclose (s);
00474 
00475     EGlistClearMP (D, EGfreeNetDdomMP, mem);
00476 
00477     EGmemPoolFree (edges, sizeof (unsigned int) * 2 * nedges, mem);
00478     EGmemPoolFree (weight, sizeof (double) * nedges, mem);
00479 
00480     nedges = nnodes = 0;
00481     edges = 0;
00482     weight = 0;
00483 
00484     graph_time = 0;
00485 
00486   }
00487 
00488 CLEANUP:
00489 
00490   EGfreeList (D);
00491   EGfreeMemPool (mem);
00492   CCutil_snet_unlisten (lport);
00493   EGfree (status);
00494 
00495   return rval;
00496 }

Generated on Thu Oct 20 14:58:40 2005 for DominoParitySeparator by  doxygen 1.4.5