00001 
00021 #include "darInt.h"
00022 #include "kit.h"
00023 
00027 
00028 
00029 typedef struct Ref_Man_t_            Ref_Man_t;
00030 struct Ref_Man_t_
00031 {
00032     
00033     Dar_RefPar_t *   pPars;          
00034     Aig_Man_t *      pAig;           
00035     
00036     Vec_Vec_t *      vCuts;          
00037     
00038     Vec_Ptr_t *      vTruthElem;     
00039     Vec_Ptr_t *      vTruthStore;    
00040     Vec_Int_t *      vMemory;        
00041     Vec_Ptr_t *      vCutNodes;      
00042     
00043     Vec_Ptr_t *      vLeavesBest;    
00044     Kit_Graph_t *    pGraphBest;     
00045     int              GainBest;       
00046     int              LevelBest;      
00047     
00048     int              nNodesInit;     
00049     int              nNodesTried;    
00050     int              nNodesBelow;    
00051     int              nNodesExten;    
00052     int              nCutsUsed;      
00053     int              nCutsTried;     
00054     
00055     int              timeCuts;
00056     int              timeEval;
00057     int              timeOther;
00058     int              timeTotal;
00059 };
00060 
00064 
00076 void Dar_ManDefaultRefParams( Dar_RefPar_t * pPars )
00077 {
00078     memset( pPars, 0, sizeof(Dar_RefPar_t) );
00079     pPars->nMffcMin     =  2;  
00080     pPars->nLeafMax     = 12;  
00081     pPars->nCutsMax     =  5;  
00082     pPars->fUpdateLevel =  0;
00083     pPars->fUseZeros    =  0;
00084     pPars->fVerbose     =  0;
00085     pPars->fVeryVerbose =  0;
00086 }
00087 
00099 Ref_Man_t * Dar_ManRefStart( Aig_Man_t * pAig, Dar_RefPar_t * pPars )
00100 {
00101     Ref_Man_t * p;
00102     
00103     p = ALLOC( Ref_Man_t, 1 );
00104     memset( p, 0, sizeof(Ref_Man_t) );
00105     p->pAig         = pAig;
00106     p->pPars        = pPars;
00107     
00108     p->vCuts        = Vec_VecStart( pPars->nCutsMax );
00109     p->vTruthElem   = Vec_PtrAllocTruthTables( pPars->nLeafMax );
00110     p->vTruthStore  = Vec_PtrAllocSimInfo( 256, Kit_TruthWordNum(pPars->nLeafMax) );
00111     p->vMemory      = Vec_IntAlloc( 1 << 16 );
00112     p->vCutNodes    = Vec_PtrAlloc( 256 );
00113     p->vLeavesBest  = Vec_PtrAlloc( pPars->nLeafMax );
00114     return p;
00115 }
00116 
00128 void Dar_ManRefPrintStats( Ref_Man_t * p )
00129 {
00130     int Gain = p->nNodesInit - Aig_ManNodeNum(p->pAig);
00131     printf( "NodesBeg = %8d. NodesEnd = %8d. Gain = %6d. (%6.2f %%).\n", 
00132         p->nNodesInit, Aig_ManNodeNum(p->pAig), Gain, 100.0*Gain/p->nNodesInit );
00133     printf( "Tried = %6d. Below = %5d. Extended = %5d.  Used = %5d.  Levels = %4d.\n", 
00134         p->nNodesTried, p->nNodesBelow, p->nNodesExten, p->nCutsUsed, Aig_ManLevels(p->pAig) );
00135     PRT( "Cuts  ", p->timeCuts );
00136     PRT( "Eval  ", p->timeEval );
00137     PRT( "Other ", p->timeOther );
00138     PRT( "TOTAL ", p->timeTotal );
00139 }
00140 
00152 void Dar_ManRefStop( Ref_Man_t * p )
00153 {
00154     if ( p->pPars->fVerbose )
00155         Dar_ManRefPrintStats( p );
00156     Vec_VecFree( p->vCuts );
00157     Vec_PtrFree( p->vTruthElem );
00158     Vec_PtrFree( p->vTruthStore );
00159     Vec_PtrFree( p->vLeavesBest );
00160     Vec_IntFree( p->vMemory );
00161     Vec_PtrFree( p->vCutNodes );
00162     free( p );
00163 }
00164 
00176 void Ref_ObjComputeCuts( Aig_Man_t * pAig, Aig_Obj_t * pRoot, Vec_Vec_t * vCuts )
00177 {
00178 }
00179 
00191 void Ref_ObjPrint( Aig_Obj_t * pObj )
00192 {
00193     printf( "%d", pObj? Aig_Regular(pObj)->Id : -1 );
00194     if ( pObj )
00195         printf( "(%d) ", Aig_IsComplement(pObj) );
00196 }
00197 
00212 int Dar_RefactTryGraph( Aig_Man_t * pAig, Aig_Obj_t * pRoot, Vec_Ptr_t * vCut, Kit_Graph_t * pGraph, int NodeMax, int LevelMax )
00213 {
00214     Kit_Node_t * pNode, * pNode0, * pNode1;
00215     Aig_Obj_t * pAnd, * pAnd0, * pAnd1;
00216     int i, Counter, LevelNew, LevelOld;
00217     
00218     if ( Kit_GraphIsConst(pGraph) || Kit_GraphIsVar(pGraph) )
00219         return 0;
00220     
00221     Kit_GraphForEachLeaf( pGraph, pNode, i )
00222     {
00223         pNode->pFunc = Vec_PtrEntry(vCut, i);
00224         pNode->Level = Aig_Regular(pNode->pFunc)->Level;
00225         assert( Aig_Regular(pNode->pFunc)->Level < (1<<14)-1 );
00226     }
00227 
00228     
00229     Counter = 0;
00230     Kit_GraphForEachNode( pGraph, pNode, i )
00231     {
00232         
00233         pNode0 = Kit_GraphNode( pGraph, pNode->eEdge0.Node );
00234         pNode1 = Kit_GraphNode( pGraph, pNode->eEdge1.Node );
00235         
00236         pAnd0 = pNode0->pFunc; 
00237         pAnd1 = pNode1->pFunc; 
00238         if ( pAnd0 && pAnd1 )
00239         {
00240             
00241             pAnd0 = Aig_NotCond( pAnd0, pNode->eEdge0.fCompl );
00242             pAnd1 = Aig_NotCond( pAnd1, pNode->eEdge1.fCompl );
00243             pAnd  = Aig_TableLookupTwo( pAig, pAnd0, pAnd1 );
00244             
00245             if ( Aig_Regular(pAnd) == pRoot )
00246                 return -1;
00247         }
00248         else
00249             pAnd = NULL;
00250         
00251         if ( pAnd == NULL || Aig_ObjIsTravIdCurrent(pAig, Aig_Regular(pAnd)) )
00252         {
00253             if ( ++Counter > NodeMax )
00254                 return -1;
00255         }
00256         
00257         LevelNew = 1 + AIG_MAX( pNode0->Level, pNode1->Level );
00258         if ( pAnd )
00259         {
00260             if ( Aig_Regular(pAnd) == Aig_ManConst1(pAig) )
00261                 LevelNew = 0;
00262             else if ( Aig_Regular(pAnd) == Aig_Regular(pAnd0) )
00263                 LevelNew = (int)Aig_Regular(pAnd0)->Level;
00264             else if ( Aig_Regular(pAnd) == Aig_Regular(pAnd1) )
00265                 LevelNew = (int)Aig_Regular(pAnd1)->Level;
00266             LevelOld = (int)Aig_Regular(pAnd)->Level;
00267 
00268         }
00269         if ( LevelNew > LevelMax )
00270             return -1;
00271         pNode->pFunc = pAnd;
00272         pNode->Level = LevelNew;
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282     }
00283     return Counter;
00284 }
00285 
00297 Aig_Obj_t * Dar_RefactBuildGraph( Aig_Man_t * pAig, Vec_Ptr_t * vCut, Kit_Graph_t * pGraph )
00298 {
00299     Aig_Obj_t * pAnd0, * pAnd1;
00300     Kit_Node_t * pNode = NULL;
00301     int i;
00302     
00303     if ( Kit_GraphIsConst(pGraph) )
00304         return Aig_NotCond( Aig_ManConst1(pAig), Kit_GraphIsComplement(pGraph) );
00305     
00306     Kit_GraphForEachLeaf( pGraph, pNode, i )
00307         pNode->pFunc = Vec_PtrEntry(vCut, i);
00308     
00309     if ( Kit_GraphIsVar(pGraph) )
00310         return Aig_NotCond( Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) );
00311     
00312 
00313     Kit_GraphForEachNode( pGraph, pNode, i )
00314     {
00315         pAnd0 = Aig_NotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); 
00316         pAnd1 = Aig_NotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); 
00317         pNode->pFunc = Aig_And( pAig, pAnd0, pAnd1 );
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327     }
00328     
00329     return Aig_NotCond( pNode->pFunc, Kit_GraphIsComplement(pGraph) );
00330 }
00331 
00343 int Dar_ManRefactorTryCuts( Ref_Man_t * p, Aig_Obj_t * pObj, int nNodesSaved, int Required )
00344 {
00345     Vec_Ptr_t * vCut;
00346     Kit_Graph_t * pGraphCur;
00347     int k, RetValue, GainCur, nNodesAdded;
00348     unsigned * pTruth;
00349 
00350     p->GainBest = -1;
00351     p->pGraphBest = NULL;
00352     Vec_VecForEachLevel( p->vCuts, vCut, k )
00353     {
00354         if ( Vec_PtrSize(vCut) == 0 )
00355             continue;
00356 
00357 
00358 
00359         p->nCutsTried++;
00360         
00361         Aig_ObjCollectCut( pObj, vCut, p->vCutNodes );
00362         
00363         pTruth = Aig_ManCutTruth( pObj, vCut, p->vCutNodes, p->vTruthElem, p->vTruthStore );
00364         if ( Kit_TruthIsConst0(pTruth, Vec_PtrSize(vCut)) )
00365         {
00366             p->GainBest = Vec_PtrSize(p->vCutNodes);
00367             p->pGraphBest = Kit_GraphCreateConst0();
00368             Vec_PtrCopy( p->vLeavesBest, vCut );
00369             return p->GainBest;
00370         }
00371         if ( Kit_TruthIsConst1(pTruth, Vec_PtrSize(vCut)) )
00372         {
00373             p->GainBest = Vec_PtrSize(p->vCutNodes);
00374             p->pGraphBest = Kit_GraphCreateConst1();
00375             Vec_PtrCopy( p->vLeavesBest, vCut );
00376             return p->GainBest;
00377         }
00378 
00379         
00380         RetValue = Kit_TruthIsop( pTruth, Vec_PtrSize(vCut), p->vMemory, 0 );
00381         if ( RetValue > -1 )
00382         {
00383             pGraphCur = Kit_SopFactor( p->vMemory, 0, Vec_PtrSize(vCut), p->vMemory );
00384             nNodesAdded = Dar_RefactTryGraph( p->pAig, pObj, vCut, pGraphCur, nNodesSaved - !p->pPars->fUseZeros, Required );
00385             if ( nNodesAdded > -1 )
00386             {
00387                 GainCur = nNodesSaved - nNodesAdded;
00388                 if ( p->GainBest < GainCur || (p->GainBest == GainCur && 
00389                     (Kit_GraphIsConst(pGraphCur) || Kit_GraphRootLevel(pGraphCur) < Kit_GraphRootLevel(p->pGraphBest))) )
00390                 {
00391                     p->GainBest = GainCur;
00392                     if ( p->pGraphBest )
00393                         Kit_GraphFree( p->pGraphBest );
00394                     p->pGraphBest = pGraphCur;
00395                     Vec_PtrCopy( p->vLeavesBest, vCut );
00396                 }
00397                 else
00398                     Kit_GraphFree( pGraphCur );
00399             }
00400             else
00401                 Kit_GraphFree( pGraphCur );
00402         }
00403         
00404         Kit_TruthNot( pTruth, pTruth, Vec_PtrSize(vCut) );
00405         RetValue = Kit_TruthIsop( pTruth, Vec_PtrSize(vCut), p->vMemory, 0 );
00406         if ( RetValue > -1 )
00407         {
00408             pGraphCur = Kit_SopFactor( p->vMemory, 1, Vec_PtrSize(vCut), p->vMemory );
00409             nNodesAdded = Dar_RefactTryGraph( p->pAig, pObj, vCut, pGraphCur, nNodesSaved - !p->pPars->fUseZeros, Required );
00410             if ( nNodesAdded > -1 )
00411             {
00412                 GainCur = nNodesSaved - nNodesAdded;
00413                 if ( p->GainBest < GainCur || (p->GainBest == GainCur && 
00414                     (Kit_GraphIsConst(pGraphCur) || Kit_GraphRootLevel(pGraphCur) < Kit_GraphRootLevel(p->pGraphBest))) )
00415                 {
00416                     p->GainBest = GainCur;
00417                     if ( p->pGraphBest )
00418                         Kit_GraphFree( p->pGraphBest );
00419                     p->pGraphBest = pGraphCur;
00420                     Vec_PtrCopy( p->vLeavesBest, vCut );
00421                 }
00422                 else
00423                     Kit_GraphFree( pGraphCur );
00424             }
00425             else
00426                 Kit_GraphFree( pGraphCur );
00427         }
00428     }
00429     return p->GainBest;
00430 }
00431 
00443 int Dar_ObjCutLevelAchieved( Vec_Ptr_t * vCut, int nLevelMin )
00444 {
00445     Aig_Obj_t * pObj;
00446     int i;
00447     Vec_PtrForEachEntry( vCut, pObj, i )
00448         if ( !Aig_ObjIsPi(pObj) && (int)pObj->Level <= nLevelMin )
00449             return 1;
00450     return 0;
00451 }
00452 
00464 int Dar_ManRefactor( Aig_Man_t * pAig, Dar_RefPar_t * pPars )
00465 {
00466 
00467     Ref_Man_t * p;
00468     Vec_Ptr_t * vCut, * vCut2;
00469     Aig_Obj_t * pObj, * pObjNew;
00470     int nNodesOld, nNodeBefore, nNodeAfter, nNodesSaved, nNodesSaved2;
00471     int i, Required, nLevelMin, clkStart, clk;
00472 
00473     
00474     p = Dar_ManRefStart( pAig, pPars );
00475     
00476     Aig_ManCleanup( pAig );
00477     
00478     Aig_ManFanoutStart( pAig );
00479     if ( p->pPars->fUpdateLevel )
00480         Aig_ManStartReverseLevels( pAig, 0 );
00481 
00482     
00483     clkStart = clock();
00484     vCut = Vec_VecEntry( p->vCuts, 0 );
00485     vCut2 = Vec_VecEntry( p->vCuts, 1 );
00486     p->nNodesInit = Aig_ManNodeNum(pAig);
00487     nNodesOld = Vec_PtrSize( pAig->vObjs );
00488 
00489     Aig_ManForEachObj( pAig, pObj, i )
00490     {
00491 
00492         if ( !Aig_ObjIsNode(pObj) )
00493             continue;
00494         if ( i > nNodesOld )
00495             break;
00496         Vec_VecClear( p->vCuts );
00497 
00498 
00499         
00500 clk = clock();
00501         nLevelMin = AIG_MAX( 0, Aig_ObjLevel(pObj) - 10 );
00502         nNodesSaved = Aig_NodeMffsSupp( pAig, pObj, nLevelMin, vCut );
00503         if ( nNodesSaved < p->pPars->nMffcMin ) 
00504         {
00505 p->timeCuts += clock() - clk;
00506             continue; 
00507         }
00508         p->nNodesTried++;
00509         if ( Vec_PtrSize(vCut) > p->pPars->nLeafMax ) 
00510         {
00511             Aig_ManFindCut( pObj, vCut, p->vCutNodes, p->pPars->nLeafMax, 50 );
00512             nNodesSaved = Aig_NodeMffsLabelCut( p->pAig, pObj, vCut );
00513         }
00514         else if ( Vec_PtrSize(vCut) < p->pPars->nLeafMax - 2 && p->pPars->fExtend )
00515         {
00516             if ( !Dar_ObjCutLevelAchieved(vCut, nLevelMin) )
00517             {
00518                 if ( Aig_NodeMffsExtendCut( pAig, pObj, vCut, vCut2 ) )
00519                 {
00520                     nNodesSaved2 = Aig_NodeMffsLabelCut( p->pAig, pObj, vCut );
00521                     assert( nNodesSaved2 == nNodesSaved );
00522                 }
00523                 if ( Vec_PtrSize(vCut2) > p->pPars->nLeafMax )
00524                     Vec_PtrClear(vCut2);
00525                 if ( Vec_PtrSize(vCut2) > 0 )
00526                 {
00527                     p->nNodesExten++;
00528 
00529                 }
00530             }
00531             else
00532                 p->nNodesBelow++;
00533         }
00534 p->timeCuts += clock() - clk;
00535 
00536         
00537 clk = clock();
00538         Required = pAig->vLevelR? Aig_ObjRequiredLevel(pAig, pObj) : AIG_INFINITY;
00539         Dar_ManRefactorTryCuts( p, pObj, nNodesSaved, Required );
00540 p->timeEval += clock() - clk;
00541 
00542         
00543         if ( !(p->GainBest > 0 || (p->GainBest == 0 && p->pPars->fUseZeros)) )
00544         {
00545             if ( p->pGraphBest )
00546                 Kit_GraphFree( p->pGraphBest );
00547             continue;
00548         }
00549 
00550 
00551         
00552         nNodeBefore = Aig_ManNodeNum( pAig );
00553         pObjNew = Dar_RefactBuildGraph( pAig, p->vLeavesBest, p->pGraphBest );
00554         assert( (int)Aig_Regular(pObjNew)->Level <= Required );
00555         
00556         Aig_ObjReplace( pAig, pObj, pObjNew, 1, p->pPars->fUpdateLevel );
00557         
00558         nNodeAfter = Aig_ManNodeNum( pAig );
00559         assert( p->GainBest <= nNodeBefore - nNodeAfter );
00560         Kit_GraphFree( p->pGraphBest );
00561         p->nCutsUsed++;
00562 
00563     }
00564 p->timeTotal = clock() - clkStart;
00565 p->timeOther = p->timeTotal - p->timeCuts - p->timeEval;
00566 
00567 
00568     
00569 
00570     
00571     Aig_ManFanoutStop( pAig );
00572     if ( p->pPars->fUpdateLevel )
00573         Aig_ManStopReverseLevels( pAig );
00574 
00575     
00576     Dar_ManRefStop( p );
00577     Aig_ManCheckPhase( pAig );
00578     if ( !Aig_ManCheck( pAig ) )
00579     {
00580         printf( "Dar_ManRefactor: The network check has failed.\n" );
00581         return 0;
00582     }
00583     return 1;
00584 
00585 }
00586 
00590 
00591