rwrEva.c 18.5 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 21
/**CFile****************************************************************

  FileName    [rwrDec.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [DAG-aware AIG rewriting package.]

  Synopsis    [Evaluation and decomposition procedures.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: rwrDec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

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

#include "rwr.h"
22 23
#include "bool/dec/dec.h"
#include "aig/ivy/ivy.h"
24 25 26

ABC_NAMESPACE_IMPL_START

Alan Mishchenko committed
27 28 29 30 31

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
32 33 34 35
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 );
static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut );
static int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
Alan Mishchenko committed
36 37

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
38
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
39 40 41 42 43 44 45 46 47 48 49
////////////////////////////////////////////////////////////////////////

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

  Synopsis    [Performs rewriting for one node.]

  Description [This procedure considers all the cuts computed for the node
  and tries to rewrite each of them using the "forest" of different AIG
  structures precomputed and stored in the RWR manager. 
  Determines the best rewriting and computes the gain in the number of AIG
  nodes in the final network. In the end, p->vFanins contains information 
Alan Mishchenko committed
50 51
  about the best cut that can be used for rewriting, while p->pGraph gives 
  the decomposition dag (represented using decomposition graph data structure).
Alan Mishchenko committed
52 53 54 55 56 57 58
  Returns gain in the number of nodes or -1 if node cannot be rewritten.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
59
int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable )
Alan Mishchenko committed
60
{
Alan Mishchenko committed
61
    int fVeryVerbose = 0;
Alan Mishchenko committed
62
    Dec_Graph_t * pGraph;
Alan Mishchenko committed
63
    Cut_Cut_t * pCut;//, * pTemp;
Alan Mishchenko committed
64
    Abc_Obj_t * pFanin;
Alan Mishchenko committed
65 66 67
    unsigned uPhase;
    unsigned uTruthBest = 0; // Suppress "might be used uninitialized"
    unsigned uTruth;
Alan Mishchenko committed
68
    char * pPerm;
Alan Mishchenko committed
69 70
    int Required, nNodesSaved;
    int nNodesSaveCur = -1; // Suppress "might be used uninitialized"
Alan Mishchenko committed
71
    int i, GainCur = -1, GainBest = -1;
72
    abctime clk, clk2;//, Counter;
Alan Mishchenko committed
73 74

    p->nNodesConsidered++;
Alan Mishchenko committed
75
    // get the required times
Alan Mishchenko committed
76 77
    Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY;

Alan Mishchenko committed
78
    // get the node's cuts
79
clk = Abc_Clock();
Alan Mishchenko committed
80
    pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 );
Alan Mishchenko committed
81
    assert( pCut != NULL );
82
p->timeCut += Abc_Clock() - clk;
Alan Mishchenko committed
83

Alan Mishchenko committed
84 85 86 87 88 89 90
//printf( " %d", Rwr_CutCountNumNodes(pNode, pCut) );
/*
    Counter = 0;
    for ( pTemp = pCut->pNext; pTemp; pTemp = pTemp->pNext )
        Counter++;
    printf( "%d ", Counter );
*/
Alan Mishchenko committed
91
    // go through the cuts
92
clk = Abc_Clock();
Alan Mishchenko committed
93
    for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
Alan Mishchenko committed
94
    {
Alan Mishchenko committed
95 96 97
        // consider only 4-input cuts
        if ( pCut->nLeaves < 4 )
            continue;
Alan Mishchenko committed
98 99
//            Cut_CutPrint( pCut, 0 ), printf( "\n" );

Alan Mishchenko committed
100
        // get the fanin permutation
Alan Mishchenko committed
101
        uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
Alan Mishchenko committed
102
        pPerm = p->pPerms4[ (int)p->pPerms[uTruth] ];
Alan Mishchenko committed
103
        uPhase = p->pPhases[uTruth];
Alan Mishchenko committed
104 105 106 107 108
        // 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++ )
        {
Alan Mishchenko committed
109
            pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[(int)pPerm[i]] );
Alan Mishchenko committed
110 111 112 113 114 115 116 117 118 119 120 121
            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++;

Alan Mishchenko committed
122 123
        {
            int Counter = 0;
124
            Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
Alan Mishchenko committed
125 126 127 128 129 130
                if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 )
                    Counter++;
            if ( Counter > 2 )
                continue;
        }

