VIS

src/part/partCmd.c

Go to the documentation of this file.
00001 
00018 #include "partInt.h"
00019 
00020 static char rcsid[] UNUSED = "$Id: partCmd.c,v 1.22 2009/04/11 01:47:18 fabio Exp $";
00021 
00022 /*---------------------------------------------------------------------------*/
00023 /* Variable declarations                                                     */
00024 /*---------------------------------------------------------------------------*/
00032 static jmp_buf timeOutEnv;
00033 
00036 /*---------------------------------------------------------------------------*/
00037 /* Static function prototypes                                                */
00038 /*---------------------------------------------------------------------------*/
00039 
00040 static int CommandBuildPartitionMdds(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00041 static int CommandPrintPartition(Hrc_Manager_t **hmgr, int argc, char **argv);
00042 static int CommandPrintPartitionStats(Hrc_Manager_t **hmgr, int argc, char **argv);
00043 static void TimeOutHandle(void);
00044 
00048 /*---------------------------------------------------------------------------*/
00049 /* Definition of exported functions                                          */
00050 /*---------------------------------------------------------------------------*/
00051 
00061 void
00062 Part_Init(void)
00063 {
00064   Cmd_CommandAdd("build_partition_mdds", CommandBuildPartitionMdds,
00065                  0/* doesn't change network */);
00066   Cmd_CommandAdd("print_partition", CommandPrintPartition,
00067                  0/* doesn't change network */);
00068   Cmd_CommandAdd("print_partition_stats", CommandPrintPartitionStats,
00069                  0/* doesn't change network*/);
00070 } /* End of Part_Init */
00071 
00072 
00082 void
00083 Part_End(void)
00084 {
00085 } /* End of Part_End */
00086 
00087 /*---------------------------------------------------------------------------*/
00088 /* Definition of internal functions                                          */
00089 /*---------------------------------------------------------------------------*/
00090 
00091 
00092 /*---------------------------------------------------------------------------*/
00093 /* Definition of static functions                                            */
00094 /*---------------------------------------------------------------------------*/
00095 
00205 static int
00206 CommandBuildPartitionMdds(
00207   Hrc_Manager_t ** hmgr,
00208   int  argc,
00209   char ** argv)
00210 {
00211   static Part_PartitionMethod method;
00212   static boolean              inTermsOfLeaves;
00213   lsList                      nodeList = lsCreate();
00214   graph_t                     *partition;
00215   static int                  verbose;
00216   static int                  sanityCheck;
00217   static int                  timeOutPeriod;
00218   int                         c;
00219   int                         length;
00220   char                        *methodString;
00221   char                        *modelName;
00222   Hrc_Node_t                  *currentNode;
00223   Ntk_Network_t               *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00224   char *nodeName;
00225   char *tmpNodeName;
00226   char *realName;
00227   FILE *nodeFile;
00228   static boolean fileUsed;
00229 
00230   fileUsed = FALSE;
00231   inTermsOfLeaves = FALSE;
00232   verbose = 0;
00233   sanityCheck = 0;
00234   timeOutPeriod = 0;
00235 
00236   nodeFile = NIL(FILE);
00237   util_getopt_reset();
00238   while ((c = util_getopt(argc, argv, "f:hvin:s:t:")) != EOF) {
00239     switch(c) {
00240       case 'f':
00241         fileUsed = TRUE;
00242         nodeFile = Cmd_FileOpen(util_optarg, "r", &realName, 1);
00243         FREE(realName);
00244         if (nodeFile == NIL(FILE)){
00245           (void)fprintf(vis_stderr,"Cannot open %s\n", util_optarg);
00246           lsDestroy(nodeList, (void (*)(lsGeneric))0);
00247           return 1;
00248         }
00249         else{
00250           tmpNodeName = ALLOC(char, 512);
00251           while(fscanf(nodeFile, "%s\n", tmpNodeName) != EOF){
00252             if(*tmpNodeName != '#'){
00253               nodeName = ALLOC(char, strlen(tmpNodeName) + 2);
00254               sprintf(nodeName, "%s", tmpNodeName);
00255               lsNewEnd(nodeList, (lsGeneric)nodeName, NIL(lsHandle));
00256             }
00257           }
00258           FREE(tmpNodeName);
00259         }
00260         break;
00261       case 'h':
00262         goto usage;
00263       case 'i':
00264         inTermsOfLeaves = TRUE;
00265         break;
00266       case 'v':
00267         verbose = 1;
00268         break;
00269       case 's':
00270         sanityCheck = atoi(util_optarg);
00271         break;
00272       case 't':
00273         timeOutPeriod = atoi(util_optarg);
00274         break;
00275       case 'n':
00276         length = strlen(util_optarg);
00277         for(c = 0; c < length; c++) {
00278           if (util_optarg[c] == ',') {
00279             util_optarg[c] = 0;
00280           } /* End of if */
00281         } /* End of for */
00282         c = 0;
00283         while (c < length) {
00284           lsNewEnd(nodeList, &util_optarg[c], NIL(lsHandle));
00285           while (util_optarg[c++] != 0);
00286         } /* End of while */
00287         break;
00288       default:
00289         goto usage;
00290     }
00291   }
00292 
00293   if (argc == util_optind) {
00294     /* No method specified. Choosing default */
00295     methodString = Cmd_FlagReadByName("partition_method");
00296     if (methodString == NIL(char)) {
00297       methodString = "default";
00298     }
00299   }
00300   else {
00301     methodString = argv[util_optind];
00302   }
00303 
00304   if (strcmp(methodString,"inout") == 0) {
00305     method = Part_InOut_c;
00306     if (lsLength(nodeList) != 0) {
00307       (void) fprintf(vis_stderr, "Ignoring provided list of nodes in <inout>");
00308       (void) fprintf(vis_stderr, " method\n");
00309     } /* End of if */
00310     if (inTermsOfLeaves) {
00311       (void) fprintf(vis_stderr, "Ignoring -i flag in the <inout> method\n");
00312     } /* End of if */
00313   }
00314   else if (strcmp(methodString,"partial") == 0) {
00315     method = Part_Partial_c;
00316     /* Make sure a list of nodes has been provided */
00317     if (lsLength(nodeList) == 0) {
00318       (void) fprintf(vis_stderr, "Method <partial> requires a non-empty list");
00319       (void) fprintf(vis_stderr, " of nodes\n");
00320 
00321       lsDestroy(nodeList, (void (*)(lsGeneric))0);
00322       goto usage;
00323     } /* End of if */
00324   }
00325   else if (strcmp(methodString,"total") == 0) {
00326     method = Part_Total_c;
00327     if (lsLength(nodeList) != 0) {
00328       (void) fprintf(vis_stderr, "Ignoring provided list of nodes in <total>");
00329       (void) fprintf(vis_stderr, " method\n");
00330     } /* End of if */
00331   }
00332   else if (strcmp(methodString,"frontier") == 0) {
00333     method = Part_Frontier_c;
00334   }
00335   else if (strcmp(methodString,"boundary") == 0) {
00336     method = Part_Boundary_c;
00337   }
00338   else if (strcmp(methodString, "fine") == 0) {
00339     method = Part_Fine_c;
00340   }
00341   else if (strcmp(methodString, "default") == 0) {
00342     method = Part_Default_c;
00343   }
00344   else {
00345     goto usage;
00346   }
00347 
00348 
00349   /* Check if the network has been read in */
00350   if (network == NIL(Ntk_Network_t)) {
00351     lsDestroy(nodeList, (void (*)(lsGeneric))0);
00352     return 1;
00353   }
00354 
00355   /* Check if the network has the variables ordered */
00356   if (Ord_NetworkTestAreVariablesOrdered(network, Ord_InputAndLatch_c) ==
00357       FALSE) {
00358     (void) fprintf(vis_stdout, "The MDD variables have not been ordered. Use static_order.\n");
00359 
00360     lsDestroy(nodeList, (void (*)(lsGeneric))0);
00361     return 1;
00362   }
00363 
00364   /* Check if there is already a partition attached to the network */
00365   partition = (graph_t *) Ntk_NetworkReadApplInfo(network,
00366                                                   PART_NETWORK_APPL_KEY);
00367 
00368   /* If there is, just return. */
00369   if (partition != NIL(graph_t)) {
00370     (void) fprintf(vis_stderr, "partition already built; reinvoke ");
00371     (void) fprintf(vis_stderr, "flatten_hierarchy to remove the current partition\n");
00372     return 1;
00373   }
00374 
00375   /* Read the name of the model to be passed to Part_NetworkCreatePartition */
00376   currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
00377   modelName = Hrc_NodeReadModelName(currentNode);
00378 
00379   /* Set the timeout */
00380   if (timeOutPeriod > 0) {
00381     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
00382     (void) alarm(timeOutPeriod);
00383     if (setjmp(timeOutEnv) > 0) {
00384       (void) fprintf(vis_stdout, "Partition: timeout occurred after ");
00385       (void) fprintf(vis_stdout, "%d seconds\n", timeOutPeriod);
00386       alarm(0);
00387 
00388       /* Partial clean up */
00389       lsDestroy(nodeList, (void (*)(lsGeneric))0);
00390       return 1;
00391     }
00392   }
00393 
00394   /*
00395    * Execute the partition algorithm. The two nil pointers is to indicate
00396    * that the graph must represent the complete network.
00397    */
00398   partition = Part_NetworkCreatePartition(network, currentNode, modelName, (lsList)0,
00399                                           (lsList)0, NIL(mdd_t), method, nodeList,
00400                                           inTermsOfLeaves, verbose,
00401                                           sanityCheck);
00402 
00403   /* Register the partition in the network if any */
00404   Ntk_NetworkAddApplInfo(network, PART_NETWORK_APPL_KEY,
00405                          (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback,
00406                          (void *) partition);
00407 
00408   /* Deactivate the alarm */
00409   alarm(0);
00410 
00411   /* Clean up */
00412   if(fileUsed){
00413     lsDestroy(nodeList, PartNameFree);
00414   }
00415   else{
00416     lsDestroy(nodeList, (void (*)(lsGeneric))0);
00417   }
00418   return 0;
00419 
00420 usage:
00421   (void) fprintf(vis_stderr, "usage: build_partition_mdds [options] [method]\n");
00422   (void) fprintf(vis_stderr, "Options:\n");
00423   (void) fprintf(vis_stderr, "    -h\t\tprint the command usage\n");
00424   (void) fprintf(vis_stderr, "    -i\t\tBuild the functions in the partition in terms of the\n");
00425   (void) fprintf(vis_stderr, "      \t\tcombinational inputs of the system. This option is redundant if\n");
00426   (void) fprintf(vis_stderr, "      \t\tthe inout partition is chosen.\n");
00427   (void) fprintf(vis_stderr, "    -n <list>\tComma separated list of network nodes to preserve in the\n");
00428   (void) fprintf(vis_stderr, "             \tpartitioning. It only matters if the partial method has been\n");
00429   (void) fprintf(vis_stderr, "             \tselected.\n");
00430   (void) fprintf(vis_stderr, "    -f <file>\tSpecifies the file containing names of network nodes\n");
00431   (void) fprintf(vis_stderr, "             \tto preserve while partitioning. This option matters only \n");
00432   (void) fprintf(vis_stderr, "             \tif the partial method has been selected. Each node name must\n");
00433   (void) fprintf(vis_stderr, "             \tbe listed on a new line. Comments in <file> must begin with '#'.\n");
00434   (void) fprintf(vis_stderr, "    -s <num>\tLevel of severity check applied after computation. 0 being no\n");
00435   (void) fprintf(vis_stderr, "      \t\tcheck, 1 begin simple check and >1 being exhaustive check.\n");
00436   (void) fprintf(vis_stderr, "    -t <sec>\tTime in seconds allowed to build the partition. If the\n");
00437   (void) fprintf(vis_stderr, "            \tcomputation time goes above that limit, the process of building\n");
00438   (void) fprintf(vis_stderr, "            \tthe partition is aborted.\n");
00439   (void) fprintf(vis_stderr, "    -v\t\tverbose\n");
00440   (void) fprintf(vis_stderr, "Methods\n");
00441   (void) fprintf(vis_stderr, "    inout\tIt represents the network with one MDD for\n");
00442   (void) fprintf(vis_stderr, "         \teach combinational output as a function of the combinational\n");
00443   (void) fprintf(vis_stderr, "         \tinputs\n");
00444   (void) fprintf(vis_stderr, "    total\tPartitions the network preserving its structure. Every node in\n");
00445   (void) fprintf(vis_stderr, "         \tthe network will produce a vertex in the partition graph. The\n");
00446   (void) fprintf(vis_stderr, "         \tflag -i explained above controls the support of\n");
00447   (void) fprintf(vis_stderr, "         \tthe functions attached to the vertices.\n");
00448   (void) fprintf(vis_stderr, "    frontier\tThe default method. Partitions the network creating vertices for intermediate nodes\n");
00449   (void) fprintf(vis_stderr, "         \tas necessary to control the BDD size. The threshold value of the\n");
00450   (void) fprintf(vis_stderr, "         \tBDD can be specified by partition_threshold.\n");
00451   (void) fprintf(vis_stderr, "    partial\tPartitions the network preserving certain nodes specified with\n");
00452   (void) fprintf(vis_stderr, "           \tthe option -n or -f.\n");
00453   (void) fprintf(vis_stderr, "    boundary\tPartitions the network preserving all nodes that are \n");
00454   (void) fprintf(vis_stderr, "           \tsubcircuit IOs.\n");
00455 
00456   lsDestroy(nodeList, (void (*)(lsGeneric))0);
00457 
00458   return 1;            /* Error exit */
00459 } /* End of CommandBuildPartitionMdds */
00460 
00461 
00474 void
00475 PartNameFree(
00476   lsGeneric name)
00477 {
00478   FREE(name);
00479 }
00480 
00481 
00519 static int
00520 CommandPrintPartition(
00521   Hrc_Manager_t **hmgr,
00522   int argc,
00523   char **argv)
00524 {
00525   FILE *fp;
00526   int c, status;
00527   graph_t *partition;
00528   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00529 
00530   util_getopt_reset();
00531   while ((c = util_getopt(argc,argv,"h")) != EOF){
00532     switch(c){
00533       case 'h':
00534         goto usage;
00535       default:
00536         goto usage;
00537     }
00538   }
00539 
00540   /* Check if the network has been read in */
00541   if (network == NIL(Ntk_Network_t)) {
00542     return 1;
00543   }
00544 
00545   /* Check if there is a partition attached to the network */
00546   partition = (graph_t *) Ntk_NetworkReadApplInfo(network,
00547                                                   PART_NETWORK_APPL_KEY);
00548   if (partition == NIL(graph_t)) {
00549     (void) fprintf(vis_stderr, "No partition has been created for this network.\n");
00550     return 1;
00551   }
00552 
00553   if (argc == 1) {
00554     fp = vis_stdout;
00555   }
00556   else if (argc == 2) {
00557     fp = Cmd_FileOpen(*(++argv), "w", NIL(char *), /* silent */ 1);
00558     if (fp == NIL(FILE)) {
00559       (void) fprintf(vis_stderr, "Cannot write to %s\n", *argv);
00560       return 1;
00561     }
00562   }
00563   else {
00564     goto usage;
00565   }
00566 
00567   error_init();
00568   status = PartPartitionPrint(fp, partition);
00569   (void) fprintf(vis_stderr, "%s", error_string());
00570   fflush(fp);
00571 
00572   /* If we opened a file before, close it */
00573   if (argc == 2) {
00574     (void) fclose(fp);
00575   }
00576   return (status ? 0 : 1);
00577 
00578  usage:
00579   (void) fprintf(vis_stderr, "usage: print_partition [-h] [file]\n");
00580   (void) fprintf(vis_stderr, "    -h\t\tprint the command usage\n");
00581   return 1;
00582 } /* End of CommandPrintPartition */
00583 
00623 static int
00624 CommandPrintPartitionStats(
00625   Hrc_Manager_t **hmgr,
00626   int argc,
00627   char **argv)
00628 {
00629   int c;
00630   graph_t *partition;
00631   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00632   boolean printNodeNames = FALSE;
00633 
00634   util_getopt_reset();
00635   while ((c = util_getopt(argc,argv,"hn")) != EOF){
00636     switch(c){
00637       case 'n':
00638         printNodeNames = TRUE;
00639         break;
00640       case 'h':
00641         goto usage;
00642       default:
00643         goto usage;
00644     }
00645   }
00646 
00647   /* Check if the network has been read in */
00648   if (network == NIL(Ntk_Network_t)) {
00649     return 1;
00650   }
00651 
00652   /* Check if there is a partition attached to the network */
00653   partition = (graph_t *) Ntk_NetworkReadApplInfo(network,
00654                                                   PART_NETWORK_APPL_KEY);
00655   if (partition == NIL(graph_t)) {
00656     (void) fprintf(vis_stderr, "No partition has been created for this network.\n");
00657     return 1;
00658   }
00659 
00660   /* Print the statistics to vis_stdout */
00661   Part_PartitionPrintStats(vis_stdout, partition, printNodeNames);
00662   return 0;
00663 
00664  usage:
00665   (void) fprintf(vis_stderr, "usage: print_partition_stats [-h] [-n]\n");
00666   (void) fprintf(vis_stderr, "    -h\t\tprint the command usage\n");
00667   (void) fprintf(vis_stderr, "    -n\t\tprint names of network nodes ");
00668   (void) fprintf(vis_stderr, "represented by vertices\n");
00669   return 1;
00670 } /* End of CommandPrintPartitionStats */
00671 
00672 
00684 static void
00685 TimeOutHandle(void)
00686 {
00687   longjmp(timeOutEnv, 1);
00688 } /* End of TimeOutHandle */