VIS
|
00001 00025 #include "grabInt.h" 00026 00027 00028 /*---------------------------------------------------------------------------*/ 00029 /* Constant declarations */ 00030 /*---------------------------------------------------------------------------*/ 00031 00032 /*---------------------------------------------------------------------------*/ 00033 /* Structure declarations */ 00034 /*---------------------------------------------------------------------------*/ 00035 00036 /*---------------------------------------------------------------------------*/ 00037 /* Type declarations */ 00038 /*---------------------------------------------------------------------------*/ 00039 00040 /*---------------------------------------------------------------------------*/ 00041 /* Variable declarations */ 00042 /*---------------------------------------------------------------------------*/ 00043 static st_table *Sel0ScoreTable; 00044 static st_table *SelScoreTable; 00045 static st_table *Sel2ScoreTable; 00046 static st_table *Sel3ScoreTable; 00047 00048 /*---------------------------------------------------------------------------*/ 00049 /* Macro declarations */ 00050 /*---------------------------------------------------------------------------*/ 00051 00054 /*---------------------------------------------------------------------------*/ 00055 /* Static function prototypes */ 00056 /*---------------------------------------------------------------------------*/ 00057 00058 static array_t * GrabFsmComputeExRings(Fsm_Fsm_t *absFsm, st_table *absVarTable, st_table *absBnvTable, array_t *oldRings, int cexType, int verbose); 00059 static int GrabCompareScores(const void *ptr1, const void *ptr2); 00060 static void GrabMddAppendSupports(mdd_manager *mddManager, mdd_t *mdd1, st_table *supportsTable); 00061 static array_t * ComputeDependence(Ntk_Network_t *network, st_table *vertexTable, array_t *leftVars); 00062 00065 /*---------------------------------------------------------------------------*/ 00066 /* Definition of internal functions */ 00067 /*---------------------------------------------------------------------------*/ 00068 00095 void 00096 GrabRefineAbstractionByGrab( 00097 Fsm_Fsm_t *absFsm, 00098 array_t *SORs, 00099 st_table *absVarTable, 00100 st_table *BnvTable, 00101 array_t *addedVars, 00102 array_t *addedBnvs, 00103 int refine_direction, 00104 st_table *nodeToFaninNumberTable, 00105 int verbose) 00106 { 00107 Ntk_Network_t *network = Fsm_FsmReadNetwork(absFsm); 00108 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00109 array_t *ExRings; 00110 array_t *visibleVarMddIds, *invisibleVarMddIds, *allPSVars; 00111 array_t *tempArray; 00112 mdd_t *mdd1, *mdd2; 00113 char *nodeName; 00114 Ntk_Node_t *node; 00115 double *Scores, *SelScores, *Sel0Scores, *Sel2Scores, *Sel3Scores; 00116 double epd, baseNum; 00117 int i, j, nRow, nCol; 00118 long mddId, value, value0; 00119 boolean isSupport, isLatch; 00120 int max_num_of_added_vars; 00121 00122 /* compute the preimages (with invisible vars in their support) 00123 */ 00124 ExRings = GrabFsmComputeExRings(absFsm, absVarTable, BnvTable, SORs, 00125 GRAB_CEX_SOR, verbose); 00126 assert(ExRings != NIL(array_t)); 00127 00128 visibleVarMddIds = GrabGetVisibleVarMddIds(absFsm,absVarTable); 00129 invisibleVarMddIds = GrabGetInvisibleVarMddIds(absFsm,absVarTable,BnvTable); 00130 allPSVars = array_dup(visibleVarMddIds); 00131 array_append(allPSVars, invisibleVarMddIds); 00132 assert(array_n(invisibleVarMddIds) > 0 ); 00133 00134 /* Compute the normalized number of "winning positions" for each individual 00135 * invisibleVar, and store them in 'Scores'! 00136 */ 00137 nRow = array_n(ExRings); 00138 nCol = array_n(invisibleVarMddIds); 00139 Scores = ALLOC(double, nRow*nCol); 00140 memset(Scores, 0, sizeof(double)*nRow*nCol); 00141 00142 00143 /********************************************************* 00144 * for each set of abstract states in (mdd1, Ring[j+1] ) 00145 *********************************************************/ 00146 arrayForEachItem(mdd_t *, ExRings, j, mdd1) { 00147 st_table *localSupportsTable = st_init_table(st_numcmp, st_numhash); 00148 GrabMddAppendSupports(mddManager, mdd1, localSupportsTable); 00149 00150 if (mdd_get_number_of_bdd_vars(mddManager, allPSVars) <= 1023 ) 00151 baseNum = mdd_count_onset(mddManager, mdd1, allPSVars); 00152 else { 00153 mdd_t *stateMdd = mdd_smooth(mddManager, mdd1, invisibleVarMddIds); 00154 baseNum = mdd_count_onset(mddManager, stateMdd, visibleVarMddIds); 00155 mdd_free(stateMdd); 00156 } 00157 00158 /*********************************************************** 00159 * compute the impact of refining with each invisible var 00160 ***********************************************************/ 00161 arrayForEachItem(int, invisibleVarMddIds, i, mddId) { 00162 /* for debugging purpose. won't affect the algorithm */ 00163 Scores[j*nCol+i] = -9E-99; 00164 00165 /* give credit simply for the appearance */ 00166 isSupport = st_is_member(localSupportsTable, (char *)mddId); 00167 if (!isSupport || baseNum==0.0) continue; 00168 Scores[j*nCol+i] += 0.001; 00169 00170 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00171 isLatch = (Ntk_NodeTestIsLatch(node)); 00172 if (refine_direction==0 && isLatch) continue; 00173 00174 { 00175 array_t *universalQVars = array_alloc(int, 0); 00176 /* MX */ 00177 array_insert_last(int, universalQVars, mddId); 00178 mdd2 = mdd_consensus(mddManager, mdd1, universalQVars); 00179 array_free(universalQVars); 00180 00181 if (mdd_get_number_of_bdd_vars(mddManager, allPSVars) <= 1023) 00182 epd = mdd_count_onset(mddManager, mdd2, allPSVars); 00183 else { 00184 mdd_t *stateMdd = mdd_smooth(mddManager, mdd2, invisibleVarMddIds); 00185 epd = mdd_count_onset(mddManager, stateMdd, visibleVarMddIds); 00186 mdd_free(stateMdd); 00187 } 00188 mdd_free(mdd2); 00189 00190 Scores[j*nCol+i] = (baseNum - epd)/baseNum; 00191 } 00192 00193 if (j == 0) 00194 Scores[j*nCol+i] /= 10.0; 00195 00196 } 00197 st_free_table(localSupportsTable); 00198 } 00199 00200 /* For each column, sum up the score over all the rows. The 00201 * selection of refinement variables will be based mainly on these 00202 * scores. 00203 */ 00204 SelScores = ALLOC(double, nCol); 00205 memset(SelScores, 0, sizeof(double)*nCol); 00206 for (i=0; i<nRow; i++) { 00207 for (j=0; j<nCol; j++) { 00208 SelScores[j] += Scores[i*nCol+j]; 00209 } 00210 } 00211 00212 /* Other selection criteria: 00213 * (0) when in the BOOLEAN refinement direction, only add bnvs 00214 * (2) how many absLatches depending on the invisible var? 00215 * (3) how much will the invisible var cost? 00216 */ 00217 Sel0Scores = ALLOC(double, nCol); 00218 Sel2Scores = ALLOC(double, nCol); 00219 Sel3Scores = ALLOC(double, nCol); 00220 tempArray = ComputeDependence(network, absVarTable, invisibleVarMddIds); 00221 value0 = lsLength(Ntk_NetworkReadNodes(network)); 00222 for (j=0; j<nCol; j++) { 00223 mddId = array_fetch(int, invisibleVarMddIds, j); 00224 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00225 isLatch = (Ntk_NodeTestIsLatch(node)); 00226 /* when refinement is in the BOOLEAN direction, only add bnvs 00227 * otherwise, add either latches or bnvs 00228 */ 00229 if (refine_direction==0 && !isLatch) 00230 Sel0Scores[j] = 1.0; 00231 else 00232 Sel0Scores[j] = 0.0; 00233 /* dependence */ 00234 value = array_fetch(int, tempArray, j); 00235 Sel2Scores[j] = ((double)value)/st_count(absVarTable); 00236 /* cost */ 00237 value = GrabNodeComputeFaninNumberTableItem(network, 00238 nodeToFaninNumberTable, 00239 node); 00240 Sel3Scores[j] = 1.0 - ((double)value)/value0; 00241 } 00242 array_free(tempArray); 00243 00244 /* Print out the 'Scores' matrix when requested 00245 */ 00246 if (verbose >= 5) { 00247 /* the entire score table */ 00248 fprintf(vis_stdout, "\n Scores[%d][%d] = \n", nRow, nCol); 00249 arrayForEachItem(int, invisibleVarMddIds, i, mddId) { 00250 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00251 fprintf(vis_stdout, "%s ", (Ntk_NodeTestIsLatch(node)?" L ":" ")); 00252 } 00253 fprintf(vis_stdout, "\n"); 00254 arrayForEachItem(int, invisibleVarMddIds, i, mddId) { 00255 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00256 fprintf(vis_stdout, "%5d ", i); 00257 } 00258 fprintf(vis_stdout, "\n"); 00259 for (i=0; i<nRow; i++) { 00260 for (j=0; j<nCol; j++) { 00261 fprintf(vis_stdout, "%+1.2f ", Scores[i*nCol+j]); 00262 } 00263 fprintf(vis_stdout, "\n"); 00264 } 00265 /* best score in each row */ 00266 for (i=0; i<nRow; i++) { 00267 int best_local = 0; 00268 for (j=0; j<nCol; j++) { 00269 if (Scores[i*nCol+best_local] < Scores[i*nCol+j]) 00270 best_local = j; 00271 } 00272 fprintf(vis_stdout, "best_local: Scores[%d][%d] = %5g\n", 00273 i, best_local, Scores[i*nCol+best_local]); 00274 } 00275 } 00276 00277 /* Sorting the invisibleVarMddIds according to the Selection Scores 00278 */ 00279 Sel0ScoreTable = st_init_table(st_numcmp, st_numhash); 00280 SelScoreTable = st_init_table(st_numcmp, st_numhash); 00281 Sel2ScoreTable = st_init_table(st_numcmp, st_numhash); 00282 Sel3ScoreTable = st_init_table(st_numcmp, st_numhash); 00283 arrayForEachItem(int, invisibleVarMddIds, j, mddId) { 00284 st_insert(Sel0ScoreTable, (char *)mddId, (char *)(Sel0Scores+j)); 00285 st_insert(SelScoreTable, (char *)mddId, (char *)(SelScores+j)); 00286 st_insert(Sel2ScoreTable, (char *)mddId, (char *)(Sel2Scores+j)); 00287 st_insert(Sel3ScoreTable, (char *)mddId, (char *)(Sel3Scores+j)); 00288 } 00289 00290 array_sort(invisibleVarMddIds, GrabCompareScores); 00291 00292 if (verbose >= 4) { 00293 fprintf(vis_stdout, " \t Sel0 Sel Sel2 Sel3\n"); 00294 arrayForEachItem(int, invisibleVarMddIds, j, mddId) { 00295 double *addr; 00296 st_lookup(Sel0ScoreTable, (char *)mddId, &addr); 00297 i = (int)(addr-Sel0Scores); 00298 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00299 isLatch = (Ntk_NodeTestIsLatch(node)); 00300 fprintf(vis_stdout, 00301 "%s[%d]\t %+1.3f %+1.3f %+1.3f %+1.3f %s\n", 00302 (isLatch? "L":" "), 00303 i, 00304 Sel0Scores[i], SelScores[i], Sel2Scores[i], Sel3Scores[i], 00305 Ntk_NodeReadName(node) 00306 ); 00307 /* only output the top 20 variables */ 00308 if (j >= 19) break; 00309 } 00310 } 00311 00312 st_free_table(Sel0ScoreTable); 00313 st_free_table(SelScoreTable); 00314 st_free_table(Sel2ScoreTable); 00315 st_free_table(Sel3ScoreTable); 00316 00317 /* Now find the best (largest score) invisible Var */ 00318 { 00319 int num_absBnvs = BnvTable? st_count(BnvTable):0; 00320 00321 if ((st_count(absVarTable) + num_absBnvs) < 10) 00322 max_num_of_added_vars = 1; 00323 else 00324 max_num_of_added_vars = 2 + (st_count(absVarTable)+num_absBnvs)/30; 00325 } 00326 00327 arrayForEachItem(int, invisibleVarMddIds, j, mddId) { 00328 00329 if (j >= max_num_of_added_vars) break; 00330 00331 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00332 nodeName = Ntk_NodeReadName(node); 00333 if (Ntk_NodeTestIsLatch(node)) { 00334 assert(!st_is_member(absVarTable, node)); 00335 st_insert(absVarTable, node, (char *)(long)st_count(absVarTable)); 00336 array_insert_last(int, addedVars, mddId); 00337 CHKPRINT2( (verbose>=3), " add Latch %s\n", nodeName ); 00338 }else if (!Ntk_NodeTestIsLatch(node)) { 00339 assert(!st_is_member(BnvTable, node)); 00340 st_insert(BnvTable, node, (char *)0); 00341 array_insert_last(int, addedBnvs, mddId); 00342 CHKPRINT2( (verbose>=3), " add BNV %s\n", nodeName ); 00343 } 00344 } 00345 00346 /* Clean-ups */ 00347 array_free(invisibleVarMddIds); 00348 array_free(visibleVarMddIds); 00349 array_free(allPSVars); 00350 mdd_array_free(ExRings); 00351 FREE(Scores); 00352 FREE(Sel0Scores); 00353 FREE(SelScores); 00354 FREE(Sel2Scores); 00355 FREE(Sel3Scores); 00356 } 00357 00368 int 00369 GrabNodeComputeFaninNumberTableItem( 00370 Ntk_Network_t *network, 00371 st_table *nodeToFaninNumberTable, 00372 Ntk_Node_t *node) 00373 { 00374 int count; 00375 array_t *roots, *supports; 00376 00377 roots = array_alloc(Ntk_Node_t *, 0); 00378 if (!st_lookup_int(nodeToFaninNumberTable, node, &count)) { 00379 if (Ntk_NodeTestIsLatch(node)) 00380 array_insert(Ntk_Node_t *, roots, 0, Ntk_LatchReadDataInput(node)); 00381 else 00382 array_insert(Ntk_Node_t *, roots, 0, node); 00383 00384 supports = Ntk_NodeComputeTransitiveFaninNodes(network, roots, TRUE,FALSE); 00385 00386 count = array_n(supports); 00387 array_free(supports); 00388 st_insert(nodeToFaninNumberTable, node, (char *)(long)count); 00389 } 00390 array_free(roots); 00391 00392 return count; 00393 } 00394 00395 /*---------------------------------------------------------------------------*/ 00396 /* Definition of static functions */ 00397 /*---------------------------------------------------------------------------*/ 00398 00412 static array_t * 00413 GrabFsmComputeExRings( 00414 Fsm_Fsm_t *absFsm, 00415 st_table *absVarTable, 00416 st_table *absBnvTable, 00417 array_t *oldRings, 00418 int cexType, 00419 int verbose) 00420 { 00421 Img_ImageInfo_t *imageInfo; 00422 Ntk_Network_t *network = Fsm_FsmReadNetwork(absFsm); 00423 array_t *careStatesArray = array_alloc(mdd_t *, 0); 00424 array_t *allPsVars, *invisibleVarMddIds; 00425 array_t *onionRings, *synOnionRings; 00426 mdd_t *mdd1, *mdd2, *mdd3, *mdd4, *initStates; 00427 int i, j, mddId; 00428 Ntk_Node_t *node; 00429 00430 imageInfo = Fsm_FsmReadOrCreateImageInfo(absFsm, 1, 0); 00431 00432 /* Compute the initial states based on all the related latches 00433 * (i.e. visible latches and invisible ones that are in the 00434 * immediate support) 00435 */ 00436 allPsVars = GrabGetVisibleVarMddIds(absFsm, absVarTable); 00437 invisibleVarMddIds = GrabGetInvisibleVarMddIds(absFsm, absVarTable, 00438 absBnvTable); 00439 arrayForEachItem(int, invisibleVarMddIds, i, mddId) { 00440 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00441 if (Ntk_NodeTestIsLatch(node)) 00442 array_insert_last(int, allPsVars, mddId); 00443 } 00444 initStates = GrabComputeInitialStates(network, allPsVars); 00445 array_free(allPsVars); 00446 array_free(invisibleVarMddIds); 00447 00448 onionRings = oldRings; 00449 if (onionRings == NIL(array_t)) 00450 onionRings = Fsm_FsmReadReachabilityOnionRings(absFsm); 00451 assert(onionRings); 00452 00453 synOnionRings = array_alloc(mdd_t *, array_n(onionRings)); 00454 00455 for (j=array_n(onionRings)-2; j>=0; j--) { 00456 mdd1 = array_fetch(mdd_t *, onionRings, j+1); 00457 mdd2 = array_fetch(mdd_t *, onionRings, j); 00458 00459 array_insert(mdd_t *, careStatesArray, 0, mdd2); 00460 mdd3 = Img_ImageInfoComputeEXWithDomainVars(imageInfo, 00461 mdd1, 00462 mdd1, 00463 careStatesArray); 00464 mdd4 = mdd_and(mdd2, mdd3, 1, 1); 00465 mdd_free(mdd3); 00466 00467 array_insert(mdd_t *, synOnionRings, j+1, mdd4); 00468 00469 /* when the more accurate initial states is available, use it */ 00470 if (j == 0) { 00471 mdd1 = mdd_and(mdd4, initStates, 1, 1); 00472 if (mdd_is_tautology(mdd1, 0)) { 00473 mdd_free(mdd1); 00474 mdd1 = mdd_dup(mdd4); 00475 } 00476 array_insert(mdd_t *, synOnionRings, j, mdd1); 00477 } 00478 } 00479 00480 /* clean-up's */ 00481 mdd_free(initStates); 00482 array_free(careStatesArray); 00483 00484 return synOnionRings; 00485 } 00486 00502 static int 00503 GrabCompareScores( 00504 const void *ptr1, 00505 const void *ptr2) 00506 { 00507 int item1 = *((int *)ptr1); 00508 int item2 = *((int *)ptr2); 00509 double *first0, *first, *first2, *first3; 00510 double *second0, *second, *second2, *second3; 00511 double value0, value, value2, value3; 00512 00513 st_lookup(Sel0ScoreTable, (char *)(long)item1, &first0); 00514 st_lookup(SelScoreTable, (char *)(long)item1, &first); 00515 st_lookup(Sel2ScoreTable, (char *)(long)item1, &first2); 00516 st_lookup(Sel3ScoreTable, (char *)(long)item1, &first3); 00517 00518 st_lookup(Sel0ScoreTable, (char *)(long)item2, &second0); 00519 st_lookup(SelScoreTable, (char *)(long)item2, &second); 00520 st_lookup(Sel2ScoreTable, (char *)(long)item2, &second2); 00521 st_lookup(Sel3ScoreTable, (char *)(long)item2, &second3); 00522 00523 value0 = *second0 - *first0; 00524 value = *second - *first; 00525 value2 = *second2 - *first2; 00526 value3 = *second3 - *first3; 00527 00528 if (value0 > 0) return 1; 00529 if (value0 < 0) return -1; 00530 00531 if (value > 0) return 1; 00532 if (value < 0) return -1; 00533 00534 return 0; 00535 00536 /* Chao: The tie-breakers are not used for this release. We achieved 00537 * the best performance on the suite of testing cases at hand 00538 * without the tie-breakers. But the code is retained for the 00539 * purpose of future experiments. 00540 */ 00541 00542 if (value2 > 0) return 1; 00543 if (value2 < 0) return -1; 00544 00545 if (value3 > 0) return 1; 00546 if (value3 < 0) return -1; 00547 00548 return 0; 00549 } 00550 00551 00561 static void 00562 GrabMddAppendSupports( 00563 mdd_manager *mddManager, 00564 mdd_t *mdd1, 00565 st_table *supportsTable) 00566 { 00567 int mddId, k; 00568 array_t *supports = mdd_get_support(mddManager, mdd1); 00569 00570 arrayForEachItem(int, supports, k, mddId) { 00571 if (!st_is_member(supportsTable, (char *)(long)mddId)) 00572 st_insert(supportsTable, (char *)(long)mddId, (char *)0); 00573 } 00574 array_free(supports); 00575 } 00576 00577 00589 static array_t * 00590 ComputeDependence( 00591 Ntk_Network_t *network, 00592 st_table *vertexTable, 00593 array_t *leftVars) 00594 { 00595 array_t *roots, *supports; 00596 st_table *supportTable; 00597 st_generator *stgen; 00598 array_t *dependenceArray = array_alloc(int, array_n(leftVars)); 00599 int i,mddId; 00600 Ntk_Node_t *node, *node1; 00601 int count; 00602 00603 /* initialize the scores to 0 */ 00604 supportTable = st_init_table(st_ptrcmp, st_ptrhash); 00605 arrayForEachItem(int, leftVars, i, mddId) { 00606 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00607 assert(node); 00608 st_insert(supportTable, node, (char *)0); 00609 } 00610 00611 /* compute the supports of the absFsm */ 00612 roots = array_alloc(Ntk_Node_t *, 0); 00613 st_foreach_item(vertexTable, stgen, &node, 0) { 00614 node = Ntk_LatchReadDataInput(node); 00615 array_insert(Ntk_Node_t *, roots, 0, node); 00616 00617 supports = Ntk_NodeComputeTransitiveFaninNodes(network, roots, TRUE, 00618 FALSE); 00619 00620 arrayForEachItem(Ntk_Node_t *, supports, i, node1) { 00621 if (st_lookup_int(supportTable, node1, &count)) { 00622 count++; 00623 st_insert(supportTable, node1, (char *)(long)count); 00624 } 00625 } 00626 array_free(supports); 00627 } 00628 array_free(roots); 00629 00630 /* put into an array */ 00631 arrayForEachItem(int, leftVars, i, mddId) { 00632 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00633 assert(node); 00634 st_lookup_int(supportTable, node, &count); 00635 array_insert(int, dependenceArray, i, count); 00636 } 00637 00638 st_free_table(supportTable); 00639 00640 return dependenceArray; 00641 } 00642 00643 00644