131
clk2 = Abc_Clock();
Alan Mishchenko committed
132 133
/*
        printf( "Considering: (" );
134
        Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
Alan Mishchenko committed
135 136 137
            printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) );
        printf( ")\n" );
*/
Alan Mishchenko committed
138
        // mark the fanin boundary 
139
        Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
Alan Mishchenko committed
140
            Abc_ObjRegular(pFanin)->vFanouts.nSize++;
Alan Mishchenko committed
141

Alan Mishchenko committed
142 143
        // label MFFC with current ID
        Abc_NtkIncrementTravId( pNode->pNtk );
Alan Mishchenko committed
144
        nNodesSaved = Abc_NodeMffcLabelAig( pNode );
Alan Mishchenko committed
145
        // unmark the fanin boundary
146
        Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
Alan Mishchenko committed
147
            Abc_ObjRegular(pFanin)->vFanouts.nSize--;
148
p->timeMffc += Abc_Clock() - clk2;
Alan Mishchenko committed
149

Alan Mishchenko committed
150
        // evaluate the cut
151
clk2 = Abc_Clock();
Alan Mishchenko committed
152
        pGraph = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, fPlaceEnable );
153
p->timeEval += Abc_Clock() - clk2;
Alan Mishchenko committed
154 155

        // check if the cut is better than the current best one
Alan Mishchenko committed
156
        if ( pGraph != NULL && GainBest < GainCur )
Alan Mishchenko committed
157
        {
Alan Mishchenko committed
158
            // save this form
Alan Mishchenko committed
159
            nNodesSaveCur = nNodesSaved;
Alan Mishchenko committed
160
            GainBest  = GainCur;
Alan Mishchenko committed
161
            p->pGraph  = pGraph;
Alan Mishchenko committed
162
            p->fCompl = ((uPhase & (1<<4)) > 0);
Alan Mishchenko committed
163
            uTruthBest = 0xFFFF & *Cut_CutReadTruth(pCut);
Alan Mishchenko committed
164
            // collect fanins in the
Alan Mishchenko committed
165
            Vec_PtrClear( p->vFanins );
166
            Vec_PtrForEachEntry( Abc_Obj_t *, p->vFaninsCur, pFanin, i )
Alan Mishchenko committed
167
                Vec_PtrPush( p->vFanins, pFanin );
Alan Mishchenko committed
168 169
        }
    }
170
p->timeRes += Abc_Clock() - clk;
Alan Mishchenko committed
171

Alan Mishchenko committed
172 173
    if ( GainBest == -1 )
        return -1;
Alan Mishchenko committed
174 175 176 177 178
/*
    if ( GainBest > 0 )
    {
        printf( "Class %d  ", p->pMap[uTruthBest] );
        printf( "Gain = %d. Node %d : ", GainBest, pNode->Id );
179
        Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
Alan Mishchenko committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
            printf( "%d ", Abc_ObjRegular(pFanin)->Id );
        Dec_GraphPrint( stdout, p->pGraph, NULL, NULL );
        printf( "\n" );
    }
*/

//    printf( "%d", nNodesSaveCur - GainBest );
/*
    if ( GainBest > 0 )
    {
        if ( Rwr_CutIsBoolean( pNode, p->vFanins ) )
            printf( "b" );
        else
        {
            printf( "Node %d : ", pNode->Id );
195
            Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
Alan Mishchenko committed
196 197 198 199 200 201 202 203 204 205 206 207
                printf( "%d ", Abc_ObjRegular(pFanin)->Id );
            printf( "a" );
        }
    }
*/
/*
    if ( GainBest > 0 )
        if ( p->fCompl )
            printf( "c" );
        else
            printf( "." );
*/
Alan Mishchenko committed
208

Alan Mishchenko committed
209
    // copy the leaves
