darCore.c 11.1 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/**CFile****************************************************************

  FileName    [darCore.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [DAG-aware AIG rewriting.]

  Synopsis    [Core of the rewriting package.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - April 28, 2007.]

  Revision    [$Id: darCore.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]

***********************************************************************/

Alan Mishchenko committed
21
#include "darInt.h"
Alan Mishchenko committed
22

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

30 31 32 33 34 35
// iterator over the nodes in the topological order
#define Aig_ManForEachNodeInOrder( p, pObj )                                    \
    for ( assert(p->pOrderData), p->iPrev = 0, p->iNext = p->pOrderData[1];     \
          p->iNext && (((pObj) = Aig_ManObj(p, p->iNext)), 1);                  \
          p->iNext = p->pOrderData[2*p->iPrev+1] )

Alan Mishchenko committed
36 37 38 39 40 41
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

Alan Mishchenko committed
42 43 44 45 46 47 48 49 50
  Synopsis    [Returns the structure with default assignment of parameters.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
51
void Dar_ManDefaultRwrParams( Dar_RwrPar_t * pPars )
Alan Mishchenko committed
52
{
Alan Mishchenko committed
53
    memset( pPars, 0, sizeof(Dar_RwrPar_t) );
Alan Mishchenko committed
54
    pPars->nCutsMax     =  8; // 8
Alan Mishchenko committed
55
    pPars->nSubgMax     =  5; // 5 is a "magic number"
Alan Mishchenko committed
56
    pPars->fFanout      =  1;
Alan Mishchenko committed
57 58
    pPars->fUpdateLevel =  0;
    pPars->fUseZeros    =  0;
Alan Mishchenko committed
59
    pPars->fPower       =  0;
Alan Mishchenko committed
60
    pPars->fRecycle     =  1;
Alan Mishchenko committed
61 62
    pPars->fVerbose     =  0;
    pPars->fVeryVerbose =  0;
Alan Mishchenko committed
63 64
}

65 66
#define MAX_VAL 10

Alan Mishchenko committed
67 68
/**Function*************************************************************

Alan Mishchenko committed
69 70 71 72 73 74 75 76 77
  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
78
int Dar_ManRewrite( Aig_Man_t * pAig, Dar_RwrPar_t * pPars )
Alan Mishchenko committed
79
{
Alan Mishchenko committed
80
    extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
Alan Mishchenko committed
81
    Dar_Man_t * p;
Alan Mishchenko committed
82
//    Bar_Progress_t * pProgress;
Alan Mishchenko committed
83 84
    Dar_Cut_t * pCut;
    Aig_Obj_t * pObj, * pObjNew;
Alan Mishchenko committed
85
    int i, k, nNodesOld, nNodeBefore, nNodeAfter, Required;
Alan Mishchenko committed
86
    int clk = 0, clkStart, Counter = 0;
87
    int nMffcSize, nMffcGains[MAX_VAL+1][MAX_VAL+1] = {{0}};
Alan Mishchenko committed
88 89
    // prepare the library
    Dar_LibPrepare( pPars->nSubgMax ); 
Alan Mishchenko committed
90 91
    // create rewriting manager
    p = Dar_ManStart( pAig, pPars );
Alan Mishchenko committed
92 93
    if ( pPars->fPower )
        pAig->vProbs = Saig_ManComputeSwitchProbs( pAig, 48, 16, 1 );
Alan Mishchenko committed
94
    // remove dangling nodes
Alan Mishchenko committed
95
    Aig_ManCleanup( pAig );
Alan Mishchenko committed
96
    // if updating levels is requested, start fanout and timing
Alan Mishchenko committed
97 98
    if ( p->pPars->fFanout )
        Aig_ManFanoutStart( pAig );
Alan Mishchenko committed
99 100
    if ( p->pPars->fUpdateLevel )
        Aig_ManStartReverseLevels( pAig, 0 );
Alan Mishchenko committed
101
    // set elementary cuts for the PIs
Alan Mishchenko committed
102
//    Dar_ManCutsStart( p );
Alan Mishchenko committed
103
    // resynthesize each node once
Alan Mishchenko committed
104
    clkStart = clock();
Alan Mishchenko committed
105 106
    p->nNodesInit = Aig_ManNodeNum(pAig);
    nNodesOld = Vec_PtrSize( pAig->vObjs );
Alan Mishchenko committed
107

Alan Mishchenko committed
108
//    pProgress = Bar_ProgressStart( stdout, nNodesOld );
Alan Mishchenko committed
109
    Aig_ManForEachObj( pAig, pObj, i )
Alan Mishchenko committed
110
//    pProgress = Bar_ProgressStart( stdout, 100 );
Alan Mishchenko committed
111 112
//    Aig_ManOrderStart( pAig );
//    Aig_ManForEachNodeInOrder( pAig, pObj )
Alan Mishchenko committed
113
    {
Alan Mishchenko committed
114
//        Bar_ProgressUpdate( pProgress, 100*pAig->nAndPrev/pAig->nAndTotal, NULL );
Alan Mishchenko committed
115
//        Bar_ProgressUpdate( pProgress, i, NULL );
Alan Mishchenko committed
116
        if ( !Aig_ObjIsNode(pObj) )
Alan Mishchenko committed
117 118
            continue;
        if ( i > nNodesOld )
Alan Mishchenko committed
119
//        if ( p->pPars->fUseZeros && i > nNodesOld )
Alan Mishchenko committed
120
            break;
Alan Mishchenko committed
121 122 123 124 125 126 127
        if ( pPars->fRecycle && ++Counter % 50000 == 0 && Aig_DagSize(pObj) < Vec_PtrSize(p->vCutNodes)/100 )
        {
//            printf( "Counter = %7d.  Node = %7d.  Dag = %5d. Vec = %5d.\n", 
//                Counter, i, Aig_DagSize(pObj), Vec_PtrSize(p->vCutNodes) );
//            fflush( stdout );
            Dar_ManCutsRestart( p, pObj );
        }
Alan Mishchenko committed
128

Alan Mishchenko committed
129 130 131 132
        // consider freeing the cuts
//        if ( (i & 0xFFF) == 0 && Aig_MmFixedReadMemUsage(p->pMemCuts)/(1<<20) > 100 )
//            Dar_ManCutsStart( p );

Alan Mishchenko committed
133
        // compute cuts for the node
Alan Mishchenko committed
134
        p->nNodesTried++;
Alan Mishchenko committed
135
clk = clock();
Alan Mishchenko committed
136
        Dar_ObjSetCuts( pObj, NULL );
Alan Mishchenko committed
137
        Dar_ObjComputeCuts_rec( p, pObj );
Alan Mishchenko committed
138
p->timeCuts += clock() - clk;
Alan Mishchenko committed
139 140 141

        // check if there is a trivial cut
        Dar_ObjForEachCut( pObj, pCut, k )
Alan Mishchenko committed
142
            if ( pCut->nLeaves == 0 || (pCut->nLeaves == 1 && pCut->pLeaves[0] != pObj->Id && Aig_ManObj(p->pAig, pCut->pLeaves[0])) )
Alan Mishchenko committed
143 144
                break;
        if ( k < (int)pObj->nCuts )
Alan Mishchenko committed
145
        {
Alan Mishchenko committed
146 147
            assert( pCut->nLeaves < 2 );
            if ( pCut->nLeaves == 0 ) // replace by constant
Alan Mishchenko committed
148
            {
Alan Mishchenko committed
149 150
                assert( pCut->uTruth == 0 || pCut->uTruth == 0xFFFF );
                pObjNew = Aig_NotCond( Aig_ManConst1(p->pAig), pCut->uTruth==0 );
Alan Mishchenko committed
151
            }
Alan Mishchenko committed
152 153 154 155 156 157 158
            else
            {
                assert( pCut->uTruth == 0xAAAA || pCut->uTruth == 0x5555 );
                pObjNew = Aig_NotCond( Aig_ManObj(p->pAig, pCut->pLeaves[0]), pCut->uTruth==0x5555 );
            }
            // remove the old cuts
            Dar_ObjSetCuts( pObj, NULL );
Alan Mishchenko committed
159
            // replace the node
Alan Mishchenko committed
160
            Aig_ObjReplace( pAig, pObj, pObjNew, p->pPars->fUpdateLevel );
Alan Mishchenko committed
161
            continue;
Alan Mishchenko committed
162
        }
Alan Mishchenko committed
163 164 165

        // evaluate the cuts
        p->GainBest = -1;
166 167
        nMffcSize   = -1;
        Required    = pAig->vLevelR? Aig_ObjRequiredLevel(pAig, pObj) : ABC_INFINITY;
Alan Mishchenko committed
168
        Dar_ObjForEachCut( pObj, pCut, k )
169 170 171 172
        {
            int nLeavesOld = pCut->nLeaves;
            if ( pCut->nLeaves == 3 )
                pCut->pLeaves[pCut->nLeaves++] = 0;
173
            Dar_LibEval( p, pObj, pCut, Required, &nMffcSize );
174 175
            pCut->nLeaves = nLeavesOld; 
        }
Alan Mishchenko committed
176
        // check the best gain
Alan Mishchenko committed
177
        if ( !(p->GainBest > 0 || (p->GainBest == 0 && p->pPars->fUseZeros)) )
Alan Mishchenko committed
178 179
        {
//            Aig_ObjOrderAdvance( pAig );
Alan Mishchenko committed
180
            continue;
Alan Mishchenko committed
181
        }
182
//        nMffcGains[p->GainBest < MAX_VAL ? p->GainBest : MAX_VAL][nMffcSize < MAX_VAL ? nMffcSize : MAX_VAL]++;
Alan Mishchenko committed
183 184
        // remove the old cuts
        Dar_ObjSetCuts( pObj, NULL );
Alan Mishchenko committed
185
        // if we end up here, a rewriting step is accepted
Alan Mishchenko committed
186
        nNodeBefore = Aig_ManNodeNum( pAig );
Alan Mishchenko committed
187 188
        pObjNew = Dar_LibBuildBest( p ); // pObjNew can be complemented!
        pObjNew = Aig_NotCond( pObjNew, Aig_ObjPhaseReal(pObjNew) ^ pObj->fPhase );
Alan Mishchenko committed
189
        assert( (int)Aig_Regular(pObjNew)->Level <= Required );
Alan Mishchenko committed
190
        // replace the node
Alan Mishchenko committed
191
        Aig_ObjReplace( pAig, pObj, pObjNew, p->pPars->fUpdateLevel );
Alan Mishchenko committed
192
        // compare the gains
Alan Mishchenko committed
193
        nNodeAfter = Aig_ManNodeNum( pAig );
Alan Mishchenko committed
194 195 196
        assert( p->GainBest <= nNodeBefore - nNodeAfter );
        // count gains of this class
        p->ClassGains[p->ClassBest] += nNodeBefore - nNodeAfter;
Alan Mishchenko committed
197
    }
Alan Mishchenko committed
198
//    Aig_ManOrderStop( pAig );
199 200 201 202 203 204 205 206 207 208 209 210
/*
    printf( "Distribution of gain (row) by MFFC size (column) %s 0-costs:\n", p->pPars->fUseZeros? "with":"without" );
    for ( k = 0; k <= MAX_VAL; k++ )
        printf( "<%4d> ", k );
    printf( "\n" );
    for ( i = 0; i <= MAX_VAL; i++ )
    {
        for ( k = 0; k <= MAX_VAL; k++ )
            printf( "%6d ", nMffcGains[i][k] );
        printf( "\n" );
    }
*/
Alan Mishchenko committed
211

Alan Mishchenko committed
212 213 214
p->timeTotal = clock() - clkStart;
p->timeOther = p->timeTotal - p->timeCuts - p->timeEval;

Alan Mishchenko committed
215
//    Bar_ProgressStop( pProgress );
Alan Mishchenko committed
216 217
    Dar_ManCutsFree( p );
    // put the nodes into the DFS order and reassign their IDs
Alan Mishchenko committed
218
//    Aig_NtkReassignIds( p );
Alan Mishchenko committed
219
    // fix the levels
Alan Mishchenko committed
220 221 222
//    Aig_ManVerifyLevel( pAig );
    if ( p->pPars->fFanout )
        Aig_ManFanoutStop( pAig );
Alan Mishchenko committed
223
    if ( p->pPars->fUpdateLevel )
Alan Mishchenko committed
224 225
    {
//        Aig_ManVerifyReverseLevel( pAig );
Alan Mishchenko committed
226
        Aig_ManStopReverseLevels( pAig );
Alan Mishchenko committed
227
    }
Alan Mishchenko committed
228 229 230 231 232
    if ( pAig->vProbs )
    {
        Vec_IntFree( pAig->vProbs );
        pAig->vProbs = NULL;
    }
Alan Mishchenko committed
233 234
    // stop the rewriting manager
    Dar_ManStop( p );
Alan Mishchenko committed
235
    Aig_ManCheckPhase( pAig );
Alan Mishchenko committed
236
    // check
Alan Mishchenko committed
237
    if ( !Aig_ManCheck( pAig ) )
Alan Mishchenko committed
238
    {
Alan Mishchenko committed
239
        printf( "Aig_ManRewrite: The network check has failed.\n" );
Alan Mishchenko committed
240 241 242 243 244
        return 0;
    }
    return 1;
}

