VIS
|
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 */