210 211
    Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
        Dec_GraphNode((Dec_Graph_t *)p->pGraph, i)->pFunc = pFanin;
Alan Mishchenko committed
212 213
/*
    printf( "(" );
214
    Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanins, pFanin, i )
Alan Mishchenko committed
215 216 217 218
        printf( " %d", Abc_ObjRegular(pFanin)->vFanouts.nSize - 1 );
    printf( " )  " );
*/
//    printf( "%d ", Rwr_NodeGetDepth_rec( pNode, p->vFanins ) );
Alan Mishchenko committed
219 220 221

    p->nScores[p->pMap[uTruthBest]]++;
    p->nNodesGained += GainBest;
Alan Mishchenko committed
222 223 224 225
    if ( fUseZeros || GainBest > 0 )
    {
        p->nNodesRewritten++;
    }
Alan Mishchenko committed
226 227

    // report the progress
Alan Mishchenko committed
228
    if ( fVeryVerbose && GainBest > 0 )
Alan Mishchenko committed
229 230 231
    {
        printf( "Node %6s :   ", Abc_ObjName(pNode) );
        printf( "Fanins = %d. ", p->vFanins->nSize );
Alan Mishchenko committed
232 233 234
        printf( "Save = %d.  ", nNodesSaveCur );
        printf( "Add = %d.  ",  nNodesSaveCur-GainBest );
        printf( "GAIN = %d.  ", GainBest );
235
        printf( "Cone = %d.  ", p->pGraph? Dec_GraphNodeNum((Dec_Graph_t *)p->pGraph) : 0 );
Alan Mishchenko committed
236
        printf( "Class = %d.  ", p->pMap[uTruthBest] );
Alan Mishchenko committed
237 238 239
        printf( "\n" );
    }
    return GainBest;
Alan Mishchenko committed
240 241 242 243
}

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

Alan Mishchenko committed
244
  Synopsis    [Evaluates the cut.]
Alan Mishchenko committed
245 246 247 248 249 250 251 252

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
253
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 )
Alan Mishchenko committed
254
{
Alan Mishchenko committed
255
    extern int            Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
Alan Mishchenko committed
256
    Vec_Ptr_t * vSubgraphs;
Alan Mishchenko committed
257 258
    Dec_Graph_t * pGraphBest = NULL; // Suppress "might be used uninitialized"
    Dec_Graph_t * pGraphCur;
Alan Mishchenko committed
259 260
    Rwr_Node_t * pNode, * pFanin;
    int nNodesAdded, GainBest, i, k;
Alan Mishchenko committed
261 262
    unsigned uTruth;
    float CostBest;//, CostCur;
Alan Mishchenko committed
263
    // find the matching class of subgraphs
Alan Mishchenko committed
264
    uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
265
    vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
Alan Mishchenko committed
266
    p->nSubgraphs += vSubgraphs->nSize;
Alan Mishchenko committed
267
    // determine the best subgraph
Alan Mishchenko committed
268
    GainBest = -1;
Alan Mishchenko committed
269
    CostBest = ABC_INFINITY;
270
    Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, i )
Alan Mishchenko committed
271
    {
Alan Mishchenko committed
272 273 274
        // get the current graph
        pGraphCur = (Dec_Graph_t *)pNode->pNext;
        // copy the leaves
275
        Vec_PtrForEachEntry( Rwr_Node_t *, vFaninsCur, pFanin, k )
Alan Mishchenko committed
276
            Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
Alan Mishchenko committed
277
        // detect how many unlabeled nodes will be reused
Alan Mishchenko committed
278
        nNodesAdded = Dec_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax );
Alan Mishchenko committed
279 280 281
        if ( nNodesAdded == -1 )
            continue;
        assert( nNodesSaved >= nNodesAdded );