Alan Mishchenko committed
245 246
/**Function*************************************************************

Alan Mishchenko committed
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
  Synopsis    [Computes the total number of cuts.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Dar_ManCutCount( Aig_Man_t * pAig, int * pnCutsK )
{
    Dar_Cut_t * pCut;
    Aig_Obj_t * pObj;
    int i, k, nCuts = 0, nCutsK = 0;
    Aig_ManForEachNode( pAig, pObj, i )
        Dar_ObjForEachCut( pObj, pCut, k )
        {
            nCuts++;
            if ( pCut->nLeaves == 4 )
                nCutsK++;
        }
    if ( pnCutsK )
        *pnCutsK = nCutsK;
    return nCuts;
}

/**Function*************************************************************

Alan Mishchenko committed
275 276 277 278 279 280 281 282 283
  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
284
Aig_MmFixed_t * Dar_ManComputeCuts( Aig_Man_t * pAig, int nCutsMax, int fVerbose )
Alan Mishchenko committed
285
{
Alan Mishchenko committed
286
    Dar_Man_t * p;
Alan Mishchenko committed
287
    Dar_RwrPar_t Pars, * pPars = &Pars; 
Alan Mishchenko committed
288 289
    Aig_Obj_t * pObj;
    Aig_MmFixed_t * pMemCuts;
Alan Mishchenko committed
290
    int i, nNodes, clk = clock();
Alan Mishchenko committed
291
    // remove dangling nodes
Alan Mishchenko committed
292
    if ( (nNodes = Aig_ManCleanup( pAig )) )
Alan Mishchenko committed
293 294 295
    {
//        printf( "Removing %d nodes.\n", nNodes );
    }
Alan Mishchenko committed
296 297 298 299 300
    // create default parameters
    Dar_ManDefaultRwrParams( pPars );
    pPars->nCutsMax = nCutsMax;
    // create rewriting manager
    p = Dar_ManStart( pAig, pPars );
Alan Mishchenko committed
301
    // set elementary cuts for the PIs
Alan Mishchenko committed
302 303 304 305 306
//    Dar_ManCutsStart( p );
    Aig_MmFixedRestart( p->pMemCuts );
    Dar_ObjPrepareCuts( p, Aig_ManConst1(p->pAig) );
    Aig_ManForEachPi( pAig, pObj, i )
        Dar_ObjPrepareCuts( p, pObj );
Alan Mishchenko committed
307
    // compute cuts for each nodes in the topological order
Alan Mishchenko committed
308
    Aig_ManForEachNode( pAig, pObj, i )
Alan Mishchenko committed
309
        Dar_ObjComputeCuts( p, pObj );
Alan Mishchenko committed
310 311 312 313 314 315 316 317 318
    // print verbose stats
    if ( fVerbose )
    {
//        Aig_Obj_t * pObj;
        int nCuts, nCutsK;//, i;
        nCuts = Dar_ManCutCount( pAig, &nCutsK );
        printf( "Nodes = %6d. Total cuts = %6d. 4-input cuts = %6d.\n",
            Aig_ManObjNum(pAig), nCuts, nCutsK );
        printf( "Cut size = %2d. Truth size = %2d. Total mem = %5.2f Mb  ",
Alan Mishchenko committed
319
            (int)sizeof(Dar_Cut_t), (int)4, 1.0*Aig_MmFixedReadMemUsage(p->pMemCuts)/(1<<20) );
Alan Mishchenko committed
320
        ABC_PRT( "Runtime", clock() - clk );
Alan Mishchenko committed
321 322 323 324 325 326
/*
        Aig_ManForEachNode( pAig, pObj, i )
            if ( i % 300 == 0 )
                Dar_ObjCutPrint( pAig, pObj );
*/
    }
Alan Mishchenko committed
327
    // free the cuts
Alan Mishchenko committed
328 329
    pMemCuts = p->pMemCuts;
    p->pMemCuts = NULL;
Alan Mishchenko committed
330
//    Dar_ManCutsFree( p );
Alan Mishchenko committed
331 332 333
    // stop the rewriting manager
    Dar_ManStop( p );
    return pMemCuts;
Alan Mishchenko committed
334 335
}

Alan Mishchenko committed
336 337


Alan Mishchenko committed
338 339 340 341 342
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


343 344
ABC_NAMESPACE_IMPL_END