00001 
00021 #include "rwr.h"
00022 #include "dec.h"
00023 
00027 
00028 static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable );
00029 static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
00030 static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut );
00031 static int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
00032 
00036 
00055 int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable )
00056 {
00057     int fVeryVerbose = 0;
00058     Dec_Graph_t * pGraph;
00059     Cut_Cut_t * pCut;
00060     Abc_Obj_t * pFanin;
00061     unsigned uPhase, uTruthBest, uTruth;
00062     char * pPerm;
00063     int Required, nNodesSaved, nNodesSaveCur;
00064     int i, GainCur, GainBest = -1;
00065     int clk, clk2;
00066 
00067     p->nNodesConsidered++;
00068     
00069     Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY;
00070 
00071     
00072 clk = clock();
00073     pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 );
00074     assert( pCut != NULL );
00075 p->timeCut += clock() - clk;
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084     
00085 clk = clock();
00086     for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
00087     {
00088         
00089         if ( pCut->nLeaves < 4 )
00090             continue;
00091 
00092 
00093         
00094         uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
00095         pPerm = p->pPerms4[ p->pPerms[uTruth] ];
00096         uPhase = p->pPhases[uTruth];
00097         
00098         Vec_PtrClear( p->vFaninsCur );
00099         Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 );
00100         for ( i = 0; i < (int)pCut->nLeaves; i++ )
00101         {
00102             pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[pPerm[i]] );
00103             if ( pFanin == NULL )
00104                 break;
00105             pFanin = Abc_ObjNotCond(pFanin, ((uPhase & (1<<i)) > 0) );
00106             Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
00107         }
00108         if ( i != (int)pCut->nLeaves )
00109         {
00110             p->nCutsBad++;
00111             continue;
00112         }
00113         p->nCutsGood++;
00114 
00115         {
00116             int Counter = 0;
00117             Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00118                 if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 )
00119                     Counter++;
00120             if ( Counter > 2 )
00121                 continue;
00122         }
00123 
00124 clk2 = clock();
00125 
00126 
00127 
00128 
00129 
00130 
00131         
00132         Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00133             Abc_ObjRegular(pFanin)->vFanouts.nSize++;
00134 
00135         
00136         Abc_NtkIncrementTravId( pNode->pNtk );
00137         nNodesSaved = Abc_NodeMffcLabelAig( pNode );
00138         
00139         Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00140             Abc_ObjRegular(pFanin)->vFanouts.nSize--;
00141 p->timeMffc += clock() - clk2;
00142 
00143         
00144 clk2 = clock();
00145         pGraph = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, fPlaceEnable );
00146 p->timeEval += clock() - clk2;
00147 
00148         
00149         if ( pGraph != NULL && GainBest < GainCur )
00150         {
00151             
00152             nNodesSaveCur = nNodesSaved;
00153             GainBest  = GainCur;
00154             p->pGraph  = pGraph;
00155             p->fCompl = ((uPhase & (1<<4)) > 0);
00156             uTruthBest = 0xFFFF & *Cut_CutReadTruth(pCut);
00157             
00158             Vec_PtrClear( p->vFanins );
00159             Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00160                 Vec_PtrPush( p->vFanins, pFanin );
00161         }
00162     }
00163 p->timeRes += clock() - clk;
00164 
00165     if ( GainBest == -1 )
00166         return -1;
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202     
00203     Vec_PtrForEachEntry( p->vFanins, pFanin, i )
00204         Dec_GraphNode(p->pGraph, i)->pFunc = pFanin;
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213     p->nScores[p->pMap[uTruthBest]]++;
00214     p->nNodesGained += GainBest;
00215     if ( fUseZeros || GainBest > 0 )
00216     {
00217         p->nNodesRewritten++;
00218     }
00219 
00220     
00221     if ( fVeryVerbose && GainBest > 0 )
00222     {
00223         printf( "Node %6s :   ", Abc_ObjName(pNode) );
00224         printf( "Fanins = %d. ", p->vFanins->nSize );
00225         printf( "Save = %d.  ", nNodesSaveCur );
00226         printf( "Add = %d.  ",  nNodesSaveCur-GainBest );
00227         printf( "GAIN = %d.  ", GainBest );
00228         printf( "Cone = %d.  ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 );
00229         printf( "Class = %d.  ", p->pMap[uTruthBest] );
00230         printf( "\n" );
00231     }
00232     return GainBest;
00233 }
00234 
00246 Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable )
00247 {
00248     Vec_Ptr_t * vSubgraphs;
00249     Dec_Graph_t * pGraphBest, * pGraphCur;
00250     Rwr_Node_t * pNode, * pFanin;
00251     int nNodesAdded, GainBest, i, k;
00252     unsigned uTruth;
00253     float CostBest;
00254     
00255     uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
00256     vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
00257     p->nSubgraphs += vSubgraphs->nSize;
00258     
00259     GainBest = -1;
00260     CostBest = ABC_INFINITY;
00261     Vec_PtrForEachEntry( vSubgraphs, pNode, i )
00262     {
00263         
00264         pGraphCur = (Dec_Graph_t *)pNode->pNext;
00265         
00266         Vec_PtrForEachEntry( vFaninsCur, pFanin, k )
00267             Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
00268         
00269         nNodesAdded = Dec_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax );
00270         if ( nNodesAdded == -1 )
00271             continue;
00272         assert( nNodesSaved >= nNodesAdded );
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310         {
00311             
00312             if ( GainBest < nNodesSaved - nNodesAdded )
00313             {
00314                 GainBest   = nNodesSaved - nNodesAdded;
00315                 pGraphBest = pGraphCur;
00316 
00317                 
00318                 if ( nNodesSaved - nNodesAdded > 0 )
00319                 {
00320                     pNode->nScore++;
00321                     pNode->nGain += GainBest;
00322                     pNode->nAdded += nNodesAdded;
00323                 }
00324             }
00325         }
00326     }
00327     if ( GainBest == -1 )
00328         return NULL;
00329     *pGainBest = GainBest;
00330     return pGraphBest;
00331 }
00332 
00344 void Rwr_CutIsBoolean_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves, int fMarkA )
00345 {
00346     if ( Vec_PtrFind(vLeaves, pObj) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pObj)) >= 0 )
00347     {
00348         if ( fMarkA )
00349             pObj->fMarkA = 1;
00350         else
00351             pObj->fMarkB = 1;
00352         return;
00353     }
00354     assert( !Abc_ObjIsCi(pObj) );
00355     Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, fMarkA );
00356     Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, fMarkA );
00357 }
00358 
00370 int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
00371 {
00372     Abc_Obj_t * pTemp;
00373     int i, RetValue;
00374     Vec_PtrForEachEntry( vLeaves, pTemp, i )
00375     {
00376         pTemp = Abc_ObjRegular(pTemp);
00377         assert( !pTemp->fMarkA && !pTemp->fMarkB );
00378     }
00379     Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, 1 );
00380     Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, 0 );
00381     RetValue = 0;
00382     Vec_PtrForEachEntry( vLeaves, pTemp, i )
00383     {
00384         pTemp = Abc_ObjRegular(pTemp);
00385         RetValue |= pTemp->fMarkA && pTemp->fMarkB;
00386         pTemp->fMarkA = pTemp->fMarkB = 0;
00387     }
00388     return RetValue;
00389 }
00390 
00391 
00403 void Rwr_CutCountNumNodes_rec( Abc_Obj_t * pObj, Cut_Cut_t * pCut, Vec_Ptr_t * vNodes )
00404 {
00405     int i;
00406     for ( i = 0; i < (int)pCut->nLeaves; i++ )
00407         if ( pCut->pLeaves[i] == pObj->Id )
00408         {
00409             
00410             if ( pObj->fMarkC == 0 )
00411             {
00412                 pObj->fMarkC = 1;
00413                 Vec_PtrPush( vNodes, pObj );
00414             }
00415             return;
00416         }
00417     assert( Abc_ObjIsNode(pObj) );
00418     
00419     if ( pObj->fMarkC == 0 )
00420     {
00421         pObj->fMarkC = 1;
00422         Vec_PtrPush( vNodes, pObj );
00423     }
00424     
00425     Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes );
00426     Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes );
00427 }
00428 
00440 int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut )
00441 {
00442     Vec_Ptr_t * vNodes;
00443     int i, Counter;
00444     
00445     vNodes = Vec_PtrAlloc( 100 );
00446     for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
00447         Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes );
00448     
00449     Vec_PtrForEachEntry( vNodes, pObj, i )
00450         pObj->fMarkC = 0;
00451     
00452     Counter = Vec_PtrSize(vNodes);
00453     Vec_PtrFree( vNodes );
00454     return Counter;
00455 }
00456 
00457 
00469 int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
00470 {
00471     Abc_Obj_t * pLeaf;
00472     int i, Depth0, Depth1;
00473     if ( Abc_ObjIsCi(pObj) )
00474         return 0;
00475     Vec_PtrForEachEntry( vLeaves, pLeaf, i )
00476         if ( pObj == Abc_ObjRegular(pLeaf) )
00477             return 0;
00478     Depth0 = Rwr_NodeGetDepth_rec( Abc_ObjFanin0(pObj), vLeaves );
00479     Depth1 = Rwr_NodeGetDepth_rec( Abc_ObjFanin1(pObj), vLeaves );
00480     return 1 + ABC_MAX( Depth0, Depth1 );
00481 }
00482 
00483 
00495 void Rwr_ScoresClean( Rwr_Man_t * p )
00496 {
00497     Vec_Ptr_t * vSubgraphs;
00498     Rwr_Node_t * pNode;
00499     int i, k;
00500     for ( i = 0; i < p->vClasses->nSize; i++ )
00501     {
00502         vSubgraphs = Vec_VecEntry( p->vClasses, i );
00503         Vec_PtrForEachEntry( vSubgraphs, pNode, k )
00504             pNode->nScore = pNode->nGain = pNode->nAdded = 0;
00505     }
00506 }
00507 
00508 static int Gains[222];
00509 
00521 int Rwr_ScoresCompare( int * pNum1, int * pNum2 )
00522 {
00523     if ( Gains[*pNum1] > Gains[*pNum2] )
00524         return -1;
00525     if ( Gains[*pNum1] < Gains[*pNum2] )
00526         return 1;
00527     return 0;
00528 }
00529 
00541 void Rwr_ScoresReport( Rwr_Man_t * p )
00542 {
00543     extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
00544     int Perm[222];
00545     Vec_Ptr_t * vSubgraphs;
00546     Rwr_Node_t * pNode;
00547     int i, iNew, k;
00548     unsigned uTruth;
00549     
00550     assert( p->vClasses->nSize == 222 );
00551     for ( i = 0; i < p->vClasses->nSize; i++ )
00552     {
00553         Perm[i] = i;
00554         Gains[i] = 0;
00555         vSubgraphs = Vec_VecEntry( p->vClasses, i );
00556         Vec_PtrForEachEntry( vSubgraphs, pNode, k )
00557             Gains[i] += pNode->nGain;
00558     }
00559     
00560     qsort( Perm, 222, sizeof(int), (int (*)(const void *, const void *))Rwr_ScoresCompare );
00561 
00562     
00563     for ( i = 0; i < p->vClasses->nSize; i++ )
00564     {
00565         iNew = Perm[i];
00566         if ( Gains[iNew] == 0 )
00567             break;
00568         vSubgraphs = Vec_VecEntry( p->vClasses, iNew );
00569         printf( "CLASS %3d: Subgr = %3d. Total gain = %6d.  ", iNew, Vec_PtrSize(vSubgraphs), Gains[iNew] );
00570         uTruth = (unsigned)p->pMapInv[iNew];
00571         Extra_PrintBinary( stdout, &uTruth, 16 );
00572         printf( "  " );
00573         Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[iNew] | ((unsigned)p->pMapInv[iNew] << 16) );
00574         Vec_PtrForEachEntry( vSubgraphs, pNode, k )
00575         {
00576             if ( pNode->nScore == 0 )
00577                 continue;
00578             printf( "    %2d: S=%5d. A=%5d. G=%6d. ", k, pNode->nScore, pNode->nAdded, pNode->nGain );
00579             Dec_GraphPrint( stdout, (Dec_Graph_t *)pNode->pNext, NULL, NULL );
00580         }
00581     }
00582 }
00583 
00587 
00588