diff options
Diffstat (limited to 'src/opt/rwr/rwrEva.c')
-rw-r--r-- | src/opt/rwr/rwrEva.c | 254 |
1 files changed, 98 insertions, 156 deletions
diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c index b486785f..735232af 100644 --- a/src/opt/rwr/rwrEva.c +++ b/src/opt/rwr/rwrEva.c @@ -25,7 +25,7 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t * pCut, int NodeMax, int LevelMax ); +static Vec_Int_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 ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFITIONS /// @@ -49,37 +49,101 @@ static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t SeeAlso [] ***********************************************************************/ -int Rwr_NodeRewrite( Rwr_Man_t * p, Abc_Obj_t * pNode ) +int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUseZeros ) { + int fVeryVerbose = 0; Vec_Int_t * vForm; - Rwr_Cut_t * pCut; + Cut_Cut_t * pCut; + Abc_Obj_t * pFanin; + unsigned uPhase, uTruthBest; + char * pPerm; int Required, nNodesSaved; - int i, BestGain = -1; - // compute the cuts for this node - Rwr_NodeComputeCuts( p, pNode ); + int i, GainCur, GainBest = -1; + int clk; + + p->nNodesConsidered++; // get the required times - Required = Vec_IntEntry( p->vReqTimes, pNode->Id ); - // label MFFC with current ID - nNodesSaved = Abc_NodeMffcLabel( pNode ); + Required = Abc_NodeReadRequiredLevel( pNode ); + // get the node's cuts +clk = clock(); + pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode ); + assert( pCut != NULL ); +p->timeCut += clock() - clk; + // go through the cuts - for ( pCut = (Rwr_Cut_t *)pNode->pCopy, pCut = pCut->pNext; pCut; pCut = pCut->pNext ) +clk = clock(); + for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext ) { + // consider only 4-input cuts + if ( pCut->nLeaves < 4 ) + continue; + // get the fanin permutation + pPerm = p->pPerms4[ p->pPerms[pCut->uTruth] ]; + uPhase = p->pPhases[pCut->uTruth]; + // collect fanins with the corresponding permutation/phase + Vec_PtrClear( p->vFaninsCur ); + Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + { + pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[pPerm[i]] ); + if ( pFanin == NULL ) + break; + pFanin = Abc_ObjNotCond(pFanin, ((uPhase & (1<<i)) > 0) ); + Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin ); + } + if ( i != (int)pCut->nLeaves ) + { + p->nCutsBad++; + continue; + } + p->nCutsGood++; + + // mark the fanin boundary + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Abc_ObjRegular(pFanin)->vFanouts.nSize++; + // label MFFC with current ID + Abc_NtkIncrementTravId( pNode->pNtk ); + nNodesSaved = Abc_NodeMffcLabel( pNode ); + // unmark the fanin boundary + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Abc_ObjRegular(pFanin)->vFanouts.nSize--; + // evaluate the cut - vForm = Rwr_CutEvaluate( p, pNode, pCut, nNodesSaved, Required ); - // check if the cut is better than the currently best one - if ( vForm != NULL && BestGain < (int)pCut->Volume ) + vForm = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur ); + + // check if the cut is better than the current best one + if ( vForm != NULL && GainBest < GainCur ) { - assert( pCut->Volume >= 0 ); - BestGain = pCut->Volume; // save this form - p->vForm = vForm; - // collect fanins + GainBest = GainCur; + p->vForm = vForm; + p->fCompl = ((uPhase & (1<<4)) > 0); + uTruthBest = pCut->uTruth; + // collect fanins in the Vec_PtrClear( p->vFanins ); - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - Vec_PtrPush( p->vFanins, pCut->ppLeaves[i] ); + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrPush( p->vFanins, pFanin ); } } - return BestGain; +p->timeRes += clock() - clk; + + if ( GainBest == -1 || GainBest == 0 && !fUseZeros ) + return GainBest; + + p->nScores[p->pMap[uTruthBest]]++; + p->nNodesRewritten++; + p->nNodesGained += GainBest; + + // report the progress + if ( fVeryVerbose ) + { + printf( "Node %6s : ", Abc_ObjName(pNode) ); + printf( "Fanins = %d. ", p->vFanins->nSize ); + printf( "Cone = %2d. ", p->vForm->nSize - 4 ); + printf( "GAIN = %2d. ", GainBest ); + printf( "\n" ); + } + return GainBest; } /**Function************************************************************* @@ -93,161 +157,39 @@ int Rwr_NodeRewrite( Rwr_Man_t * p, Abc_Obj_t * pNode ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t * pCut, int NodeMax, int LevelMax ) +Vec_Int_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 ) { - Vec_Ptr_t Vector = {0,0,0}, * vFanins = &Vector; Vec_Ptr_t * vSubgraphs; Vec_Int_t * vFormBest; Rwr_Node_t * pNode; - int GainCur, GainBest = -1, i; + int nNodesAdded, GainBest = -1, i; + int clk = clock(); // find the matching class of subgraphs vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[pCut->uTruth] ); + p->nSubgraphs += vSubgraphs->nSize; // determine the best subgraph Vec_PtrForEachEntry( vSubgraphs, pNode, i ) { - // create the fanin array - vFanins->nSize = pCut->nLeaves; - vFanins->pArray = pCut->ppLeaves; // detect how many unlabeled nodes will be reused - GainCur = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFanins, (Vec_Int_t *)pNode->pNext, - p->vLevNums, NodeMax, LevelMax ); - if ( GainBest < GainCur ) + nNodesAdded = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFaninsCur, + (Vec_Int_t *)pNode->pNext, p->vLevNums, nNodesSaved, LevelMax ); + if ( nNodesAdded == -1 ) + continue; + assert( nNodesSaved >= nNodesAdded ); + // count the gain at this node + if ( GainBest < nNodesSaved - nNodesAdded ) { - GainBest = GainCur; + GainBest = nNodesSaved - nNodesAdded; vFormBest = (Vec_Int_t *)pNode->pNext; } } +p->timeEval += clock() - clk; if ( GainBest == -1 ) return NULL; - pCut->Volume = GainBest; + *pGainBest = GainBest; return vFormBest; } - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Vec_Int_t * vForm ) -{ - Ft_Node_t Node, NodeA, NodeB; - int Node0, Node1; - // elementary variable - if ( pNode->fUsed ) - return ((pNode->Id - 1) << 1); - // previously visited node - if ( pNode->TravId == p->nTravIds ) - return pNode->Volume; - pNode->TravId = p->nTravIds; - // solve for children - Node0 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p0), vForm ); - Node1 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p1), vForm ); - // create the decomposition node(s) - if ( pNode->fExor ) - { - assert( !Rwr_IsComplement(pNode->p0) ); - assert( !Rwr_IsComplement(pNode->p1) ); - NodeA.fIntern = 1; - NodeA.fConst = 0; - NodeA.fCompl = 0; - NodeA.fCompl0 = !(Node0 & 1); - NodeA.fCompl1 = (Node1 & 1); - NodeA.iFanin0 = (Node0 >> 1); - NodeA.iFanin1 = (Node1 >> 1); - Vec_IntPush( vForm, Ft_Node2Int(NodeA) ); - - NodeB.fIntern = 1; - NodeB.fConst = 0; - NodeB.fCompl = 0; - NodeB.fCompl0 = (Node0 & 1); - NodeB.fCompl1 = !(Node1 & 1); - NodeB.iFanin0 = (Node0 >> 1); - NodeB.iFanin1 = (Node1 >> 1); - Vec_IntPush( vForm, Ft_Node2Int(NodeB) ); - - Node.fIntern = 1; - Node.fConst = 0; - Node.fCompl = 0; - Node.fCompl0 = 1; - Node.fCompl1 = 1; - Node.iFanin0 = vForm->nSize - 2; - Node.iFanin1 = vForm->nSize - 1; - Vec_IntPush( vForm, Ft_Node2Int(Node) ); - } - else - { - Node.fIntern = 1; - Node.fConst = 0; - Node.fCompl = 0; - Node.fCompl0 = Rwr_IsComplement(pNode->p0) ^ (Node0 & 1); - Node.fCompl1 = Rwr_IsComplement(pNode->p1) ^ (Node1 & 1); - Node.iFanin0 = (Node0 >> 1); - Node.iFanin1 = (Node1 >> 1); - Vec_IntPush( vForm, Ft_Node2Int(Node) ); - } - // save the number of this node - pNode->Volume = ((vForm->nSize - 1) << 1) | pNode->fExor; - return pNode->Volume; -} - -/**Function************************************************************* - - Synopsis [Preprocesses subgraphs rooted at this node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode ) -{ - Vec_Int_t * vForm; - int i, Root; - vForm = Vec_IntAlloc( 10 ); - for ( i = 0; i < 5; i++ ) - Vec_IntPush( vForm, 0 ); - // collect the nodes - Rwr_ManIncTravId( p ); - Root = Rwr_TravCollect_rec( p, pNode, vForm ); - if ( Root & 1 ) - Ft_FactorComplement( vForm ); - pNode->pNext = (Rwr_Node_t *)vForm; -} - -/**Function************************************************************* - - Synopsis [Preprocesses computed library of subgraphs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManPreprocess( Rwr_Man_t * p ) -{ - Rwr_Node_t * pNode; - int i, k; - // put the nodes into the structure - p->vClasses = Vec_VecAlloc( 222 ); - for ( i = 0; i < p->nFuncs; i++ ) - for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext ) - Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode ); - // compute decomposition forms for each node - Vec_VecForEachEntry( p->vClasses, pNode, i, k ) - Rwr_NodePreprocess( p, pNode ); -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// |