Alan Mishchenko committed
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
/*
        // evaluate the cut
        if ( fPlaceEnable )
        {
            extern float Abc_PlaceEvaluateCut( Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins );

            float Alpha = 0.5; // ???
            float PlaceCost;

            // get the placement cost of the cut
            PlaceCost = Abc_PlaceEvaluateCut( pRoot, vFaninsCur );

            // get the weigted cost of the cut
            CostCur = nNodesSaved - nNodesAdded + Alpha * PlaceCost;

            // do not allow uphill moves
            if ( nNodesSaved - nNodesAdded < 0 )
                continue;

            // decide what cut to use
            if ( CostBest > CostCur )
            {
                GainBest   = nNodesSaved - nNodesAdded; // pure node cost
                CostBest   = CostCur;                   // cost with placement
                pGraphBest = pGraphCur;                 // subgraph to be used for rewriting

                // score the graph
                if ( nNodesSaved - nNodesAdded > 0 )
                {
                    pNode->nScore++;
                    pNode->nGain += GainBest;
                    pNode->nAdded += nNodesAdded;
                }
            }
        }
        else
*/
Alan Mishchenko committed
319
        {
Alan Mishchenko committed
320 321 322 323 324 325 326 327 328 329 330 331 332 333
            // count the gain at this node
            if ( GainBest < nNodesSaved - nNodesAdded )
            {
                GainBest   = nNodesSaved - nNodesAdded;
                pGraphBest = pGraphCur;

                // score the graph
                if ( nNodesSaved - nNodesAdded > 0 )
                {
                    pNode->nScore++;
                    pNode->nGain += GainBest;
                    pNode->nAdded += nNodesAdded;
                }
            }
Alan Mishchenko committed
334
        }
Alan Mishchenko committed
335
    }
Alan Mishchenko committed
336 337
    if ( GainBest == -1 )
        return NULL;
Alan Mishchenko committed
338
    *pGainBest = GainBest;
Alan Mishchenko committed
339
    return pGraphBest;
Alan Mishchenko committed
340
}
Alan Mishchenko committed
341

