VIS
|
00001 00045 #include "partInt.h" 00046 00047 static char rcsid[] UNUSED = "$Id: partGroup.c,v 1.51 2005/04/28 14:15:50 fabio Exp $"; 00048 00049 /*---------------------------------------------------------------------------*/ 00050 /* Constant declarations */ 00051 /*---------------------------------------------------------------------------*/ 00052 00053 00054 /*---------------------------------------------------------------------------*/ 00055 /* Type declarations */ 00056 /*---------------------------------------------------------------------------*/ 00057 00058 00059 /*---------------------------------------------------------------------------*/ 00060 /* Structure declarations */ 00061 /*---------------------------------------------------------------------------*/ 00062 00063 00064 /*---------------------------------------------------------------------------*/ 00065 /* Variable declarations */ 00066 /*---------------------------------------------------------------------------*/ 00067 00068 00069 /*---------------------------------------------------------------------------*/ 00070 /* Macro declarations */ 00071 /*---------------------------------------------------------------------------*/ 00072 00073 00076 /*---------------------------------------------------------------------------*/ 00077 /* Static function prototypes */ 00078 /*---------------------------------------------------------------------------*/ 00079 00080 static char * PartCreateDependencyMatrix(Part_SubsystemInfo_t *partSubInfo, st_table *ptrToIndex); 00081 static float * PartCreateCorrelationMatrixFromSupport(Part_SubsystemInfo_t *partSubInfo); 00082 static float * PartCreateCorrelationMatrixFromBDD(Part_SubsystemInfo_t *partSubInfo); 00083 static float PartVertexComputeCorrelation(int index1, int index2, array_t *arrayOfInputSupportTable, Part_SubsystemInfo_t *partSubInfo); 00084 static array_t * PartVertexComputeAgreement(mdd_manager *mddMgr, int index1, int index2, array_t *arrayOfBddArray); 00085 static float * PartCreateAffinityMatrix(char *arrayOfConnectivity, float *arrayOfCorrelation, Part_SubsystemInfo_t *partSubInfo); 00086 static array_t * PartGetConnectedComponent(float *arrayOfAffinity, Part_SubsystemInfo_t *partSubInfo, st_table *indexToPtr); 00087 static void PartFindCC(int *next, int *ccId, array_t *arrayOfCCIndex, float *arrayOfAffinity, array_t *arrayOfFrom, Part_SubsystemInfo_t *PartSubInfo); 00088 static array_t * PartBreakingAggregating(array_t *arrayOfInit, float *arrayOfAffinity, Part_SubsystemInfo_t *partSubInfo, st_table *ptrToIndex, char *arrayOfDependency); 00089 static array_t * PartBreakingBigConnectedComponent(array_t *arrayOfCC, array_t *ccCheck, array_t *arrayOfSeed, float *arrayOfAffinity, Part_SubsystemInfo_t *partSubInfo, st_table *ptrToIndex); 00090 static array_t * PartAggregating(array_t *arrayOfSmall, float *arrayOfAffinity, Part_SubsystemInfo_t *partSubInfo, st_table *ptrToIndex); 00091 static array_t * PartCreateSubSystemWithGroupIndex(Part_SubsystemInfo_t *partSubInfo, array_t *arrayOfLatchNames, array_t *arrayOfGroupIndex); 00092 static Ntk_Node_t * PartSelectCloseNode(Ntk_Node_t *seed, array_t *arrayOfCC, array_t *ccCheck, float *arrayOfAffinity, st_table *ptrToIndex); 00093 static int PartSelectCloseSeedIndex(Ntk_Node_t *variable, array_t *arrayOfSeed, float *arrayOfAffinity, st_table *ptrToIndex, array_t *seedFull, int bound); 00094 static Ntk_Node_t * PartSelectFarNode(Ntk_Node_t *seed, array_t *cc, array_t *ccCheck, float *arrayOfAffinity, st_table *ptrToIndex); 00095 static float * PartGetGroupMatrixRegular(array_t *arrayOfCluster, char *arrayOfGivenMatrix, st_table *ptrToIndex, int nVertices); 00096 static float * PartGetGroupMatrixSym(array_t *arrayOfCluster, float *arrayOfGivenMatrix, st_table *ptrToIndex); 00097 static int PartSelectCCIndexOfMinSupport(array_t *arrayOfSmall, array_t *ccCheck, Part_SubsystemInfo_t *partSubInfo); 00098 static Ntk_Node_t * PartSelectNodeOfMinSupport(array_t *cc, array_t *ccCheck, Part_SubsystemInfo_t *partSubInfo); 00099 static int PartSelectFarCCIndex(int seedIndex, array_t *arrayOfSmall, float *arrayOfGroupAff, Part_SubsystemInfo_t *partSubInfo, array_t *ccCheck); 00100 static int PartSelectCloseCCIndex(int seedIndex, array_t *arrayOfSmall, float *arrayOfGroupAff, array_t *ccCheck); 00101 static Part_Subsystem_t* PartCreateSingleSubSystem(array_t *arrayOfNodes, Ntk_Network_t *network); 00102 static array_t * PartReadLatchNameFromLatchInput(Ntk_Network_t *network, Ntk_Node_t *latchInput); 00103 static void PartArrayOfArrayFree(array_t *arrayOfMatrix); 00104 static float PartGetElementFromSymMatrix(float *matrix, int i, int j); 00105 static void PartPrintArrayArray(void *arrayOfMatrix, int nVertices, int type); 00106 static int strCompare(const void * name1, const void * name2); 00107 static int numCompare(const void * num1, const void * num2); 00108 static array_t *PartCreateSubsystemWithCTL(Part_SubsystemInfo_t *, array_t *, array_t *, boolean , boolean ); 00109 static array_t *PartCreateSubsystemWithCtlAndLtl(Part_SubsystemInfo_t *, array_t *, array_t *, array_t *, boolean , boolean, boolean ); 00110 00111 00115 /*---------------------------------------------------------------------------*/ 00116 /* Definition of exported functions */ 00117 /*---------------------------------------------------------------------------*/ 00118 00144 array_t * 00145 Part_PartGroupVeriticesBasedOnHierarchy( 00146 Ntk_Network_t *network, 00147 array_t *latchDataInputNames) 00148 { 00149 graph_t *partition; 00150 array_t *arrayOfPartition = NIL(array_t); 00151 array_t *arrayOfGroups = NIL(array_t); 00152 array_t *arrayOfLatches = NIL(array_t); 00153 array_t *arrayOfLatchSort = NIL(array_t); 00154 st_table *vertexTable = NIL(st_table); 00155 int numOfVertex, reset; 00156 int i, j, k; 00157 char *numberOfVertexInGroup; 00158 char *flagValue; 00159 char *latchName, *name; 00160 st_table *latchDataInputNameTable; 00161 Part_Subsystem_t *testSubsystem; 00162 00163 partition = Part_NetworkReadPartition(network); 00164 if (partition == NIL(graph_t)) { 00165 error_append("Network has no partition. Cannot create sub machines."); 00166 return (NIL(array_t)); 00167 } 00168 00169 /* 00170 * Convert graph of vertices into array of table of vertices. 00171 */ 00172 00173 numberOfVertexInGroup = Cmd_FlagReadByName("amc_sizeof_group"); 00174 if (numberOfVertexInGroup != NIL(char)) { 00175 numOfVertex = atoi(numberOfVertexInGroup); 00176 reset = atoi(numberOfVertexInGroup); 00177 } 00178 else { 00179 /* default value */ 00180 numOfVertex = 8; 00181 reset = 8; 00182 } 00183 00184 latchDataInputNameTable = st_init_table(strcmp, st_strhash); 00185 00186 arrayForEachItem(char *, latchDataInputNames, i, name) { 00187 st_insert(latchDataInputNameTable, (char *)name, (char *)NULL); 00188 } 00189 00190 /* 00191 * In the first phase, group latches by the processes. 00192 * That is, group latches that are within same sub-circuit. 00193 */ 00194 00195 arrayOfGroups = array_alloc(array_t *, 0); 00196 00197 { 00198 Ntk_Node_t *latch; 00199 lsGen gen; 00200 char *groupName = util_strsav(" "); 00201 00202 arrayOfLatchSort = array_alloc(char *, 0); 00203 Ntk_NetworkForEachLatch(network, gen, latch) { 00204 Ntk_Node_t *latchInput = Ntk_LatchReadDataInput(latch); 00205 char *latchInputName = Ntk_NodeReadName(latchInput); 00206 vertex_t *vertex = Part_PartitionFindVertexByName(partition, 00207 latchInputName); 00208 if ((vertex != NIL(vertex_t)) && 00209 (st_lookup(latchDataInputNameTable, latchInputName, NIL(char *)))) { 00210 array_insert_last(char *, arrayOfLatchSort, Ntk_NodeReadName(latch)); 00211 } 00212 } 00213 array_sort(arrayOfLatchSort, strCompare); 00214 00215 arrayForEachItem(char *, arrayOfLatchSort, i, latchName) { 00216 char *suffixLatchName, *currentGroupName; 00217 00218 suffixLatchName = util_strsav(latchName); 00219 00220 /* Extract out group name into the string "groupName" and leave 00221 rest in suffixLatchName. */ 00222 00223 currentGroupName = strtok(suffixLatchName, "."); 00224 00225 if (strcmp(groupName, currentGroupName)) { 00226 if (strcmp(groupName, " ")) { 00227 array_insert_last(array_t *, arrayOfGroups, arrayOfLatches); 00228 } 00229 FREE(groupName); 00230 groupName = util_strsav(currentGroupName); 00231 arrayOfLatches = array_alloc(char *, 0); 00232 } 00233 FREE(currentGroupName); 00234 array_insert_last(char *, arrayOfLatches, latchName); 00235 } 00236 FREE(groupName); 00237 } 00238 00239 array_free(arrayOfLatchSort); 00240 st_free_table(latchDataInputNameTable); 00241 00242 /* Fill in the last arrayOfLatches */ 00243 array_insert_last(array_t *, arrayOfGroups, arrayOfLatches); 00244 00245 /* 00246 * In the second phase, further break latch group into 00247 * smaller group size according to the "amc_sizeof_group". 00248 */ 00249 00250 arrayOfPartition = array_alloc(Part_Subsystem_t *, 0); 00251 00252 arrayForEachItem(array_t *, arrayOfGroups, k, arrayOfLatches) { 00253 char *latchName; 00254 int numOfLatches = array_n(arrayOfLatches); 00255 00256 arrayForEachItem(char *, arrayOfLatches, i, latchName) { 00257 00258 if (numOfVertex == reset) 00259 vertexTable = st_init_table(strcmp, st_strhash); 00260 00261 st_insert(vertexTable, latchName, (char *)NULL); 00262 00263 if ((numOfVertex == 1) || (numOfLatches == i+1)) { 00264 /* testSubsystem freed by calling function */ 00265 testSubsystem = ALLOC(Part_Subsystem_t, 1); 00266 testSubsystem->vertexNameTable = vertexTable; 00267 testSubsystem->subsystemFanIn = NIL(array_t); 00268 testSubsystem->subsystemFanOut = NIL(array_t); 00269 00270 array_insert_last(Part_Subsystem_t *, arrayOfPartition, testSubsystem); 00271 numOfVertex = reset; 00272 } 00273 else 00274 numOfVertex--; 00275 } /* End of arrayForEachItem(arrayOfLatches) */ 00276 } /* End of arrayForEachItem(arrayOfGroups) */ 00277 00278 /* Free arrayOfGroups, arrayOfLatches */ 00279 arrayForEachItem(array_t *, arrayOfGroups, i, arrayOfLatches) { 00280 array_free(arrayOfLatches); 00281 } 00282 array_free(arrayOfGroups); 00283 00284 /* 00285 * Currently this function is used only from amc package. 00286 * When the function gets popular use parameter passing rather that this 00287 * ugly method. 00288 */ 00289 flagValue = Cmd_FlagReadByName("amc_use_MBM"); 00290 if (flagValue != NIL(char)) { 00291 array_t *latchNodeArray; 00292 array_t *faninNodeArray; 00293 array_t *faninLatchArray; 00294 00295 /* 00296 * Fill in the subsystem dependencies using the latch dependencies. 00297 */ 00298 00299 arrayForEachItem(Part_Subsystem_t *, arrayOfPartition, i, testSubsystem) { 00300 array_t *fanInArray = array_alloc(int, 0); 00301 st_table *vertexTable = testSubsystem->vertexNameTable; 00302 st_generator *stGen; 00303 char *latchName; 00304 Ntk_Node_t *latchNode; 00305 00306 latchNodeArray = array_alloc(Ntk_Node_t *, 0); 00307 faninLatchArray = array_alloc(Ntk_Node_t *, 0); 00308 00309 /* Convert table of latch names into array of latch nodes */ 00310 st_foreach_item(vertexTable, stGen, &latchName, NIL(char *)) { 00311 latchNode = Ntk_NetworkFindNodeByName(network, latchName); 00312 array_insert_last(Ntk_Node_t *, latchNodeArray, latchNode); 00313 } 00314 00315 /* Find the transitive fanin nodes */ 00316 faninNodeArray = Ntk_NodeComputeCombinationalSupport(network, 00317 latchNodeArray, FALSE); 00318 00319 /* Find the transitive fanin latches from the fanin nodes */ 00320 if (array_n(faninNodeArray) != 0) { 00321 int x; 00322 arrayForEachItem(Ntk_Node_t *, faninNodeArray, x, latchNode) { 00323 if (Ntk_NodeTestIsLatch(latchNode) == TRUE) { 00324 array_insert_last(Ntk_Node_t *, faninLatchArray, latchNode); 00325 } 00326 } 00327 } 00328 00329 /* Find the fanin subsystems */ 00330 if (array_n(faninLatchArray) != 0) { 00331 Part_Subsystem_t *scanSubsystem; 00332 int y; 00333 00334 arrayForEachItem(Part_Subsystem_t *, arrayOfPartition, j, 00335 scanSubsystem) { 00336 /* Scan subsystems that aren't the currently considered subsytem */ 00337 st_table *otherVertexTable = scanSubsystem->vertexNameTable; 00338 00339 if (i != j) { 00340 arrayForEachItem(Ntk_Node_t *, faninLatchArray, y, latchNode) { 00341 char *latchName = Ntk_NodeReadName(latchNode); 00342 if (st_lookup(otherVertexTable, latchName, NIL(char *))) { 00343 array_insert_last(int, fanInArray, j); 00344 break; 00345 } 00346 } /* end of arrayForEachItem(Ntk_Node_t *) */ 00347 } /* end of if (i != j) */ 00348 } 00349 } /* end of if (array_n(faninLatchArray) != 0) */ 00350 00351 /* Update fanInArray into the subsystem */ 00352 testSubsystem->subsystemFanIn = fanInArray; 00353 00354 array_free(latchNodeArray); 00355 array_free(faninNodeArray); 00356 array_free(faninLatchArray); 00357 } /* end of arrayForEachItem(Part_Subsystem_t *) */ 00358 } /* end of if (!flagValue) */ 00359 00360 /* 00361 * Currently this function is used only from amc package. 00362 * When the function gets popular use parameter passing rather that this 00363 * ugly method. 00364 */ 00365 00366 flagValue = Cmd_FlagReadByName("amc_use_MBM"); 00367 if (flagValue != NIL(char)) { 00368 st_table *fanOutDependencies = Ntk_NetworkComputeLatchDependencies(network); 00369 00370 /* 00371 * Fill in the fanout dependencies of subsystems. 00372 */ 00373 arrayForEachItem(Part_Subsystem_t *, arrayOfPartition, i, testSubsystem) { 00374 array_t *fanOutArray = array_alloc(int, 0); 00375 st_table *vertexTable = testSubsystem->vertexNameTable; 00376 st_generator *stGen; 00377 char *latchName; 00378 st_table *everyFanOuts = st_init_table(st_ptrcmp, st_ptrhash); 00379 00380 /* 00381 * For the latches in this subsystem, 00382 * find all latches that transitively fanouts from the latches 00383 * inside this subsystem. Store it in a hash table, "everyFanOuts". 00384 */ 00385 st_foreach_item(vertexTable, stGen, &latchName, NIL(char *)) { 00386 Ntk_Node_t *latchNode; 00387 lsList fanOutLatchList; 00388 lsGen gen; 00389 lsGeneric data; 00390 00391 latchNode = Ntk_NetworkFindNodeByName(network, latchName); 00392 st_lookup(fanOutDependencies, latchNode, &fanOutLatchList); 00393 00394 /* Obtain all fanout latches coming from latches of this subsystem */ 00395 gen = lsStart(fanOutLatchList); 00396 while (lsNext(gen, &data, LS_NH) == LS_OK) { 00397 st_insert(everyFanOuts, data, NULL); 00398 } 00399 (void) lsFinish(gen); 00400 lsDestroy(fanOutLatchList, (void (*) (lsGeneric)) NULL); 00401 } 00402 00403 /* 00404 * Scan subsystems that aren't the currently considered subsytem. 00405 */ 00406 { 00407 Part_Subsystem_t *scanSubsystem; 00408 arrayForEachItem(Part_Subsystem_t *, arrayOfPartition, j, 00409 scanSubsystem) { 00410 st_table *otherVertexTable = scanSubsystem->vertexNameTable; 00411 00412 if (i != j) { 00413 st_generator *stGen; 00414 Ntk_Node_t *latchNode; 00415 00416 st_foreach_item(everyFanOuts, stGen, &latchNode, NULL) { 00417 char *latchName = Ntk_NodeReadName(latchNode); 00418 if (st_lookup(otherVertexTable, latchName, NIL(char *))) { 00419 array_insert_last(int, fanOutArray, j); 00420 break; 00421 } 00422 } /* end of */ 00423 } /* end of if (i != j) */ 00424 } /* end of arrayForEachItem(Part_Subsystem_t *) */ 00425 } 00426 00427 st_free_table(everyFanOuts); 00428 00429 /* Update fanOutArray into the subsystem */ 00430 testSubsystem->subsystemFanOut = fanOutArray; 00431 } /* end of arrayForEachItem(Part_Subsystem_t *) */ 00432 00433 /* Free dependency hash table */ 00434 st_free_table(fanOutDependencies); 00435 } 00436 00437 return(arrayOfPartition); 00438 } 00439 00453 array_t * 00454 Part_PartCreateSubsystems( 00455 Part_SubsystemInfo_t *subInfo, 00456 array_t *arrayOfLatchNames, 00457 array_t *arrayOfGroupIndex) 00458 { 00459 if (subInfo->verbosity > 0) { 00460 if (arrayOfLatchNames != NIL(array_t)) { 00461 fprintf(vis_stdout, "Grouping: Array of latch data is given.\n"); 00462 fprintf(vis_stdout, 00463 "Grouping: All latches related to the array will be grouped.\n"); 00464 } else if (Part_NetworkReadPartition(subInfo->network) == NIL(graph_t)) { 00465 fprintf(vis_stdout, "Grouping: Network has no partition.\n"); 00466 fprintf(vis_stdout, 00467 "Grouping: All latches in network will be grouped.\n"); 00468 } else { 00469 fprintf(vis_stdout, "Grouping: Network has a partition.\n"); 00470 fprintf(vis_stdout, 00471 "Grouping: All latches in partition will be grouped.\n"); 00472 } 00473 } 00474 return(PartCreateSubsystem(subInfo, arrayOfLatchNames, arrayOfGroupIndex)); 00475 } 00476 00491 array_t * 00492 Part_PartCreateSubsystemsWithCTL( 00493 Part_SubsystemInfo_t *subInfo, 00494 array_t *ctlArray, 00495 array_t *fairArray, 00496 boolean dynamicIncrease, 00497 boolean dynamicAndDependency) 00498 { 00499 if (subInfo->verbosity > 0 ){ 00500 fprintf(vis_stdout,"Grouping: All latches related to "); 00501 fprintf(vis_stdout,"the CTL will be grouped.\n"); 00502 } 00503 return (PartCreateSubsystemWithCTL(subInfo, ctlArray, fairArray, 00504 dynamicIncrease,dynamicAndDependency)); 00505 } 00506 00521 array_t * 00522 Part_PartCreateSubsystemsWithCtlAndLtl( 00523 Part_SubsystemInfo_t *subInfo, 00524 array_t *ctlArray, 00525 array_t *ltlArray, 00526 array_t *fairArray, 00527 boolean dynamicIncrease, 00528 boolean dynamicAndDependency, 00529 boolean strictBound) 00530 { 00531 if (subInfo->verbosity > 0 ){ 00532 fprintf(vis_stdout,"Grouping: All latches related to "); 00533 fprintf(vis_stdout,"the CTL/LTL/fairness will be grouped.\n"); 00534 } 00535 return (PartCreateSubsystemWithCtlAndLtl(subInfo, ctlArray, ltlArray, 00536 fairArray, 00537 dynamicIncrease, 00538 dynamicAndDependency, 00539 strictBound)); 00540 } 00541 00542 00550 st_table * 00551 Part_PartitionSubsystemReadVertexTable( 00552 Part_Subsystem_t *partitionedSubsystem) 00553 { 00554 return(partitionedSubsystem->vertexNameTable); 00555 } 00556 00564 array_t * 00565 Part_PartitionSubsystemReadFanIn( 00566 Part_Subsystem_t *partitionedSubsystem) 00567 { 00568 return(partitionedSubsystem->subsystemFanIn); 00569 } 00570 00578 array_t * 00579 Part_PartitionSubsystemReadFanOut( 00580 Part_Subsystem_t *partitionedSubsystem) 00581 { 00582 return(partitionedSubsystem->subsystemFanOut); 00583 } 00584 00585 00595 Part_SubsystemInfo_t * 00596 Part_PartitionSubsystemInfoInit( 00597 Ntk_Network_t *network) 00598 { 00599 Part_SubsystemInfo_t *partSubInfo; 00600 00601 partSubInfo = ALLOC(Part_SubsystemInfo_t, 1); 00602 00603 /* 00604 * set values as defaults 00605 */ 00606 partSubInfo->network = network; 00607 partSubInfo->arrayOfVertex = NIL(array_t); 00608 partSubInfo->numberOfVertex = 0; 00609 partSubInfo->partBM = Part_BFix_v; 00610 partSubInfo->con_factor = PART_SUB_CON_FACTOR; 00611 partSubInfo->cor_factor = PART_SUB_COR_FACTOR; 00612 partSubInfo->aff_factor = PART_SUB_AFF_FACTOR; 00613 partSubInfo->threshold = 0.0; 00614 partSubInfo->bound = 8; 00615 partSubInfo->verbosity = 0; 00616 partSubInfo->corMethod = Part_CorrelationDefault; 00617 partSubInfo->dupLatchTable = st_init_table(strcmp, st_strhash); 00618 partSubInfo->latchNameTable = st_init_table(strcmp, st_strhash); 00619 return(partSubInfo); 00620 } 00621 00631 void 00632 Part_PartitionSubsystemInfoFree( 00633 Part_SubsystemInfo_t *partSubInfo) 00634 { 00635 st_generator *stGen; 00636 char *latchInputName; 00637 array_t *latchNames; 00638 00639 array_free(partSubInfo->arrayOfVertex); 00640 st_foreach_item(partSubInfo->dupLatchTable, stGen, &latchInputName, 00641 &latchNames) { 00642 array_free(latchNames); 00643 } 00644 st_free_table(partSubInfo->dupLatchTable); 00645 st_free_table(partSubInfo->latchNameTable); 00646 FREE(partSubInfo); 00647 } 00648 00649 00659 void 00660 Part_PartitionSubsystemFree( 00661 Part_Subsystem_t *partSubsystem) 00662 { 00663 st_free_table(partSubsystem->vertexNameTable); 00664 array_free(partSubsystem->subsystemFanIn); 00665 array_free(partSubsystem->subsystemFanOut); 00666 FREE(partSubsystem); 00667 } 00668 00678 void 00679 Part_PartitionSubsystemInfoSetBreakingMethod( 00680 Part_SubsystemInfo_t *subInfo, 00681 Part_BMethod bMethod) 00682 { 00683 subInfo->partBM = bMethod; 00684 } 00685 00686 00696 void 00697 Part_PartitionSubsystemInfoSetBound( 00698 Part_SubsystemInfo_t *subInfo, 00699 int bound) 00700 { 00701 subInfo->bound = bound; 00702 } 00703 00713 void 00714 Part_PartitionSubsystemInfoSetThreshold( 00715 Part_SubsystemInfo_t *subInfo, 00716 float threshold) 00717 { 00718 subInfo->threshold = threshold; 00719 } 00720 00721 00731 void 00732 Part_PartitionSubsystemInfoSetVerbosity( 00733 Part_SubsystemInfo_t *subInfo, 00734 int verbosity) 00735 { 00736 subInfo->verbosity = verbosity; 00737 } 00738 00739 00749 void 00750 Part_PartitionSubsystemInfoSetCorrelationMethod( 00751 Part_SubsystemInfo_t *subInfo, 00752 Part_CMethod corMethod) 00753 { 00754 subInfo->corMethod = corMethod; 00755 } 00756 00766 void 00767 Part_PartitionSubsystemInfoSetAffinityFactor( 00768 Part_SubsystemInfo_t *subInfo, 00769 float affinity) 00770 { 00771 subInfo->aff_factor = affinity; 00772 } 00773 00774 00784 Part_Subsystem_t* 00785 Part_PartCreateSingleSubSystem( 00786 array_t *arrayOfNodes, 00787 Ntk_Network_t *network) 00788 { 00789 return PartCreateSingleSubSystem(arrayOfNodes, network); 00790 } 00791 00792 00793 /*---------------------------------------------------------------------------*/ 00794 /* Definition of internal functions */ 00795 /*---------------------------------------------------------------------------*/ 00796 00797 00819 array_t * 00820 PartCreateSubsystem( 00821 Part_SubsystemInfo_t *partSubInfo, 00822 array_t *arrayOfLatchNames, 00823 array_t *arrayOfGroupIndex) 00824 { 00825 char *arrayOfDependency = NIL(char); 00826 float *arrayOfCorrelation = NIL(float); 00827 float *arrayOfAffinity; 00828 array_t *arrayOfInit; 00829 st_table *indexToPtrInfo; /* index to pointer table */ 00830 st_table *ptrToIndexInfo; /* pointer to index table */ 00831 array_t *result; 00832 Ntk_Node_t *node; 00833 char *functionName; 00834 char *latchName; 00835 lsList vertexList; 00836 lsGen gen; 00837 int i; 00838 vertex_t *vertex; 00839 array_t *initArray; 00840 array_t *arrayOfVertex; 00841 Ntk_Network_t *network = partSubInfo->network; 00842 graph_t *partition = Part_NetworkReadPartition(network); 00843 long initialTime = 0; 00844 long finalTime; 00845 00846 if (partition == NIL(graph_t)) { 00847 if (partSubInfo->corMethod == Part_CorrelationWithBDD) { 00848 error_append("Network has no partition. Correlation "); 00849 error_append("with MDD operation can not be used.\n"); 00850 return NIL(array_t); 00851 } 00852 } 00853 if (arrayOfGroupIndex != NIL(array_t)) { 00854 if (!arrayOfLatchNames) { 00855 error_append("Latch name array is not given.\n"); 00856 result = NIL(array_t); 00857 } 00858 if (array_n(arrayOfLatchNames) != array_n(arrayOfGroupIndex)) { 00859 error_append("Given function names and index have different size.\n"); 00860 result = NIL(array_t); 00861 } 00862 } 00863 00864 if (arrayOfLatchNames && arrayOfGroupIndex) { 00865 result = PartCreateSubSystemWithGroupIndex(partSubInfo, 00866 arrayOfLatchNames, arrayOfGroupIndex); 00867 return result; 00868 } 00869 00870 arrayOfVertex = array_alloc(Ntk_Node_t *, 0); 00871 00872 /* 00873 * Convert graph vertices into array of array of vertices. 00874 */ 00875 if (partSubInfo->verbosity > 2) { 00876 fprintf(vis_stdout, "\nGroupting: List of latches\n"); 00877 fprintf(vis_stdout, "----------------------------\n"); 00878 } 00879 if (arrayOfLatchNames != NIL(array_t)) { 00880 Ntk_Node_t *latchNode, *latchInputNode; 00881 char *otherLatchName; 00882 array_t *latchNameArray; 00883 00884 arrayForEachItem(char *, arrayOfLatchNames, i, latchName) { 00885 latchNode = Ntk_NetworkFindNodeByName(network, latchName); 00886 latchInputNode = Ntk_LatchReadDataInput(latchNode); 00887 functionName = Ntk_NodeReadName(latchInputNode); 00888 if (partSubInfo->verbosity > 2) 00889 fprintf(vis_stdout, "%s\n", latchName); 00890 if (st_lookup(partSubInfo->latchNameTable, functionName, 00891 &otherLatchName)) { 00892 if (st_lookup(partSubInfo->dupLatchTable, functionName, 00893 &latchNameArray)) { 00894 array_insert_last(char *, latchNameArray, latchName); 00895 } else { 00896 latchNameArray = array_alloc(char *, 0); 00897 array_insert_last(char *, latchNameArray, otherLatchName); 00898 array_insert_last(char *, latchNameArray, latchName); 00899 st_insert(partSubInfo->dupLatchTable, (char *)functionName, 00900 (char *)latchNameArray); 00901 } 00902 continue; 00903 } 00904 st_insert(partSubInfo->latchNameTable, (char *)functionName, 00905 (char *)latchName); 00906 array_insert_last(Ntk_Node_t *, arrayOfVertex, latchInputNode); 00907 } 00908 } else if (partition == NIL(graph_t)) { 00909 Ntk_NetworkForEachNode(network, gen, node) { 00910 if (Ntk_NodeTestIsLatchDataInput(node)) { 00911 array_insert_last(Ntk_Node_t *, arrayOfVertex, node); 00912 arrayOfLatchNames = PartReadLatchNameFromLatchInput(network, node); 00913 functionName = Ntk_NodeReadName(node); 00914 latchName = array_fetch(char *, arrayOfLatchNames, 0); 00915 st_insert(partSubInfo->latchNameTable, (char *)functionName, 00916 (char *)latchName); 00917 if (array_n(arrayOfLatchNames) > 1) { 00918 st_insert(partSubInfo->dupLatchTable, (char *)functionName, 00919 (char *)arrayOfLatchNames); 00920 if (partSubInfo->verbosity > 2) { 00921 char *nname; 00922 arrayForEachItem(char *, arrayOfLatchNames, i, nname) { 00923 fprintf(vis_stdout, "%s\n", nname); 00924 } 00925 } 00926 } else { 00927 array_free(arrayOfLatchNames); 00928 if (partSubInfo->verbosity > 2) 00929 fprintf(vis_stdout, "%s\n", latchName); 00930 } 00931 } 00932 } /* End of Ntk_NetworkForEachNode */ 00933 } else { 00934 vertexList = g_get_vertices(partition); 00935 lsForEachItem(vertexList, gen, vertex) { 00936 char *nodeName = PartVertexReadName(vertex); 00937 node = Ntk_NetworkFindNodeByName(network, nodeName); 00938 if (Ntk_NodeTestIsLatchDataInput(node)) { 00939 array_insert_last(Ntk_Node_t *, arrayOfVertex, node); 00940 arrayOfLatchNames = PartReadLatchNameFromLatchInput(network, node); 00941 functionName = Ntk_NodeReadName(node); 00942 latchName = array_fetch(char *, arrayOfLatchNames, 0); 00943 st_insert(partSubInfo->latchNameTable, (char *)functionName, 00944 (char *)latchName); 00945 if (array_n(arrayOfLatchNames) > 1) { 00946 st_insert(partSubInfo->dupLatchTable, (char *)functionName, 00947 (char *)arrayOfLatchNames); 00948 if (partSubInfo->verbosity > 2) { 00949 char *nname; 00950 arrayForEachItem(char *, arrayOfLatchNames, i, nname) { 00951 fprintf(vis_stdout, "%s\n", nname); 00952 } 00953 } 00954 } else { 00955 array_free(arrayOfLatchNames); 00956 if (partSubInfo->verbosity > 2) 00957 fprintf(vis_stdout, "%s\n", latchName); 00958 } 00959 } 00960 } 00961 } 00962 00963 if (partSubInfo->verbosity > 2) { 00964 fprintf(vis_stdout, "Total # of latch data input = %d\n", 00965 array_n(arrayOfVertex)); 00966 } 00967 partSubInfo->arrayOfVertex = arrayOfVertex; 00968 partSubInfo->numberOfVertex = array_n(arrayOfVertex); 00969 00970 /* 00971 * table from index to pointer and pointer to index 00972 */ 00973 indexToPtrInfo = st_init_table(st_numcmp, st_numhash); 00974 ptrToIndexInfo = st_init_table(st_ptrcmp, st_ptrhash); 00975 00976 arrayForEachItem(Ntk_Node_t *, partSubInfo->arrayOfVertex, i, node) { 00977 st_insert(indexToPtrInfo, (char *)(long)i, (char *)node); 00978 st_insert(ptrToIndexInfo, (char *)node, (char *)(long)i); 00979 } 00980 00981 /* 00982 * get a dependency matrix 00983 */ 00984 if (partSubInfo->aff_factor > 0.0) { 00985 if (partSubInfo->verbosity > 0) 00986 initialTime = util_cpu_time(); 00987 arrayOfDependency = PartCreateDependencyMatrix(partSubInfo, ptrToIndexInfo); 00988 if (partSubInfo->verbosity > 0) { 00989 finalTime = util_cpu_time(); 00990 fprintf(vis_stdout, "time for computing dependency = %g\n", 00991 (double)(finalTime - initialTime) / 1000.0); 00992 } 00993 } 00994 00995 /* 00996 * get a correlation matrix 00997 */ 00998 if (partSubInfo->aff_factor != 1.0) { 00999 if (partSubInfo->verbosity > 0) 01000 initialTime = util_cpu_time(); 01001 if (partSubInfo->corMethod == Part_CorrelationWithBDD) 01002 arrayOfCorrelation = PartCreateCorrelationMatrixFromBDD(partSubInfo); 01003 else if ((partSubInfo->corMethod == Part_CorrelationWithSupport) || 01004 (partSubInfo->corMethod == Part_CorrelationDefault)) { 01005 arrayOfCorrelation = PartCreateCorrelationMatrixFromSupport(partSubInfo); 01006 } 01007 if (partSubInfo->verbosity > 0) { 01008 finalTime = util_cpu_time(); 01009 fprintf(vis_stdout, "time for computing correlation = %g\n", 01010 (double)(finalTime - initialTime) / 1000.0); 01011 } 01012 } 01013 01014 if (partSubInfo->verbosity > 2) { 01015 if (arrayOfDependency) { 01016 fprintf(vis_stdout, "\nGrouping: Dependency\n"); 01017 fprintf(vis_stdout, "--------------------\n"); 01018 PartPrintArrayArray(arrayOfDependency, partSubInfo->numberOfVertex, 1); 01019 } 01020 if (arrayOfCorrelation) { 01021 fprintf(vis_stdout, "\nGrouping: Correlation\n"); 01022 fprintf(vis_stdout, "---------------------\n"); 01023 PartPrintArrayArray(arrayOfCorrelation, partSubInfo->numberOfVertex, 0); 01024 } 01025 } 01026 01027 /* 01028 * get an affinity matrix, arrayOfCorrelation is freed. 01029 */ 01030 if (partSubInfo->verbosity > 0) 01031 initialTime = util_cpu_time(); 01032 arrayOfAffinity = PartCreateAffinityMatrix(arrayOfDependency, 01033 arrayOfCorrelation, partSubInfo); 01034 FREE(arrayOfCorrelation); 01035 if (partSubInfo->verbosity > 0) { 01036 finalTime = util_cpu_time(); 01037 fprintf(vis_stdout, "time for computing affinity = %g\n", 01038 (double)(finalTime - initialTime) / 1000.0); 01039 } 01040 01041 if (partSubInfo->verbosity > 2) { 01042 fprintf(vis_stdout, "\nGrouping: Affinity\n"); 01043 fprintf(vis_stdout, "------------------\n"); 01044 PartPrintArrayArray(arrayOfAffinity, partSubInfo->numberOfVertex, 0); 01045 } 01046 01047 /* 01048 * get an initial subsysytm by searching for connected component in 01049 * vertex affinity matrix 01050 */ 01051 if (partSubInfo->verbosity > 0) 01052 initialTime = util_cpu_time(); 01053 arrayOfInit = PartGetConnectedComponent(arrayOfAffinity, partSubInfo, 01054 indexToPtrInfo); 01055 if (partSubInfo->verbosity > 0) { 01056 finalTime = util_cpu_time(); 01057 fprintf(vis_stdout, "time for computing connected component = %g\n", 01058 (double)(finalTime - initialTime) / 1000.0); 01059 } 01060 01061 if (partSubInfo->verbosity > 2) { 01062 fprintf(vis_stdout, "\nGrouping: Initial connected component size\n"); 01063 fprintf(vis_stdout, "------------------------------------------\n\n"); 01064 arrayForEachItem(array_t *, arrayOfInit, i, initArray) { 01065 fprintf(vis_stdout, "%3d group: size = %d\n", i, array_n(initArray)); 01066 } 01067 } 01068 01069 /* 01070 * get a final subsystem by breaking big connected components and 01071 * aggregating small connected components. 01072 */ 01073 if (partSubInfo->verbosity > 0) 01074 initialTime = util_cpu_time(); 01075 result = PartBreakingAggregating(arrayOfInit, arrayOfAffinity, partSubInfo, 01076 ptrToIndexInfo, arrayOfDependency); 01077 if (partSubInfo->verbosity > 0) { 01078 finalTime = util_cpu_time(); 01079 fprintf(vis_stdout, "time for breaking and aggregating = %g\n", 01080 (double)(finalTime - initialTime) / 1000.0); 01081 } 01082 01083 array_free(arrayOfInit); 01084 01085 if (partSubInfo->verbosity >= 2) { 01086 Part_Subsystem_t *sub; 01087 char *latchName; 01088 st_generator *stGen; 01089 01090 fprintf(vis_stdout, "\nGrouping: List of subsytem latches\n"); 01091 fprintf(vis_stdout, "----------------------------------\n\n"); 01092 arrayForEachItem(Part_Subsystem_t *, result, i, sub) { 01093 fprintf(vis_stdout, "[Subsystem %3d]\n", i); 01094 st_foreach_item(sub->vertexNameTable, stGen, &latchName, NIL(char *)) { 01095 fprintf(vis_stdout, "%s\n", latchName); 01096 } 01097 fprintf(vis_stdout, "\n"); 01098 } 01099 } 01100 01101 if (partSubInfo->verbosity >= 1) { 01102 (void)fprintf(vis_stdout, "\nGrouping: grouping options\n"); 01103 (void)fprintf(vis_stdout, "--------------------------\n\n"); 01104 (void)fprintf(vis_stdout, "Threshold : %f\n", 01105 partSubInfo->threshold); 01106 (void)fprintf(vis_stdout, "bound : %d\n", 01107 partSubInfo->bound); 01108 (void)fprintf(vis_stdout, "connectivity factor: %f\n", 01109 partSubInfo->con_factor); 01110 (void)fprintf(vis_stdout, "correlation factor : %f\n", 01111 partSubInfo->cor_factor); 01112 (void)fprintf(vis_stdout, "affinity factor : %f\n", 01113 partSubInfo->aff_factor); 01114 (void)fprintf(vis_stdout, "\n"); 01115 } 01116 01117 st_free_table(indexToPtrInfo); 01118 st_free_table(ptrToIndexInfo); 01119 FREE(arrayOfDependency); 01120 FREE(arrayOfAffinity); 01121 01122 return result; 01123 } 01124 01125 /*---------------------------------------------------------------------------*/ 01126 /* Definition of static functions */ 01127 /*---------------------------------------------------------------------------*/ 01128 01145 static 01146 array_t * 01147 PartCreateSubsystemWithCTL( 01148 Part_SubsystemInfo_t *partSubInfo, 01149 array_t *ctlArray, 01150 array_t *fairArray, 01151 boolean dynamicIncrease, 01152 boolean dynamicAndDependency) 01153 { 01154 return PartCreateSubsystemWithCtlAndLtl(partSubInfo, ctlArray, NIL(array_t), 01155 fairArray, dynamicIncrease, 01156 dynamicAndDependency, FALSE); 01157 } 01158 01180 static 01181 array_t * 01182 PartCreateSubsystemWithCtlAndLtl( 01183 Part_SubsystemInfo_t *partSubInfo, 01184 array_t *ctlArray, 01185 array_t *ltlArray, 01186 array_t *fairArray, 01187 boolean dynamicIncrease, 01188 boolean dynamicAndDependency, 01189 boolean strictBound) 01190 { 01191 int i, j, index, maxSize, maxIndex, leftNodes, numSeed; 01192 array_t *result = NIL(array_t); 01193 Ntk_Network_t *network = partSubInfo->network; 01194 lsList latchNodeList; 01195 lsGen gen; 01196 char *arrayOfDependency = NIL(char); 01197 float *arrayOfCorrelation = NIL(float); 01198 float *arrayOfAffinity = NIL(float); 01199 array_t *arrayTemp = NIL(array_t); 01200 array_t *arrayOfVertex = NIL(array_t); 01201 array_t *arrayOfLatchNames = NIL(array_t); 01202 st_table *vertexToArrayOfLatchNames = NIL(st_table); 01203 array_t *arrayOfLatchNodeName = NIL(array_t); 01204 Ntk_Node_t *node = NIL(Ntk_Node_t); 01205 float affinity; 01206 char *name = NIL(char); 01207 st_table *indexToPtrInfo = NIL(st_table); 01208 st_table *ptrToIndexInfo = NIL(st_table); 01209 array_t *check = NIL(array_t); 01210 array_t *tempCheck = NIL(array_t); 01211 array_t *tempCC = NIL(array_t); 01212 st_generator *stGen = NIL(st_generator); 01213 array_t *arrayOfSeed = NIL(array_t); 01214 Ntk_Node_t *seedLast = NIL(Ntk_Node_t); 01215 Ntk_Node_t *seedNext = NIL(Ntk_Node_t); 01216 array_t *arrayOfBreak = NIL(array_t); 01217 array_t *arrayOfNodes = NIL(array_t); 01218 array_t *arrayOfIndex = NIL(array_t); 01219 st_table *dataInputNodes = NIL(st_table); 01220 Part_Subsystem_t *sub = NIL(Part_Subsystem_t); 01221 int numIncluded; 01222 float prevAffinity; 01223 01224 if (ctlArray == NIL(array_t) && ltlArray == NIL(array_t)){ 01225 return NIL(array_t); 01226 } 01227 01228 /* 01229 * arrayOfLatchNodeName <-- COI latch names 01230 */ 01231 latchNodeList = lsCreate(); 01232 PartGetLatchListFromCtlAndLtl(network, ctlArray, ltlArray, 01233 fairArray, latchNodeList, FALSE); 01234 arrayOfLatchNodeName = array_alloc(Ntk_Node_t *, 0); 01235 lsForEachItem(latchNodeList, gen, node){ 01236 array_insert_last(char *, arrayOfLatchNodeName, Ntk_NodeReadName(node)); 01237 } 01238 lsDestroy(latchNodeList, (void (*)(lsGeneric))0); 01239 01240 /* 01241 * arrayOfVertex <-- COI latch datainput nodes 01242 */ 01243 array_sort(arrayOfLatchNodeName, strCompare); 01244 arrayOfVertex = array_alloc(Ntk_Node_t *, 0); 01245 vertexToArrayOfLatchNames = st_init_table(st_ptrcmp, st_ptrhash); 01246 /* multiple latch may correspond to the same dataInput */ 01247 arrayForEachItem(char *, arrayOfLatchNodeName, i, name){ 01248 node = Ntk_NetworkFindNodeByName(network, name); 01249 node = Ntk_LatchReadDataInput(node); 01250 if (!st_lookup(vertexToArrayOfLatchNames, node, &arrayOfLatchNames) ) { 01251 arrayOfLatchNames = array_alloc(char *, 0); 01252 array_insert_last(char *, arrayOfLatchNames, name); 01253 st_insert(vertexToArrayOfLatchNames, node, arrayOfLatchNames); 01254 01255 array_insert_last(Ntk_Node_t *, arrayOfVertex, node); 01256 }else 01257 array_insert_last(char *, arrayOfLatchNames, name); 01258 } 01259 01260 /* 01261 * Print a list of latch names. 01262 */ 01263 if (partSubInfo->verbosity >= 2){ 01264 fprintf(vis_stdout,"\nGroupting: List of latches\n"); 01265 fprintf(vis_stdout,"------------------------\n\n"); 01266 arrayForEachItem(char *, arrayOfLatchNodeName, i, name){ 01267 fprintf(vis_stdout,"%s\n", name); 01268 } 01269 } 01270 array_free(arrayOfLatchNodeName); 01271 01272 01273 /* 01274 * dataInputNodes <-- formulae latch datainput nodes 01275 */ 01276 latchNodeList = lsCreate(); 01277 PartGetLatchListFromCtlAndLtl(network, ctlArray, ltlArray, 01278 fairArray, latchNodeList, TRUE); 01279 dataInputNodes = st_init_table( st_ptrcmp, st_ptrhash ); 01280 lsForEachItem(latchNodeList, gen, node) { 01281 Ntk_Node_t *dataInputNode = Ntk_LatchReadDataInput(node); 01282 if (!st_is_member(dataInputNodes, (char *)dataInputNode)) 01283 st_insert(dataInputNodes, (char *)dataInputNode, NIL(char)); 01284 } 01285 lsDestroy(latchNodeList, (void (*)(lsGeneric))0); 01286 01287 01288 /* 01289 * table from index to pointer and pointer to index 01290 */ 01291 partSubInfo->arrayOfVertex = arrayOfVertex; 01292 partSubInfo->numberOfVertex = array_n(arrayOfVertex); 01293 01294 indexToPtrInfo = st_init_table(st_numcmp, st_numhash); 01295 ptrToIndexInfo = st_init_table(st_ptrcmp, st_ptrhash); 01296 01297 arrayForEachItem(Ntk_Node_t *, partSubInfo->arrayOfVertex, i, node){ 01298 st_insert(indexToPtrInfo, (char *)(long)i, (char *)node); 01299 st_insert(ptrToIndexInfo, (char *)node, (char *)(long)i); 01300 } 01301 01302 check = array_alloc(int, partSubInfo->numberOfVertex); 01303 for(i=0;i<partSubInfo->numberOfVertex;i++){ 01304 array_insert(int, check, i, 0); 01305 } 01306 01307 01308 leftNodes = partSubInfo->numberOfVertex; 01309 arrayOfIndex = array_alloc(int, st_count(dataInputNodes)); 01310 result = array_alloc(Part_Subsystem_t *, 0); 01311 01312 01313 /* 01314 * If (1) number of formula nodes is smaller than bound, or (2) 01315 * strictBound is FALSE, or (3) dynamicIncrease is TRUE, create a 01316 * subsystem and put all formula nodes in the sub-system 01317 */ 01318 if ( !strictBound || st_count(dataInputNodes) <= partSubInfo->bound 01319 || dynamicIncrease ) { 01320 int numNodesInFirstSubsys; 01321 01322 if (!strictBound || st_count(dataInputNodes) <= partSubInfo->bound) 01323 numNodesInFirstSubsys = st_count(dataInputNodes); 01324 else 01325 numNodesInFirstSubsys = partSubInfo->bound; 01326 01327 arrayOfNodes = array_alloc(Ntk_Node_t *, st_count(dataInputNodes)); 01328 i=0; 01329 st_foreach_item(dataInputNodes, stGen, &node, NULL) { 01330 if (i == numNodesInFirstSubsys) break; 01331 st_lookup_int(ptrToIndexInfo, node, &index); 01332 array_insert(int, check, index, 1); 01333 array_insert(int, arrayOfIndex, i, index); 01334 array_insert(Ntk_Node_t *, arrayOfNodes, i++, node); 01335 } 01336 sub = PartCreateSingleSubSystem(arrayOfNodes, network); 01337 leftNodes -= array_n(arrayOfNodes); 01338 array_insert_last(Part_Subsystem_t *, result, sub); 01339 array_free(arrayOfNodes); 01340 01341 if (dynamicIncrease) { 01342 /* the second subsystem <-- remaining latches in dataInputTable 01343 * the thrid subsystem <-- other COI latches 01344 */ 01345 if ( dynamicAndDependency ) { 01346 if ( st_count(dataInputNodes) == numNodesInFirstSubsys ) 01347 array_insert_last(Part_Subsystem_t *, result, NIL(Part_Subsystem_t)); 01348 else { 01349 arrayOfNodes = array_alloc(Ntk_Node_t *, 0); 01350 i=0; 01351 st_foreach_item(dataInputNodes, stGen, &node, NULL) { 01352 st_lookup_int(ptrToIndexInfo, node, &index); 01353 if (array_fetch(int, check, index)==0){ 01354 array_insert(int, check, index, 1); 01355 array_insert(int, arrayOfIndex, i, index); 01356 array_insert_last(Ntk_Node_t *, arrayOfNodes, node); 01357 } 01358 } 01359 sub = PartCreateSingleSubSystem(arrayOfNodes, network); 01360 leftNodes -= array_n(arrayOfNodes); 01361 array_insert_last(Part_Subsystem_t *, result, sub); 01362 array_free(arrayOfNodes); 01363 } 01364 } 01365 01366 if (leftNodes > 0){ 01367 arrayOfNodes = array_alloc(Ntk_Node_t *, 0); 01368 arrayForEachItem(Ntk_Node_t *, partSubInfo->arrayOfVertex, i, node){ 01369 if (array_fetch(int, check, i)==0) 01370 array_insert_last(Ntk_Node_t *, arrayOfNodes, node); 01371 } 01372 sub = PartCreateSingleSubSystem(arrayOfNodes, network); 01373 array_free(arrayOfNodes); 01374 }else{ 01375 sub = NIL(Part_Subsystem_t); 01376 } 01377 array_insert_last(Part_Subsystem_t *, result, sub); 01378 01379 array_free(check); 01380 array_free(arrayOfIndex); 01381 st_free_table(ptrToIndexInfo); 01382 st_free_table(indexToPtrInfo); 01383 st_free_table(dataInputNodes); 01384 return result; 01385 } /*if dynamicIncrease*/ 01386 01387 }else { 01388 /* 01389 * If we don't want to put all formula nodes in the 1st subsystem, 01390 * we need to break them into several pieces. 01391 */ 01392 } 01393 01394 /* 01395 * get a affinity matrix (dependency matrix, correlation matrix) 01396 */ 01397 arrayOfDependency = PartCreateDependencyMatrix(partSubInfo, 01398 ptrToIndexInfo); 01399 01400 if (partSubInfo->corMethod == Part_CorrelationWithBDD) 01401 arrayOfCorrelation = PartCreateCorrelationMatrixFromBDD(partSubInfo); 01402 else if ((partSubInfo->corMethod == Part_CorrelationWithSupport) || 01403 (partSubInfo->corMethod == Part_CorrelationDefault)) 01404 arrayOfCorrelation = PartCreateCorrelationMatrixFromSupport(partSubInfo); 01405 01406 arrayOfAffinity = PartCreateAffinityMatrix(arrayOfDependency, 01407 arrayOfCorrelation, 01408 partSubInfo); 01409 01410 if (partSubInfo->verbosity > 2 ){ 01411 fprintf(vis_stdout,"\nGrouping: Dependency\n"); 01412 fprintf(vis_stdout,"--------------------\n"); 01413 PartPrintArrayArray(arrayOfDependency, partSubInfo->numberOfVertex, 1); 01414 fprintf(vis_stdout,"\nGrouping: Correlation\n"); 01415 fprintf(vis_stdout,"---------------------\n"); 01416 PartPrintArrayArray(arrayOfCorrelation, partSubInfo->numberOfVertex, 0); 01417 fprintf(vis_stdout,"\nGrouping: Affinity\n"); 01418 fprintf(vis_stdout,"------------------\n"); 01419 PartPrintArrayArray(arrayOfAffinity, partSubInfo->numberOfVertex, 0); 01420 } 01421 FREE(arrayOfDependency); 01422 FREE(arrayOfCorrelation); 01423 01424 01425 /* If number of formula nodes are bigger than bound, break down into 01426 * bounded sized subsystems. 01427 */ 01428 if (st_count(dataInputNodes) > partSubInfo->bound && strictBound ){ 01429 tempCheck = array_alloc(int, partSubInfo->numberOfVertex); 01430 tempCC = array_alloc(Ntk_Node_t *, partSubInfo->numberOfVertex); 01431 for(i=0; i<partSubInfo->numberOfVertex; i++){ 01432 array_insert(int, tempCheck, i, 1); 01433 array_insert(Ntk_Node_t *, tempCC, i, (Ntk_Node_t *)0); 01434 } 01435 i = 0; 01436 st_foreach_item(dataInputNodes, stGen, &node, NULL) { 01437 st_lookup_int(ptrToIndexInfo, node, &index); 01438 array_insert(int, arrayOfIndex, i++, index); 01439 array_insert(int, check, index, 1); 01440 array_insert(int, tempCheck, index, 0); 01441 array_insert(Ntk_Node_t *, tempCC, index, node); 01442 } 01443 01444 numSeed = (int) ceil((double)st_count(dataInputNodes)/(double)(partSubInfo->bound)); 01445 arrayOfSeed = array_alloc(Ntk_Node_t *, numSeed); 01446 seedLast = PartSelectNodeOfMinSupport(tempCC, 01447 tempCheck, partSubInfo); 01448 array_insert(Ntk_Node_t *, arrayOfSeed, 0, seedLast); 01449 for (i=1; i< numSeed; i++){ 01450 seedNext = PartSelectFarNode(seedLast, tempCC, tempCheck, 01451 arrayOfAffinity, ptrToIndexInfo); 01452 array_insert(Ntk_Node_t *, arrayOfSeed, i, seedNext); 01453 seedLast = seedNext; 01454 } 01455 01456 /* 01457 * Break formula nodes, put into table and insert into final result 01458 */ 01459 arrayOfBreak = PartBreakingBigConnectedComponent(tempCC, tempCheck, 01460 arrayOfSeed, arrayOfAffinity, partSubInfo, ptrToIndexInfo); 01461 array_free(tempCheck); 01462 array_free(tempCC); 01463 array_free(arrayOfSeed); 01464 01465 assert(array_n(arrayOfBreak) > 0); 01466 maxSize = -1; 01467 maxIndex = -1; /* don't care value to suppress warning */ 01468 arrayForEachItem(array_t *, arrayOfBreak, i, arrayOfNodes){ 01469 if (array_n(arrayOfNodes)>maxSize){ 01470 maxIndex = i; 01471 maxSize = array_n(arrayOfNodes); 01472 } 01473 } 01474 arrayOfNodes = array_fetch(array_t *, arrayOfBreak, maxIndex); 01475 sub = PartCreateSingleSubSystem(arrayOfNodes, network); 01476 leftNodes -= array_n(arrayOfNodes); 01477 array_insert_last(Part_Subsystem_t *, result, sub); 01478 arrayForEachItem(array_t *, arrayOfBreak, i, arrayOfNodes){ 01479 if (i != maxIndex){ 01480 sub = PartCreateSingleSubSystem(arrayOfNodes, network); 01481 leftNodes -= array_n(arrayOfNodes); 01482 array_insert_last(Part_Subsystem_t *, result, sub); 01483 } 01484 } 01485 PartArrayOfArrayFree(arrayOfBreak); 01486 }/* if (st_count(dataInputNodes) > partSubInfo->bound && strictBound)*/ 01487 st_free_table(dataInputNodes); 01488 01489 01490 /* 01491 * Create new affinity matrix. Now new affinity is defined from 01492 * sub-system(s) created above to left nodes. 01493 */ 01494 arrayTemp = NIL(array_t); 01495 01496 if (leftNodes > 0){ 01497 arrayTemp = array_alloc(float, partSubInfo->numberOfVertex); 01498 arrayForEachItem(int, arrayOfIndex, i, index){ 01499 for(j=0;j<partSubInfo->numberOfVertex;j++){ 01500 affinity = PartGetElementFromSymMatrix(arrayOfAffinity,index,j); 01501 if (i==0){ 01502 array_insert(float, arrayTemp, j, affinity); 01503 } else { 01504 prevAffinity = array_fetch(float, arrayTemp, j); 01505 array_insert(float, arrayTemp, j, affinity + prevAffinity); 01506 } 01507 } 01508 } 01509 01510 array_free(arrayOfIndex); 01511 FREE(arrayOfAffinity); 01512 01513 if (partSubInfo->verbosity > 2 ){ 01514 fprintf(vis_stdout,"\nGrouping:: combinded affinity\n"); 01515 fprintf(vis_stdout,"------------------\n"); 01516 arrayForEachItem(float, arrayTemp, i, affinity){ 01517 fprintf(vis_stdout, "%.10f ", affinity); 01518 } 01519 fprintf(vis_stdout, "\n"); 01520 } 01521 }else{ 01522 array_free(arrayOfIndex); 01523 FREE(arrayOfAffinity); 01524 } 01525 01526 /* 01527 * Create sub-system by choosing a nodes with biggest new affinity 01528 */ 01529 while( leftNodes > 0 ){ 01530 numIncluded = 0; 01531 arrayOfVertex = array_alloc(Ntk_Node_t *, 0); 01532 while ((numIncluded < partSubInfo->bound) && (leftNodes > 0)){ 01533 /* 01534 * The node with maximum affinity to formula nodes is included 01535 * in next sub-system until number of nodes reaches to bound 01536 */ 01537 prevAffinity = -1.0; 01538 maxIndex = 0; 01539 arrayForEachItem( float, arrayTemp, i, affinity){ 01540 if ( array_fetch(int, check, i) != 1 ){ 01541 if (affinity >= prevAffinity){ 01542 prevAffinity = affinity; 01543 maxIndex = i; 01544 } 01545 } 01546 } 01547 st_lookup(indexToPtrInfo, (char *)(long)maxIndex, &node); 01548 array_insert_last(Ntk_Node_t *, arrayOfVertex, node); 01549 array_insert(int, check, maxIndex, 1); 01550 numIncluded++; 01551 leftNodes--; 01552 } 01553 sub = PartCreateSingleSubSystem(arrayOfVertex, network); 01554 array_free(arrayOfVertex); 01555 array_insert_last(Part_Subsystem_t *, result, sub); 01556 } 01557 01558 array_free(check); 01559 if (arrayTemp != NIL(array_t)) 01560 array_free(arrayTemp); 01561 st_free_table(ptrToIndexInfo); 01562 st_free_table(indexToPtrInfo); 01563 01564 01565 if (partSubInfo->verbosity >= 2){ 01566 Part_Subsystem_t *sub; 01567 char *latchName; 01568 st_generator *stGen; 01569 01570 fprintf(vis_stdout,"\nGrouping: List of subsytem latches\n"); 01571 fprintf(vis_stdout,"----------------------------------\n\n"); 01572 arrayForEachItem(Part_Subsystem_t *, result, i, sub){ 01573 fprintf(vis_stdout,"[Subsystem %3d]\n",i); 01574 st_foreach_item(sub->vertexNameTable, stGen, &latchName, NIL(char *) ){ 01575 fprintf(vis_stdout,"%s\n",latchName); 01576 } 01577 fprintf(vis_stdout,"\n"); 01578 } 01579 } 01580 01581 return result; 01582 } 01583 01584 01595 static char * 01596 PartCreateDependencyMatrix( 01597 Part_SubsystemInfo_t *partSubInfo, 01598 st_table *ptrToIndex) 01599 { 01600 char *result; 01601 array_t *arrayNodeFrom; 01602 int i, j, k; 01603 Ntk_Node_t *node, *latchInputNode; 01604 array_t *arrayOfSupport; 01605 Ntk_Network_t *network = partSubInfo->network; 01606 int index, size; 01607 01608 size = partSubInfo->numberOfVertex; 01609 result = ALLOC(char, size * size); 01610 (void)memset((void *)result, 0, sizeof(char) * size * size); 01611 01612 for (i = 0; i < partSubInfo->numberOfVertex; i++) { 01613 node = array_fetch(Ntk_Node_t *, partSubInfo->arrayOfVertex, i); 01614 arrayNodeFrom = array_alloc(Ntk_Node_t *, 1); 01615 array_insert(Ntk_Node_t *, arrayNodeFrom, 0, node); 01616 arrayOfSupport = Ntk_NodeComputeCombinationalSupport(network, 01617 arrayNodeFrom, 01618 FALSE); 01619 array_free(arrayNodeFrom); 01620 arrayForEachItem(Ntk_Node_t *, arrayOfSupport, j, node) { 01621 if (!Ntk_NodeTestIsLatch(node)) 01622 continue; 01623 latchInputNode = Ntk_LatchReadDataInput(node); 01624 if (st_lookup_int(ptrToIndex, (char *)latchInputNode, &k)) { 01625 index = i * partSubInfo->numberOfVertex + k; 01626 result[index] = 1; 01627 } else { 01628 fprintf(vis_stderr, 01629 "** part error: can't find the latch input index.\n"); 01630 } 01631 } 01632 array_free(arrayOfSupport); 01633 } 01634 return result; 01635 } 01636 01637 01646 static float * 01647 PartCreateCorrelationMatrixFromSupport( 01648 Part_SubsystemInfo_t *partSubInfo) 01649 { 01650 int i, j; 01651 float *result; 01652 float correlation; 01653 array_t *arrayOfSupport; 01654 st_table *tableOfSupport; 01655 array_t *arrayOfSupportTable; 01656 array_t *arrayNodeFrom; 01657 Ntk_Node_t *nodeFrom, *node; 01658 Ntk_Network_t *network = partSubInfo->network; 01659 int index; 01660 01661 result = ALLOC(float, 01662 partSubInfo->numberOfVertex * (partSubInfo->numberOfVertex - 1) / 2); 01663 01664 arrayOfSupportTable = array_alloc(st_table *, partSubInfo->numberOfVertex); 01665 01666 for (i = 0; i < partSubInfo->numberOfVertex; i++) { 01667 nodeFrom = array_fetch(Ntk_Node_t *, partSubInfo->arrayOfVertex, i); 01668 arrayNodeFrom = array_alloc(Ntk_Node_t *, 1); 01669 array_insert(Ntk_Node_t *, arrayNodeFrom, 0, nodeFrom); 01670 arrayOfSupport = Ntk_NodeComputeCombinationalSupport(network, 01671 arrayNodeFrom, 01672 FALSE); 01673 array_free(arrayNodeFrom); 01674 tableOfSupport = st_init_table(st_ptrcmp, st_ptrhash); 01675 arrayForEachItem(Ntk_Node_t *, arrayOfSupport, j, node) { 01676 st_insert(tableOfSupport, (char *)node, (char *)NULL); 01677 } 01678 array_free(arrayOfSupport); 01679 array_insert(st_table *, arrayOfSupportTable, i, tableOfSupport); 01680 } 01681 01682 for (i = 1; i < partSubInfo->numberOfVertex; i++) { 01683 for (j = 0; j < i; j++) { 01684 correlation = PartVertexComputeCorrelation(i, j, arrayOfSupportTable, 01685 partSubInfo); 01686 index = i * (i - 1) / 2 + j; 01687 result[index] = correlation; 01688 } 01689 }/* end of for */ 01690 01691 for (i = 0; i < partSubInfo->numberOfVertex; i++) 01692 st_free_table(array_fetch(st_table *, arrayOfSupportTable, i)); 01693 array_free(arrayOfSupportTable); 01694 01695 return result; 01696 } 01697 01698 01707 static float * 01708 PartCreateCorrelationMatrixFromBDD( 01709 Part_SubsystemInfo_t *partSubInfo) 01710 { 01711 int i, j; 01712 float *result; 01713 array_t *agreeArray; 01714 array_t *arrayOfMddArray; 01715 float agreement; 01716 float correlation = 0.0; 01717 char *name; 01718 Ntk_Node_t *node; 01719 Mvf_Function_t *mvf; 01720 vertex_t *vertex; 01721 graph_t *partition = Part_NetworkReadPartition(partSubInfo->network); 01722 mdd_manager *mddmgr = PartPartitionReadMddManager(partition); 01723 int index; 01724 01725 result = ALLOC(float, 01726 partSubInfo->numberOfVertex * (partSubInfo->numberOfVertex - 1) / 2); 01727 01728 arrayOfMddArray = array_alloc(array_t *, partSubInfo->numberOfVertex); 01729 for (i = 0; i < partSubInfo->numberOfVertex; i++) { 01730 node = array_fetch(Ntk_Node_t *, partSubInfo->arrayOfVertex, i); 01731 name = Ntk_NodeReadName(node); 01732 vertex = Part_PartitionFindVertexByName(partition, name); 01733 mvf = Part_VertexReadFunction(vertex); 01734 array_insert(array_t *, arrayOfMddArray, i, (array_t *)mvf); 01735 } 01736 01737 for (i = 1; i < partSubInfo->numberOfVertex; i++) { 01738 for (j = 0; j < i; j++) { 01739 int k; 01740 agreeArray = PartVertexComputeAgreement(mddmgr, i, j, arrayOfMddArray); 01741 correlation = 0.0; 01742 arrayForEachItem(float, agreeArray, k, agreement) { 01743 correlation += (float)pow(1.0 - 4.0 * agreement * (1.0 - agreement), 01744 partSubInfo->cor_factor); 01745 } 01746 correlation /= (float)array_n(agreeArray); 01747 array_free(agreeArray); 01748 index = i * (i - 1) / 2 + j; 01749 result[index] = correlation; 01750 } 01751 }/* end of for */ 01752 01753 array_free(arrayOfMddArray); 01754 return result; 01755 } 01756 01757 01766 static float 01767 PartVertexComputeCorrelation( 01768 int index1, 01769 int index2, 01770 array_t *arrayOfInputSupportTable, 01771 Part_SubsystemInfo_t *partSubInfo) 01772 { 01773 st_generator *stGen; 01774 st_table *inputSupportTable1; 01775 st_table *inputSupportTable2; 01776 int sameSupportCount; 01777 float correlation; 01778 int inputSupportCount; 01779 Ntk_Node_t *node; 01780 01781 sameSupportCount = 0; 01782 inputSupportTable1 = array_fetch(st_table *, arrayOfInputSupportTable, 01783 index1); 01784 inputSupportTable2 = array_fetch(st_table *, arrayOfInputSupportTable, 01785 index2); 01786 01787 st_foreach_item(inputSupportTable1, stGen, &node, NULL) { 01788 if (st_is_member(inputSupportTable2, node)) { 01789 sameSupportCount++; 01790 } 01791 } 01792 01793 inputSupportCount = st_count(inputSupportTable1) + 01794 st_count(inputSupportTable2) - sameSupportCount; 01795 if (inputSupportCount != 0) { 01796 correlation = (float)pow((double)sameSupportCount / 01797 (double)inputSupportCount, 01798 (double)partSubInfo->cor_factor); 01799 } else { 01800 correlation = 0.0; 01801 } 01802 return correlation; 01803 } 01804 01805 01814 static array_t * 01815 PartVertexComputeAgreement( 01816 mdd_manager *mddMgr, 01817 int index1, 01818 int index2, 01819 array_t *arrayOfMddArray) 01820 { 01821 int i, j; 01822 float agreement; 01823 mdd_t *mddFrom, *mddTo; 01824 array_t *mddArrayFrom, *mddArrayTo; 01825 array_t *agreeArray = array_alloc(float, 0); 01826 01827 mddArrayFrom = array_fetch(array_t *, arrayOfMddArray, index1); 01828 mddArrayTo = array_fetch(array_t *, arrayOfMddArray, index2); 01829 arrayForEachItem(mdd_t *, mddArrayFrom, i, mddFrom) { 01830 arrayForEachItem(mdd_t *, mddArrayTo, j, mddTo) { 01831 agreement = bdd_correlation(mddFrom, mddTo); 01832 array_insert_last(float, agreeArray, agreement); 01833 } 01834 } 01835 01836 return agreeArray; 01837 } 01838 01839 01855 static float * 01856 PartCreateAffinityMatrix( 01857 char *arrayOfDependency, 01858 float *arrayOfCorrelation, 01859 Part_SubsystemInfo_t *partSubInfo) 01860 { 01861 float *result; 01862 int i, j; 01863 float dep1, dep2; 01864 float connectivity = 0.0; 01865 float correlation = 0.0; 01866 float affinity; 01867 int index; 01868 01869 result = ALLOC(float, 01870 partSubInfo->numberOfVertex * (partSubInfo->numberOfVertex - 1) / 2); 01871 01872 for (i = 1; i < partSubInfo->numberOfVertex; i++) { 01873 for (j = 0; j < i; j++) { 01874 if (arrayOfDependency) { 01875 dep1 = dep2 = 0.0; 01876 index = i * partSubInfo->numberOfVertex + j; 01877 if (arrayOfDependency[index] == 1) 01878 dep1 = 1.0; 01879 index = j * partSubInfo->numberOfVertex + i; 01880 if (arrayOfDependency[index] == 1) 01881 dep2 = 1.0; 01882 connectivity = (dep1 + dep2 + 01883 (partSubInfo->con_factor - 2) * dep1 * dep2) / 01884 partSubInfo->con_factor; 01885 } else 01886 connectivity = 0.0; 01887 01888 if (arrayOfCorrelation) 01889 correlation = PartGetElementFromSymMatrix(arrayOfCorrelation, i, j); 01890 else 01891 correlation = 0.0; 01892 01893 /* 01894 * affinity is a convex function of connectivity and correlation 01895 */ 01896 affinity = partSubInfo->aff_factor * connectivity + 01897 (1.0 - partSubInfo->aff_factor) * correlation; 01898 index = i * (i - 1) / 2 + j; 01899 result[index] = affinity; 01900 } 01901 } 01902 return result; 01903 } 01904 01917 static array_t * 01918 PartGetConnectedComponent( 01919 float *arrayOfAffinity, 01920 Part_SubsystemInfo_t *partSubInfo, 01921 st_table *indexToPtr) 01922 { 01923 array_t *arrayOfCCs; /* array of connected component */ 01924 array_t *connectedComponent; 01925 array_t *arrayOfFrom; 01926 array_t *arrayOfCCIndex; /* keep ccId of each vertex */ 01927 float affinity, affmax; 01928 float affsum, density, nonZeroCount; 01929 int next; /* serching connected component from this index */ 01930 int ccId; /* each connected component gets its own ccId */ 01931 int ccIndex; 01932 int i, size; 01933 Ntk_Node_t *node; 01934 01935 next = 0; /* keep the smallest index of vertex not included in CC */ 01936 ccId = 0; /* give ccId to each CC */ 01937 affmax = 0.0; 01938 affsum = 0.0; 01939 nonZeroCount = 0; 01940 01941 arrayOfCCIndex = array_alloc(int, partSubInfo->numberOfVertex); 01942 /* 01943 * Initially, all vertecies are included in one component 01944 */ 01945 for (i = 0; i < partSubInfo->numberOfVertex; i++) { 01946 array_insert(int, arrayOfCCIndex, i, 0); 01947 } 01948 /* 01949 * If the threshold is not defined, get an average of affinity in the matrix 01950 * and a density. Threshold is assigned between average of affinity and 01951 * the maximum value of affinity according to density. If the matrix is 01952 * dense(sparse), threshold goes up(goes down). 01953 */ 01954 if (partSubInfo->threshold == 0.0) { 01955 size = partSubInfo->numberOfVertex * (partSubInfo->numberOfVertex - 1) / 2; 01956 for (i = 0; i < size; i++) { 01957 affinity = arrayOfAffinity[i]; 01958 if (affmax < affinity) { 01959 affmax = affinity; 01960 } 01961 if (affinity > 0.0) { 01962 nonZeroCount += 1.0; 01963 } 01964 affsum += affinity; 01965 } 01966 density = nonZeroCount / pow((double)partSubInfo->numberOfVertex, 2.0); 01967 partSubInfo->threshold = (float)((affsum / nonZeroCount) + 01968 (affmax - affsum / nonZeroCount) * density); 01969 } 01970 01971 /* 01972 * Get a connected component from the vertex which is pointed by 'next' 01973 * with its index. The 'next' is updated during searching CC in the function 01974 * PartFindCC 01975 */ 01976 while (next < partSubInfo->numberOfVertex) { 01977 ccId++; 01978 array_insert(int, arrayOfCCIndex, next, ccId); 01979 if (next == partSubInfo->numberOfVertex - 1) { 01980 break; 01981 } 01982 arrayOfFrom = array_alloc(int, 1); 01983 array_insert(int, arrayOfFrom, 0, next); 01984 PartFindCC(&next, &ccId, arrayOfCCIndex, arrayOfAffinity, arrayOfFrom, 01985 partSubInfo); 01986 } 01987 01988 /* 01989 * initialize arrayOfCCs, which is the result. 01990 */ 01991 arrayOfCCs = array_alloc(array_t *, ccId); 01992 for (i = 0; i < ccId; i++) { 01993 connectedComponent = array_alloc(Ntk_Node_t *, 0); 01994 array_insert(array_t *, arrayOfCCs, i, connectedComponent); 01995 } 01996 01997 /* 01998 * change index to vertex pointer and insert into each CC 01999 */ 02000 arrayForEachItem(int, arrayOfCCIndex, i, ccIndex) { 02001 st_lookup(indexToPtr, (char *)(long)i, &node); 02002 connectedComponent = array_fetch(array_t *, arrayOfCCs, ccIndex-1); 02003 array_insert_last(Ntk_Node_t *, connectedComponent, node); 02004 02005 } 02006 array_free(arrayOfCCIndex); 02007 return arrayOfCCs; 02008 } 02009 02020 static void 02021 PartFindCC( 02022 int *next, 02023 int *ccId, 02024 array_t *arrayOfCCIndex, 02025 float *arrayOfAffinity, 02026 array_t *arrayOfFrom, 02027 Part_SubsystemInfo_t *partSubInfo) 02028 { 02029 int i, j, from; 02030 int arrayInd; 02031 float connected; 02032 array_t *arrayOfReached; 02033 02034 /* 02035 * Update next in order to let next keep the smallest vertex index which 02036 * is not traversed. 02037 */ 02038 (*next)++; 02039 while (1) { 02040 if (*next == partSubInfo->numberOfVertex) { 02041 array_free(arrayOfFrom); 02042 return; 02043 } 02044 if (array_fetch(int, arrayOfCCIndex, *next) != 0) { 02045 (*next)++; 02046 } else { 02047 break; 02048 } 02049 } 02050 02051 arrayOfReached = array_alloc(int, 0); /* Reached set from arrayOfFrom */ 02052 02053 /* 02054 * Find all vertecies which can be traversed from arrayOfFrom 02055 * and update next 02056 */ 02057 while (array_n(arrayOfFrom) > 0) { 02058 arrayForEachItem(int, arrayOfFrom, i, from) { 02059 for (j = 0; j < partSubInfo->numberOfVertex; j++) { 02060 connected = PartGetElementFromSymMatrix(arrayOfAffinity, from, j); 02061 arrayInd = array_fetch(int, arrayOfCCIndex, j); 02062 if (connected > partSubInfo->threshold && arrayInd == 0) { 02063 array_insert_last(int, arrayOfReached, j); 02064 array_insert(int, arrayOfCCIndex, j, *ccId); 02065 if (*next == j) { 02066 (*next)++; 02067 while (1) { 02068 if (*next == partSubInfo->numberOfVertex) { 02069 array_free(arrayOfReached); 02070 array_free(arrayOfFrom); 02071 return; 02072 } 02073 if (array_fetch(int, arrayOfCCIndex, *next) != 0) { 02074 (*next)++; 02075 } else { 02076 break; 02077 } 02078 }/* end of while */ 02079 }/* end if */ 02080 } 02081 }/* end for */ 02082 }/* end of arrayForEachItem(arrayOfFrom) */ 02083 array_free(arrayOfFrom); 02084 arrayOfFrom = arrayOfReached; /* Traverse with new reached set */ 02085 arrayOfReached = array_alloc(int, 0); 02086 }/* end of while */ 02087 array_free(arrayOfFrom); 02088 array_free(arrayOfReached); 02089 return; 02090 } 02091 02104 static array_t * 02105 PartBreakingAggregating( 02106 array_t *arrayOfInit, 02107 float *arrayOfAffinity, 02108 Part_SubsystemInfo_t *partSubInfo, 02109 st_table *ptrToIndex, 02110 char *arrayOfDependency) 02111 { 02112 array_t *arrayOfAggregate; 02113 array_t *arrayOfSeed; 02114 array_t *arrayOfSmall; 02115 array_t *arrayOfBreak; 02116 array_t *arrayOfFinal; 02117 array_t *arrayOfCCVertex; 02118 array_t *arrayVertex; 02119 array_t *arrayOfNew; 02120 array_t *cc; 02121 array_t *ccCheck; /* check cc which is included in final result */ 02122 float *groupDependency; 02123 st_table *tableOfCC; 02124 float groupDep; 02125 int i, j, k, l; 02126 array_t *arrayOfLatchNames; 02127 char *name; 02128 Part_Subsystem_t *sub; 02129 Part_Subsystem_t *subIn; 02130 Part_Subsystem_t *subOut; 02131 Ntk_Node_t *seedlast, *seednext, *node; 02132 char *funcName; 02133 02134 arrayOfSmall = array_alloc(array_t *, 0); 02135 arrayOfFinal = array_alloc(Part_Subsystem_t *, 0); 02136 arrayOfCCVertex = array_alloc(array_t *, 0); 02137 02138 if (partSubInfo->bound == 0) { 02139 partSubInfo->bound = partSubInfo->numberOfVertex / array_n(arrayOfInit); 02140 } 02141 02142 arrayForEachItem(array_t *, arrayOfInit, i, cc) { 02143 if (array_n(cc) > partSubInfo->bound) { 02144 /* 02145 * If cc has more vertecies than bound, calculate how many seeds are needed 02146 * and get those seeds which are far away from each others 02147 */ 02148 ccCheck = array_alloc(int, array_n(cc)); 02149 for (j = 0; j < array_n(cc); j++) { 02150 array_insert(int, ccCheck, j, 0); 02151 } 02152 02153 /* 02154 * The first seed is the vertex which has the smallest support and 02155 * choose the next vertex which is the farthest from last seed 02156 */ 02157 arrayOfSeed = array_alloc(Ntk_Node_t *, 0); 02158 seedlast = PartSelectNodeOfMinSupport(cc, ccCheck, partSubInfo); 02159 array_insert_last(Ntk_Node_t *, arrayOfSeed, seedlast); 02160 for (j = 1; j < ceil((double)array_n(cc) / (double)(partSubInfo->bound)); 02161 j++) { 02162 seednext = PartSelectFarNode(seedlast, cc, ccCheck, arrayOfAffinity, 02163 ptrToIndex); 02164 array_insert_last(Ntk_Node_t *, arrayOfSeed, seednext); 02165 seedlast = seednext; 02166 } 02167 /* 02168 * Break big CC, put into table and insert into final result 02169 */ 02170 arrayOfBreak = PartBreakingBigConnectedComponent(cc, ccCheck, 02171 arrayOfSeed, arrayOfAffinity, partSubInfo, ptrToIndex); 02172 array_free(ccCheck); 02173 array_free(arrayOfSeed); 02174 02175 arrayForEachItem(array_t *, arrayOfBreak, j, arrayOfNew) { 02176 if (array_n(arrayOfNew) == partSubInfo->bound) { 02177 tableOfCC = st_init_table(strcmp, st_strhash); 02178 arrayVertex = array_alloc(Ntk_Node_t *, array_n(arrayOfNew)); 02179 arrayForEachItem(Ntk_Node_t *, arrayOfNew, k, node) { 02180 funcName = Ntk_NodeReadName(node); 02181 if (st_lookup(partSubInfo->dupLatchTable, funcName, 02182 &arrayOfLatchNames)) { 02183 arrayForEachItem(char *, arrayOfLatchNames, l, name) { 02184 st_insert(tableOfCC, (char *)name, (char *)NULL); 02185 } 02186 } else { 02187 if (st_lookup(partSubInfo->latchNameTable, (char *)funcName, 02188 (char **)&name)) { 02189 st_insert(tableOfCC, (char *)name, (char *)NULL); 02190 } else 02191 error_append("can't find the latch name."); 02192 } 02193 array_insert(Ntk_Node_t *, arrayVertex, k, node); 02194 } 02195 sub = ALLOC(Part_Subsystem_t, 1); 02196 sub->vertexNameTable = tableOfCC; 02197 sub->subsystemFanIn = array_alloc(int, 0); 02198 sub->subsystemFanOut = array_alloc(int, 0); 02199 array_insert_last(Part_Subsystem_t *, arrayOfFinal, sub); 02200 array_insert_last(array_t *, arrayOfCCVertex, arrayVertex); 02201 array_free(arrayOfNew); 02202 } else { 02203 array_insert_last(array_t *, arrayOfSmall, arrayOfNew); 02204 } 02205 }/* end of arrayForEachItem(arrayOfBreak) */ 02206 array_free(arrayOfBreak); 02207 array_free(cc); 02208 } else if (array_n(cc) < partSubInfo->bound) { 02209 /* 02210 * If cc has less nodes than bound, put into arrayOfSmall 02211 */ 02212 array_insert_last(array_t *, arrayOfSmall, cc); 02213 } else { 02214 /* 02215 * If cc has same number of verteices as bound, put into table and 02216 * insert into final result 02217 */ 02218 tableOfCC = st_init_table(strcmp, st_strhash); 02219 arrayVertex = array_alloc(Ntk_Node_t *, array_n(cc)); 02220 arrayForEachItem(Ntk_Node_t *, cc, j, node) { 02221 funcName = Ntk_NodeReadName(node); 02222 if (st_lookup(partSubInfo->dupLatchTable, funcName, 02223 &arrayOfLatchNames)) { 02224 arrayForEachItem(char *, arrayOfLatchNames, l, name) { 02225 st_insert(tableOfCC, (char *)name, (char *)NULL); 02226 } 02227 } else { 02228 if (st_lookup(partSubInfo->latchNameTable, (char *)funcName, 02229 (char **)&name)) { 02230 st_insert(tableOfCC, (char *)name, (char *)NULL); 02231 } else 02232 error_append("can't find the latch name."); 02233 } 02234 array_insert(Ntk_Node_t *, arrayVertex, j, node); 02235 } 02236 sub = ALLOC(Part_Subsystem_t, 1); 02237 sub->vertexNameTable = tableOfCC; 02238 sub->subsystemFanIn = array_alloc(int, 0); 02239 sub->subsystemFanOut = array_alloc(int, 0); 02240 array_insert_last(Part_Subsystem_t *, arrayOfFinal, sub); 02241 array_insert_last(array_t *, arrayOfCCVertex, arrayVertex); 02242 array_free(cc); 02243 } 02244 } 02245 02246 /* 02247 * aggregate small cc, put into table and insert into final resault 02248 */ 02249 arrayOfAggregate = PartAggregating(arrayOfSmall, arrayOfAffinity, 02250 partSubInfo, ptrToIndex); 02251 02252 array_free(arrayOfSmall); 02253 02254 arrayForEachItem(array_t *, arrayOfAggregate, i, arrayOfNew) { 02255 tableOfCC = st_init_table(strcmp, st_strhash); 02256 arrayVertex = array_alloc(Ntk_Node_t *, array_n(arrayOfNew)); 02257 arrayForEachItem(Ntk_Node_t *, arrayOfNew, j, node) { 02258 funcName = Ntk_NodeReadName(node); 02259 if (st_lookup(partSubInfo->dupLatchTable, funcName, 02260 &arrayOfLatchNames)) { 02261 arrayForEachItem(char *, arrayOfLatchNames, l, name) { 02262 st_insert(tableOfCC, (char *)name, (char *)NULL); 02263 } 02264 } else { 02265 if (st_lookup(partSubInfo->latchNameTable, (char *)funcName, 02266 (char **)&name)) { 02267 st_insert(tableOfCC, (char *)name, (char *)NULL); 02268 } else 02269 error_append("can't find the latch name."); 02270 } 02271 array_insert(Ntk_Node_t *, arrayVertex, j, node); 02272 } 02273 sub = ALLOC(Part_Subsystem_t, 1); 02274 sub->vertexNameTable = tableOfCC; 02275 sub->subsystemFanIn = array_alloc(int, 0); 02276 sub->subsystemFanOut = array_alloc(int, 0); 02277 array_insert_last(Part_Subsystem_t *, arrayOfFinal, sub); 02278 array_insert_last(array_t *, arrayOfCCVertex, arrayVertex); 02279 array_free(arrayOfNew); 02280 }/* end of arrayForEachItem(arrayOfAggregate) */ 02281 02282 array_free(arrayOfAggregate); 02283 02284 /* 02285 * Get group dependency, which is dependency between two subsystems from 02286 * dependency between vertecies 02287 */ 02288 groupDependency = PartGetGroupMatrixRegular(arrayOfCCVertex, 02289 arrayOfDependency, ptrToIndex, 02290 partSubInfo->numberOfVertex); 02291 02292 if (partSubInfo->verbosity >= 2) { 02293 int index; 02294 fprintf(vis_stdout, "\nGrouping: Group Dependency\n"); 02295 fprintf(vis_stdout, "--------------------------\n"); 02296 for (i = 0; i < array_n(arrayOfCCVertex); i++) { 02297 for (j = 0; j < array_n(arrayOfCCVertex); j++) { 02298 index = i * array_n(arrayOfCCVertex) + j; 02299 fprintf(vis_stdout, "%4.3f ", groupDependency[index]); 02300 } 02301 fprintf(vis_stdout, "\n"); 02302 } 02303 } 02304 02305 for (i = 0; i < array_n(arrayOfCCVertex); i++) { 02306 subIn = array_fetch(Part_Subsystem_t *, arrayOfFinal, i); 02307 for (j = 0; j < array_n(arrayOfCCVertex); j++) { 02308 subOut = array_fetch(Part_Subsystem_t *, arrayOfFinal, j); 02309 if (i != j) { 02310 int index; 02311 02312 index = i * array_n(arrayOfCCVertex) + j; 02313 groupDep = groupDependency[index]; 02314 if (groupDep > 0.0) { 02315 array_insert_last(int, subIn ->subsystemFanIn, j); 02316 array_insert_last(int, subOut->subsystemFanOut, i); 02317 } 02318 } 02319 } 02320 } 02321 PartArrayOfArrayFree(arrayOfCCVertex); 02322 FREE(groupDependency); 02323 return arrayOfFinal; 02324 } 02325 02338 static array_t * 02339 PartCreateSubSystemWithGroupIndex( 02340 Part_SubsystemInfo_t *partSubInfo, 02341 array_t *arrayOfLatchNames, 02342 array_t *arrayOfGroupIndex) 02343 { 02344 int i, j; 02345 array_t *result; 02346 char *latchName; 02347 array_t *arrayOfGroupVertex; 02348 array_t *arrayOfVertex; 02349 array_t *arrayOfLatchDataInputNames; 02350 Ntk_Node_t *node, *latchNode, *latchInputNode; 02351 Part_Subsystem_t *sub; 02352 st_table *groupIndexTable; 02353 st_table **faninIndexTable, **fanoutIndexTable; 02354 char *name; 02355 array_t *arrayOfSupport; 02356 st_generator *stGen; 02357 int nLatches; 02358 int nGroups = 0; 02359 int preIndex, newIndex; 02360 long index; 02361 char *otherLatchName; 02362 array_t *latchNameArray; 02363 02364 nLatches = array_n(arrayOfLatchNames); 02365 02366 /* reassign group index with counting the number of groups */ 02367 groupIndexTable = st_init_table(st_numcmp, st_numhash); 02368 preIndex = -1; 02369 arrayForEachItem(int, arrayOfGroupIndex, i, index) { 02370 if (index == preIndex || 02371 st_lookup_int(groupIndexTable, (char *)index, &newIndex)) { 02372 if (index != newIndex) 02373 array_insert(int, arrayOfGroupIndex, i, newIndex); 02374 } else { 02375 st_insert(groupIndexTable, (char *)index, (char *)(long)nGroups); 02376 newIndex = nGroups++; 02377 if (index != newIndex) 02378 array_insert(int, arrayOfGroupIndex, i, newIndex); 02379 } 02380 preIndex = (int) index; 02381 } 02382 st_free_table(groupIndexTable); 02383 02384 groupIndexTable = st_init_table(strcmp, st_strhash); 02385 faninIndexTable = ALLOC(st_table *, nGroups); 02386 fanoutIndexTable = ALLOC(st_table *, nGroups); 02387 for (i = 0; i < nGroups; i++) { 02388 faninIndexTable[i] = st_init_table(st_numcmp, st_numhash); 02389 fanoutIndexTable[i] = st_init_table(st_numcmp, st_numhash); 02390 } 02391 02392 /* makes an array of latch input names from latch names */ 02393 arrayOfLatchDataInputNames = array_alloc(char *, 0); 02394 arrayForEachItem(char *, arrayOfLatchNames, i, latchName) { 02395 latchNode = Ntk_NetworkFindNodeByName(partSubInfo->network, latchName); 02396 latchInputNode = Ntk_LatchReadDataInput(latchNode); 02397 name = Ntk_NodeReadName(latchInputNode); 02398 array_insert_last(char *, arrayOfLatchDataInputNames, name); 02399 } 02400 02401 result = array_alloc(Part_Subsystem_t *, nGroups); 02402 arrayOfGroupVertex = array_alloc(array_t *, nGroups); 02403 02404 /* creates subsystems */ 02405 for (i = 0; i < nGroups; i++) { 02406 sub = ALLOC(Part_Subsystem_t, 1); 02407 sub->vertexNameTable = st_init_table(strcmp, st_strhash); 02408 sub->subsystemFanIn = array_alloc(int, 0); 02409 sub->subsystemFanOut = array_alloc(int, 0); 02410 arrayOfVertex = array_alloc(Ntk_Node_t *, 0); 02411 array_insert(Part_Subsystem_t *, result, i, sub); 02412 array_insert(array_t *, arrayOfGroupVertex, i, arrayOfVertex); 02413 } 02414 02415 /* makes group index table and fills in the vertex name table */ 02416 for (i = 0; i < nLatches; i++) { 02417 index = (long) array_fetch(int, arrayOfGroupIndex, i); 02418 name = array_fetch(char *, arrayOfLatchDataInputNames, i); 02419 latchName = array_fetch(char *, arrayOfLatchNames, i); 02420 02421 sub = array_fetch(Part_Subsystem_t *, result, (int) index); 02422 latchNode = Ntk_NetworkFindNodeByName(partSubInfo->network, latchName); 02423 latchName = Ntk_NodeReadName(latchNode); 02424 st_insert(sub->vertexNameTable, (char *)latchName, (char *)NULL); 02425 02426 if (st_lookup(partSubInfo->latchNameTable, name, &otherLatchName)) { 02427 if (st_lookup(partSubInfo->dupLatchTable, name, &latchNameArray)) { 02428 array_insert_last(char *, latchNameArray, latchName); 02429 } else { 02430 latchNameArray = array_alloc(char *, 0); 02431 array_insert_last(char *, latchNameArray, otherLatchName); 02432 array_insert_last(char *, latchNameArray, latchName); 02433 st_insert(partSubInfo->dupLatchTable, name, latchNameArray); 02434 } 02435 continue; 02436 } 02437 02438 st_insert(partSubInfo->latchNameTable, name, latchName); 02439 st_insert(groupIndexTable, name, (char *)index); 02440 02441 arrayOfVertex = array_fetch(array_t *, arrayOfGroupVertex, (int)index); 02442 node = Ntk_NetworkFindNodeByName(partSubInfo->network, name); 02443 array_insert_last(Ntk_Node_t *, arrayOfVertex, node); 02444 } 02445 02446 /* computes fanin and fanout table for each group */ 02447 for (i = 0; i < nGroups; i++) { 02448 arrayOfVertex = array_fetch(array_t *, arrayOfGroupVertex, i); 02449 arrayOfSupport = Ntk_NodeComputeCombinationalSupport(partSubInfo->network, 02450 arrayOfVertex, FALSE); 02451 arrayForEachItem(Ntk_Node_t *, arrayOfSupport, j, node) { 02452 if (!Ntk_NodeTestIsLatch(node)) 02453 continue; 02454 name = Ntk_NodeReadName(Ntk_LatchReadDataInput(node)); 02455 if (st_lookup(groupIndexTable, name, &index)) { 02456 if (index == i) 02457 continue; 02458 st_insert(faninIndexTable[i], (char *)index, NIL(char)); 02459 st_insert(fanoutIndexTable[index], (char *)(long)i, NIL(char)); 02460 } 02461 } 02462 array_free(arrayOfSupport); 02463 } 02464 02465 /* makes fanin and fanout array for each subsystem */ 02466 for (i = 0; i < nGroups; i++) { 02467 sub = array_fetch(Part_Subsystem_t *, result, i); 02468 st_foreach_item(faninIndexTable[i], stGen, &index, NULL) { 02469 array_insert_last(int, sub->subsystemFanIn, (int) index); 02470 } 02471 st_free_table(faninIndexTable[i]); 02472 array_sort(sub->subsystemFanIn, numCompare); 02473 st_foreach_item(fanoutIndexTable[i], stGen, &index, NULL) { 02474 array_insert_last(int, sub->subsystemFanOut, (int) index); 02475 } 02476 st_free_table(fanoutIndexTable[i]); 02477 array_sort(sub->subsystemFanOut, numCompare); 02478 } 02479 02480 FREE(faninIndexTable); 02481 FREE(fanoutIndexTable); 02482 array_free(arrayOfLatchDataInputNames); 02483 st_free_table(groupIndexTable); 02484 PartArrayOfArrayFree(arrayOfGroupVertex); 02485 return result; 02486 } 02487 02498 static array_t * 02499 PartBreakingBigConnectedComponent( 02500 array_t *arrayOfCC, 02501 array_t *ccCheck, 02502 array_t *arrayOfSeed, 02503 float *arrayOfAffinity, 02504 Part_SubsystemInfo_t *partSubInfo, 02505 st_table *ptrToIndex) 02506 { 02507 array_t *result; /* array of groups with the proper size */ 02508 array_t *resultRow; /* a group with the proper size */ 02509 array_t *arrayTemp; 02510 array_t *seedFull; /* array of seeds */ 02511 int i, count; 02512 int totalCount; /* how many vertixes are already computed */ 02513 int indexOfSeed; /* index of the seed which is closest from the vertex */ 02514 Ntk_Node_t *seed, *variable, *pick; 02515 02516 result = array_alloc(array_t *, array_n(arrayOfSeed)); 02517 02518 for (i = 0; i < array_n(arrayOfSeed); i++) { 02519 arrayTemp = array_alloc(Ntk_Node_t *, 0); 02520 seed = array_fetch(Ntk_Node_t *, arrayOfSeed, i); 02521 array_insert_last(Ntk_Node_t *, arrayTemp, seed); 02522 array_insert(array_t *, result, i, arrayTemp); 02523 } 02524 02525 switch (partSubInfo->partBM) { 02526 /* 02527 * Breaking Static Round Robin Seed Choice 02528 * Fixed order of seeds and each seed find the closest vertex 02529 */ 02530 case Part_BSRR_s: 02531 totalCount = array_n(arrayOfSeed); 02532 arrayForEachItem(Ntk_Node_t *, arrayOfSeed, i, seed) { 02533 count = 1; 02534 resultRow = array_fetch(array_t *, result, i); 02535 while ((count < partSubInfo->bound) && 02536 (totalCount < array_n(arrayOfCC))) { 02537 pick = PartSelectCloseNode(seed, arrayOfCC, ccCheck, 02538 arrayOfAffinity, ptrToIndex); 02539 array_insert_last(Ntk_Node_t *, resultRow, pick); 02540 count++; 02541 totalCount++; 02542 seed = pick; 02543 } 02544 } 02545 break; 02546 /* 02547 * Breaking Fixed Order State Variable Choice 02548 * Fixed order of vertecies and each vertex find the closest seed 02549 */ 02550 case Part_BFix_v: 02551 /* 02552 * Fixed order of nodes and each node find the closest seed 02553 */ 02554 seedFull = array_alloc(int, 0); 02555 for (i = 0; i < array_n(arrayOfSeed); i++) { 02556 array_insert_last(int, seedFull, 1); 02557 02558 } 02559 arrayForEachItem(Ntk_Node_t *, arrayOfCC, i, variable) { 02560 if (array_fetch(int, ccCheck, i) != 1) { 02561 indexOfSeed = PartSelectCloseSeedIndex(variable, arrayOfSeed, 02562 arrayOfAffinity, ptrToIndex, seedFull, partSubInfo->bound); 02563 resultRow = array_fetch(array_t *, result, indexOfSeed); 02564 array_insert_last(Ntk_Node_t *, resultRow, variable); 02565 array_insert(int, ccCheck, i, 1); 02566 } 02567 } 02568 array_free(seedFull); 02569 break; 02570 default: 02571 break; 02572 } 02573 return result; 02574 } 02575 02576 02588 static array_t * 02589 PartAggregating( 02590 array_t *arrayOfSmall, 02591 float *arrayOfAffinity, 02592 Part_SubsystemInfo_t *partSubInfo, 02593 st_table *ptrToIndex) 02594 { 02595 float *arrayOfGroupAff; 02596 array_t *result; 02597 array_t *arraySeed; 02598 array_t *arraySeedIndex; 02599 array_t *arrayTemp; 02600 array_t *arrayRow; 02601 array_t *cc; 02602 array_t *ccCheck; 02603 array_t *seed; 02604 int i, j; 02605 int count; /* total number of vertices in all small connected components */ 02606 int pick, keepInd; 02607 int seedLast, seedNew, seedIndex; 02608 int numberOfSeed; 02609 boolean isDone; 02610 array_t *keep = array_alloc(int, 0); 02611 02612 count = 0; 02613 02614 arrayForEachItem(array_t *, arrayOfSmall, i, cc) { 02615 count += array_n(cc); 02616 } 02617 02618 numberOfSeed = (int) ceil((double)count/(double)partSubInfo->bound); 02619 02620 arrayOfGroupAff = PartGetGroupMatrixSym(arrayOfSmall, arrayOfAffinity, 02621 ptrToIndex); 02622 02623 if (partSubInfo->verbosity >= 2) { 02624 fprintf(vis_stdout, "\nGrouping: Group affinity of initial "); 02625 fprintf(vis_stdout, "connected component\n"); 02626 fprintf(vis_stdout, "------------------------------------"); 02627 fprintf(vis_stdout, "-------------------\n"); 02628 PartPrintArrayArray(arrayOfGroupAff, array_n(arrayOfSmall), 0); 02629 } 02630 02631 ccCheck = array_alloc(int, array_n(arrayOfSmall)); 02632 for (i = 0; i < array_n(arrayOfSmall); i++) { 02633 array_insert(int, ccCheck, i, 0); 02634 } 02635 02636 /* 02637 * The first seed is the cc which has minmum support and the next 02638 * is the farthest cc 02639 */ 02640 seedLast = PartSelectCCIndexOfMinSupport(arrayOfSmall, 02641 ccCheck, partSubInfo); 02642 02643 result = array_alloc(array_t *, numberOfSeed); 02644 arraySeed = array_alloc(array_t *, numberOfSeed); 02645 arraySeedIndex = array_alloc(int, numberOfSeed); 02646 02647 for (i = 0; i < numberOfSeed; i++) { 02648 seed = array_fetch(array_t *, arrayOfSmall, seedLast); 02649 array_insert(array_t *, arraySeed, i, seed); 02650 array_insert(int, arraySeedIndex, i, seedLast); 02651 array_insert(array_t *, result, i, seed); 02652 if (i<numberOfSeed-1) { 02653 seedNew = PartSelectFarCCIndex(seedLast, arrayOfSmall, arrayOfGroupAff, 02654 partSubInfo, ccCheck); 02655 seedLast = seedNew; 02656 } 02657 } 02658 02659 /* 02660 * Static Round Robin Cluster Seed: Fixed order of seed and each seed 02661 * choose the closest connected component 02662 */ 02663 isDone = FALSE; 02664 count = array_n(arraySeed); 02665 while ((!isDone) && count < array_n(arrayOfSmall)) { 02666 isDone = TRUE; 02667 arrayForEachItem(int, arraySeedIndex, i, seedIndex) { 02668 arrayRow = array_fetch(array_t *, result, i); 02669 pick = PartSelectCloseCCIndex(seedIndex, arrayOfSmall, 02670 arrayOfGroupAff, ccCheck); 02671 count++; 02672 /* check if not all cc is assigned */ 02673 if (pick != -1) { 02674 arrayTemp = array_fetch(array_t *, arrayOfSmall, pick); 02675 if (array_n(array_fetch(array_t *, arrayOfSmall, seedIndex)) + 02676 array_n(arrayTemp) <= partSubInfo->bound) { 02677 array_append(arrayRow, arrayTemp); 02678 array_free(arrayTemp); 02679 isDone = FALSE; 02680 } else { 02681 /* 02682 * If pick cc is too big to be appended to seed, find new cc 02683 */ 02684 array_insert_last(int, keep, pick); 02685 pick = PartSelectCloseCCIndex(seedIndex, arrayOfSmall, 02686 arrayOfGroupAff, ccCheck); 02687 while (pick != -1) { 02688 arrayTemp = array_fetch(array_t *, arrayOfSmall, pick); 02689 if (array_n(array_fetch(array_t *, arrayOfSmall, seedIndex)) + 02690 array_n(arrayTemp) <= partSubInfo->bound) { 02691 array_append(arrayRow, arrayTemp); 02692 array_free(arrayTemp); 02693 isDone = FALSE; 02694 break; 02695 } else { 02696 array_insert_last(int, keep, pick); 02697 pick = PartSelectCloseCCIndex(seedIndex, arrayOfSmall, 02698 arrayOfGroupAff, ccCheck); 02699 } 02700 } /* end while */ 02701 if (pick == -1) { 02702 count--; 02703 } 02704 arrayForEachItem(int, keep, j, keepInd) { 02705 array_insert(int, ccCheck, keepInd, 0); 02706 } 02707 array_free(keep); 02708 keep = array_alloc(int, 0); 02709 } /* end if */ 02710 } else { 02711 count--; 02712 }/* end if */ 02713 }/* end arrayForEachItem */ 02714 /* 02715 * If all seeds fail to find suitable cc and not all cc is assigned, 02716 * get a new seed. 02717 */ 02718 if (count < array_n(arrayOfSmall) && isDone) { 02719 seedIndex = PartSelectCCIndexOfMinSupport(arrayOfSmall, 02720 ccCheck, partSubInfo); 02721 count++; 02722 seed = array_fetch(array_t *, arrayOfSmall, seedIndex); 02723 array_insert_last(array_t *, arraySeed, seed); 02724 array_insert_last(int, arraySeedIndex, seedIndex); 02725 array_insert_last(array_t *, result, seed); 02726 isDone = FALSE; 02727 } 02728 } 02729 array_free(arraySeed); 02730 array_free(arraySeedIndex); 02731 array_free(keep); 02732 array_free(ccCheck); 02733 FREE(arrayOfGroupAff); 02734 return result; 02735 } 02736 02744 static Ntk_Node_t * 02745 PartSelectCloseNode( 02746 Ntk_Node_t *seed, 02747 array_t *arrayOfCC, 02748 array_t *ccCheck, 02749 float *arrayOfAffinity, 02750 st_table *ptrToIndex) 02751 { 02752 int i; 02753 float affinity; 02754 float big; /* The bigest value of affinity of vertecies*/ 02755 int bigInd; /* the index of node with the biggest affinity */ 02756 int col; 02757 int row; 02758 Ntk_Node_t *node, *pick; 02759 02760 big = -1.0; 02761 bigInd = 0; /* to avoid warning */ 02762 pick = NIL(Ntk_Node_t); 02763 02764 st_lookup_int(ptrToIndex, (char *)seed, &row); 02765 02766 arrayForEachItem(Ntk_Node_t *, arrayOfCC, i, node) { 02767 if (array_fetch(int, ccCheck, i) != 1) { 02768 st_lookup_int(ptrToIndex, (char *)node, &col); 02769 affinity = PartGetElementFromSymMatrix(arrayOfAffinity, row, col); 02770 if (affinity > big) { 02771 big = affinity; 02772 pick = node; 02773 bigInd = i; 02774 } 02775 } 02776 } 02777 array_insert(int, ccCheck, bigInd, 1); 02778 return pick; 02779 } 02780 02788 static int 02789 PartSelectCloseSeedIndex( 02790 Ntk_Node_t *variable, 02791 array_t *arrayOfSeed, 02792 float *arrayOfAffinity, 02793 st_table *ptrToIndex, 02794 array_t *seedFull, 02795 int bound) 02796 { 02797 float affinity; 02798 int i; 02799 float big; 02800 int pick, row, col; 02801 Ntk_Node_t *node; 02802 02803 big = -1.0; 02804 pick = -1; 02805 02806 st_lookup_int(ptrToIndex, (char *)variable, &row); 02807 02808 arrayForEachItem(Ntk_Node_t *, arrayOfSeed, i, node) { 02809 st_lookup_int(ptrToIndex, (char *)node, &col); 02810 affinity = PartGetElementFromSymMatrix(arrayOfAffinity, row, col); 02811 if (affinity > big && array_fetch(int, seedFull, i) < bound) { 02812 big = affinity; 02813 pick = i; 02814 } 02815 } 02816 array_insert(int, seedFull, pick, array_fetch(int, seedFull, pick) + 1); 02817 return pick; 02818 } 02819 02827 static Ntk_Node_t * 02828 PartSelectFarNode( 02829 Ntk_Node_t *seed, 02830 array_t *cc, 02831 array_t *ccCheck, 02832 float *arrayOfAffinity, 02833 st_table *ptrToIndex) 02834 { 02835 float affinity; 02836 int i; 02837 float small; /* the smallest affinity of vertecies */ 02838 int smallInd; /* index of vertex with the smallest affinity */ 02839 int col; 02840 int row; 02841 Ntk_Node_t *node, *pick; 02842 02843 small = (float)BIG_NUMBER; 02844 smallInd = 0; /* to avoid warning */ 02845 pick = NIL(Ntk_Node_t); 02846 02847 st_lookup_int(ptrToIndex, (char *)seed, &row); 02848 arrayForEachItem(Ntk_Node_t *, cc, i, node) { 02849 if (array_fetch(int, ccCheck, i) != 1) { 02850 st_lookup_int(ptrToIndex, (char *)node, &col); 02851 affinity = PartGetElementFromSymMatrix(arrayOfAffinity, row, col); 02852 if (affinity < small) { 02853 small = affinity; 02854 pick = node; 02855 smallInd = i; 02856 } 02857 } 02858 } 02859 array_insert(int, ccCheck, smallInd, 1); 02860 return pick; 02861 } 02862 02863 02876 static float * 02877 PartGetGroupMatrixRegular( 02878 array_t *arrayOfCluster, 02879 char *arrayOfGivenMatrix, 02880 st_table *ptrToIndex, 02881 int nVertices) 02882 { 02883 float *arrayOfGroupMatrix; /* final result */ 02884 array_t *arrayClusterRow; 02885 array_t *arrayClusterCol; 02886 float subSum; 02887 int row, col, i, j, k, l; 02888 Ntk_Node_t *nodeRow, *nodeCol; 02889 int index, size; 02890 02891 size = array_n(arrayOfCluster); 02892 arrayOfGroupMatrix = ALLOC(float, size * size); 02893 02894 arrayForEachItem(array_t *, arrayOfCluster, i, arrayClusterRow) { 02895 arrayForEachItem(array_t *, arrayOfCluster, j, arrayClusterCol) { 02896 if (i != j) { 02897 subSum = 0.0; 02898 arrayForEachItem(Ntk_Node_t *, arrayClusterRow, k, nodeRow) { 02899 st_lookup_int(ptrToIndex, (char *)nodeRow, &row); 02900 arrayForEachItem(Ntk_Node_t *, arrayClusterCol, l, nodeCol) { 02901 st_lookup_int(ptrToIndex, (char *)nodeCol, &col); 02902 index = row * nVertices + col; 02903 if (arrayOfGivenMatrix[index] == 1) 02904 subSum += 1.0; 02905 } 02906 } 02907 index = i * size + j; 02908 arrayOfGroupMatrix[index] = subSum / 02909 (float)(array_n(arrayClusterRow) * array_n(arrayClusterCol)); 02910 } else { 02911 index = i * size + j; 02912 arrayOfGroupMatrix[index] = 0.0; 02913 } 02914 } 02915 } 02916 return arrayOfGroupMatrix; 02917 } 02918 02930 static float * 02931 PartGetGroupMatrixSym( 02932 array_t *arrayOfCluster, 02933 float *arrayOfGivenMatrix, 02934 st_table *ptrToIndex) 02935 { 02936 float *arrayOfGroupMatrix; /* final result */ 02937 array_t *arrayClusterRow; 02938 array_t *arrayClusterCol; 02939 float subSum; 02940 int row, col, i, j, k, l; 02941 Ntk_Node_t *nodeRow, *nodeCol; 02942 int index, size; 02943 02944 size = array_n(arrayOfCluster); 02945 arrayOfGroupMatrix = ALLOC(float, size * (size - 1) / 2); 02946 02947 for (i = 0; i < size; i++) { 02948 arrayClusterRow = array_fetch(array_t *, arrayOfCluster, i); 02949 for (j = 0; j < i; j++) { 02950 arrayClusterCol = array_fetch(array_t *, arrayOfCluster, j); 02951 if (i == j) { 02952 index = i * (i - 1) / 2 + j; 02953 arrayOfGroupMatrix[index] = 0.0; 02954 } else { 02955 subSum = 0.0; 02956 arrayForEachItem(Ntk_Node_t *, arrayClusterRow, k, nodeRow) { 02957 st_lookup_int(ptrToIndex, (char *)nodeRow, &row); 02958 arrayForEachItem(Ntk_Node_t *, arrayClusterCol, l, nodeCol) { 02959 st_lookup_int(ptrToIndex, (char *)nodeCol, &col); 02960 subSum += PartGetElementFromSymMatrix(arrayOfGivenMatrix, row, col); 02961 } 02962 } 02963 index = i * (i - 1) / 2 + j; 02964 arrayOfGroupMatrix[index] = subSum / 02965 (float)((array_n(arrayClusterRow)) * array_n(arrayClusterCol)); 02966 } 02967 } 02968 } 02969 return arrayOfGroupMatrix; 02970 } 02971 02979 static int 02980 PartSelectCCIndexOfMinSupport( 02981 array_t *arrayOfSmall, 02982 array_t *ccCheck, 02983 Part_SubsystemInfo_t *partSubInfo) 02984 { 02985 array_t *cc; 02986 array_t *support; 02987 int i, count, minCount, minIndex; 02988 02989 minCount = BIG_NUMBER; 02990 minIndex = -1; 02991 02992 for (i = 0; i < array_n(ccCheck); i++) { 02993 if (array_fetch(int, ccCheck, i) != 1) { 02994 cc = array_fetch(array_t *, arrayOfSmall, i); 02995 support = Ntk_NodeComputeCombinationalSupport( 02996 partSubInfo->network, cc, TRUE); 02997 count = array_n(support); 02998 array_free(support); 02999 if (count < minCount) { 03000 minIndex = i; 03001 minCount = count; 03002 } 03003 } 03004 } 03005 if (minIndex != -1) { 03006 array_insert(int, ccCheck, minIndex, 1); 03007 } 03008 return minIndex; 03009 } 03010 03019 static Ntk_Node_t * 03020 PartSelectNodeOfMinSupport( 03021 array_t *cc, 03022 array_t *ccCheck, 03023 Part_SubsystemInfo_t *partSubInfo) 03024 { 03025 array_t *support; 03026 array_t *nodeArray; 03027 int i, minInd, count, min; 03028 Ntk_Node_t *node; 03029 Ntk_Node_t *minNode = NIL(Ntk_Node_t); 03030 03031 if (array_n(cc) == 0) { 03032 return NIL(Ntk_Node_t); 03033 } 03034 03035 min = BIG_NUMBER; 03036 minInd = 0; /* to avoid warning */ 03037 arrayForEachItem(Ntk_Node_t *, cc, i, node) { 03038 if (array_fetch(int, ccCheck, i) != 1) { 03039 nodeArray = array_alloc(Ntk_Node_t *, 1); 03040 array_insert(Ntk_Node_t *, nodeArray, 0, node); 03041 support = Ntk_NodeComputeCombinationalSupport( 03042 partSubInfo->network, nodeArray, TRUE); 03043 count = array_n(support); 03044 if (count < min) { 03045 minNode = node; 03046 min = count; 03047 minInd = i; 03048 } 03049 array_free(support); 03050 array_free(nodeArray); 03051 } 03052 } 03053 array_insert(int, ccCheck, minInd, 1); 03054 return minNode; 03055 } 03056 03065 static int 03066 PartSelectFarCCIndex( 03067 int seedIndex, 03068 array_t *arrayOfSmall, 03069 float *arrayOfGroupAff, 03070 Part_SubsystemInfo_t *partSubInfo, 03071 array_t *ccCheck) 03072 { 03073 array_t *col; 03074 int i; 03075 float groupAff; 03076 float min; 03077 int minIndex; 03078 03079 min = (float)BIG_NUMBER; 03080 minIndex = -1; 03081 03082 arrayForEachItem(array_t *, arrayOfSmall, i, col) { 03083 if (array_fetch(int, ccCheck, i) != 1) { 03084 groupAff = PartGetElementFromSymMatrix(arrayOfGroupAff, seedIndex, i); 03085 if (groupAff < min) { 03086 minIndex = i; 03087 min = groupAff; 03088 } 03089 } 03090 } 03091 if (minIndex != -1) { 03092 array_insert(int, ccCheck, minIndex, 1); 03093 } 03094 return minIndex; 03095 } 03096 03105 static int 03106 PartSelectCloseCCIndex( 03107 int seedIndex, 03108 array_t *arrayOfSmall, 03109 float *arrayOfGroupAff, 03110 array_t *ccCheck) 03111 { 03112 int i; 03113 float groupAff; 03114 float max; 03115 int maxIndex; 03116 03117 max = -1.0; 03118 maxIndex = -1; 03119 03120 for (i = 0; i < array_n(ccCheck); i++) { 03121 if (array_fetch(int, ccCheck, i) != 1) { 03122 groupAff = PartGetElementFromSymMatrix(arrayOfGroupAff, seedIndex, i); 03123 if (groupAff > max) { 03124 maxIndex = i; 03125 max = groupAff; 03126 } 03127 } 03128 } 03129 if (maxIndex != -1) { 03130 array_insert(int, ccCheck, maxIndex, 1); 03131 } 03132 return maxIndex; 03133 } 03134 03135 03144 static Part_Subsystem_t* 03145 PartCreateSingleSubSystem( 03146 array_t *arrayOfNodes, 03147 Ntk_Network_t *network) 03148 { 03149 int i, j; 03150 char *name; 03151 Ntk_Node_t *node; 03152 st_table *vertexNameTable; 03153 array_t *arrayOfLatchNames; 03154 Part_Subsystem_t *sub; 03155 03156 if (array_n(arrayOfNodes) == 0 || arrayOfNodes == NIL(array_t)) { 03157 return NIL(Part_Subsystem_t); 03158 } 03159 03160 vertexNameTable = st_init_table(strcmp, st_strhash); 03161 arrayForEachItem(Ntk_Node_t *, arrayOfNodes, i, node) { 03162 arrayOfLatchNames = PartReadLatchNameFromLatchInput(network, node); 03163 arrayForEachItem(char *, arrayOfLatchNames, j, name) { 03164 st_insert(vertexNameTable, (char *)name, (char *)NULL); 03165 } 03166 array_free(arrayOfLatchNames); 03167 } 03168 sub = ALLOC(Part_Subsystem_t, 1); 03169 sub->vertexNameTable = vertexNameTable; 03170 sub->subsystemFanIn = NIL(array_t); 03171 sub->subsystemFanOut = NIL(array_t); 03172 03173 return sub; 03174 } 03175 03184 static array_t * 03185 PartReadLatchNameFromLatchInput( 03186 Ntk_Network_t *network, 03187 Ntk_Node_t *latchInput) 03188 { 03189 lsGen gen; 03190 Ntk_Node_t *latch, *temp1; 03191 char *latchName = NIL(char); 03192 array_t *arrayOfLatchNames; 03193 03194 arrayOfLatchNames = array_alloc(char *, 0); 03195 Ntk_NetworkForEachLatch(network, gen, latch) { 03196 temp1 = Ntk_LatchReadDataInput(latch); 03197 if (temp1 == latchInput) { 03198 latchName = Ntk_NodeReadName(latch); 03199 array_insert_last(char *, arrayOfLatchNames, latchName); 03200 } 03201 } /* end of Ntk_NetworkForEachLatch */ 03202 03203 return arrayOfLatchNames; 03204 } 03205 03213 static void 03214 PartArrayOfArrayFree( 03215 array_t *arrayOfMatrix) 03216 { 03217 array_t *arrayRow; 03218 int i; 03219 03220 arrayForEachItem(array_t *, arrayOfMatrix, i, arrayRow) { 03221 array_free(arrayRow); 03222 } 03223 array_free(arrayOfMatrix); 03224 } 03225 03233 static float 03234 PartGetElementFromSymMatrix( 03235 float *matrix, 03236 int i, 03237 int j) 03238 { 03239 int index; 03240 03241 if (i == j) 03242 return(0.0); 03243 if (i < j) { 03244 int tmp; 03245 03246 tmp = i; 03247 i = j; 03248 j = tmp; 03249 } 03250 index = i * (i - 1) / 2 + j; 03251 return(matrix[index]); 03252 } 03253 03264 static void 03265 PartPrintArrayArray( 03266 void *arrayArray, 03267 int nVertices, 03268 int type) 03269 { 03270 int i, j; 03271 float num; 03272 int index; 03273 03274 if (type == 0) { /* numerical data * symetric matrix */ 03275 for (i = 0; i < nVertices; i++) { 03276 for (j = 0; j < nVertices; j++) { 03277 num = PartGetElementFromSymMatrix((float *)arrayArray, i, j); 03278 fprintf(vis_stdout, "%4.3f ", num); 03279 } 03280 fprintf(vis_stdout, "\n"); 03281 } 03282 } else if (type == 1) { /* char data & regular */ 03283 for (i = 0; i < nVertices; i++) { 03284 for (j = 0; j < nVertices; j++) { 03285 index = i * nVertices + j; 03286 if (((char *)arrayArray)[index] == 1) { 03287 fprintf(vis_stdout, "1 "); 03288 } else { 03289 fprintf(vis_stdout, "0 "); 03290 } 03291 } 03292 fprintf(vis_stdout, "\n"); 03293 } 03294 } 03295 fprintf(vis_stdout, "\n"); 03296 } 03297 03307 static int 03308 strCompare( 03309 const void *name1, 03310 const void *name2) 03311 { 03312 return(strcmp(*(char **)name1, *(char **)name2)); 03313 } /* end of strCompare */ 03314 03324 static int 03325 numCompare( 03326 const void *num1, 03327 const void *num2) 03328 { 03329 return(*(int *)num1 > *(int *)num2); 03330 } /* end of strCompare */