Alan Mishchenko committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
/**Function*************************************************************

  Synopsis    [Checks the type of the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Rwr_CutIsBoolean_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves, int fMarkA )
{
    if ( Vec_PtrFind(vLeaves, pObj) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pObj)) >= 0 )
    {
        if ( fMarkA )
            pObj->fMarkA = 1;
        else
            pObj->fMarkB = 1;
        return;
    }
    assert( !Abc_ObjIsCi(pObj) );
    Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, fMarkA );
    Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, fMarkA );
}

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

  Synopsis    [Checks the type of the cut.]

  Description [Returns 1(0) if the cut is Boolean (algebraic).]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
{
    Abc_Obj_t * pTemp;
    int i, RetValue;
383
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pTemp, i )
Alan Mishchenko committed
384 385 386 387 388 389 390
    {
        pTemp = Abc_ObjRegular(pTemp);
        assert( !pTemp->fMarkA && !pTemp->fMarkB );
    }
    Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, 1 );
    Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, 0 );
    RetValue = 0;
391
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pTemp, i )
Alan Mishchenko committed
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
    {
        pTemp = Abc_ObjRegular(pTemp);
        RetValue |= pTemp->fMarkA && pTemp->fMarkB;
        pTemp->fMarkA = pTemp->fMarkB = 0;
    }
    return RetValue;
}


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

  Synopsis    [Count the nodes in the cut space of a node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Rwr_CutCountNumNodes_rec( Abc_Obj_t * pObj, Cut_Cut_t * pCut, Vec_Ptr_t * vNodes )
{
    int i;
    for ( i = 0; i < (int)pCut->nLeaves; i++ )
        if ( pCut->pLeaves[i] == pObj->Id )
        {
            // check if the node is collected
            if ( pObj->fMarkC == 0 )
            {
                pObj->fMarkC = 1;
                Vec_PtrPush( vNodes, pObj );
            }
            return;
        }
    assert( Abc_ObjIsNode(pObj) );
    // check if the node is collected
    if ( pObj->fMarkC == 0 )
    {
        pObj->fMarkC = 1;
        Vec_PtrPush( vNodes, pObj );
    }
    // traverse the fanins
    Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes );
    Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes );
}

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

  Synopsis    [Count the nodes in the cut space of a node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut )
{
    Vec_Ptr_t * vNodes;
    int i, Counter;
    // collect all nodes
    vNodes = Vec_PtrAlloc( 100 );
    for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
        Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes );
    // clean all nodes
458
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
Alan Mishchenko committed
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
        pObj->fMarkC = 0;
    // delete and return
    Counter = Vec_PtrSize(vNodes);
    Vec_PtrFree( vNodes );
    return Counter;
}


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

  Synopsis    [Returns depth of the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
{
    Abc_Obj_t * pLeaf;
    int i, Depth0, Depth1;
    if ( Abc_ObjIsCi(pObj) )
        return 0;
484
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pLeaf, i )
Alan Mishchenko committed
485 486 487 488
        if ( pObj == Abc_ObjRegular(pLeaf) )
            return 0;
    Depth0 = Rwr_NodeGetDepth_rec( Abc_ObjFanin0(pObj), vLeaves );
    Depth1 = Rwr_NodeGetDepth_rec( Abc_ObjFanin1(pObj), vLeaves );
489
    return 1 + Abc_MaxInt( Depth0, Depth1 );
Alan Mishchenko committed
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
}


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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Rwr_ScoresClean( Rwr_Man_t * p )
{
    Vec_Ptr_t * vSubgraphs;
    Rwr_Node_t * pNode;
    int i, k;
    for ( i = 0; i < p->vClasses->nSize; i++ )
    {
511
        vSubgraphs = Vec_VecEntry( p->vClasses, i );
512
        Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, k )
Alan Mishchenko committed
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
            pNode->nScore = pNode->nGain = pNode->nAdded = 0;
    }
}

static int Gains[222];

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Rwr_ScoresCompare( int * pNum1, int * pNum2 )
{
    if ( Gains[*pNum1] > Gains[*pNum2] )
        return -1;
    if ( Gains[*pNum1] < Gains[*pNum2] )
        return 1;
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Rwr_ScoresReport( Rwr_Man_t * p )
{
    extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
    int Perm[222];
    Vec_Ptr_t * vSubgraphs;
    Rwr_Node_t * pNode;
    int i, iNew, k;
    unsigned uTruth;
    // collect total gains
    assert( p->vClasses->nSize == 222 );
    for ( i = 0; i < p->vClasses->nSize; i++ )
    {
        Perm[i] = i;
        Gains[i] = 0;
564
        vSubgraphs = Vec_VecEntry( p->vClasses, i );
565
        Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, k )
Alan Mishchenko committed
566 567 568 569 570 571 572 573 574 575 576
            Gains[i] += pNode->nGain;
    }
    // sort the gains
    qsort( Perm, 222, sizeof(int), (int (*)(const void *, const void *))Rwr_ScoresCompare );

    // print classes
    for ( i = 0; i < p->vClasses->nSize; i++ )
    {
        iNew = Perm[i];
        if ( Gains[iNew] == 0 )
            break;
577
        vSubgraphs = Vec_VecEntry( p->vClasses, iNew );
Alan Mishchenko committed
578 579 580 581 582
        printf( "CLASS %3d: Subgr = %3d. Total gain = %6d.  ", iNew, Vec_PtrSize(vSubgraphs), Gains[iNew] );
        uTruth = (unsigned)p->pMapInv[iNew];
        Extra_PrintBinary( stdout, &uTruth, 16 );
        printf( "  " );
        Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[iNew] | ((unsigned)p->pMapInv[iNew] << 16) );
583
        Vec_PtrForEachEntry( Rwr_Node_t *, vSubgraphs, pNode, k )
Alan Mishchenko committed
584 585 586 587 588 589 590 591 592
        {
            if ( pNode->nScore == 0 )
                continue;
            printf( "    %2d: S=%5d. A=%5d. G=%6d. ", k, pNode->nScore, pNode->nAdded, pNode->nGain );
            Dec_GraphPrint( stdout, (Dec_Graph_t *)pNode->pNext, NULL, NULL );
        }
    }
}

Alan Mishchenko committed
593 594 595 596 597
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


598 599
ABC_NAMESPACE_IMPL_END