src/map/mapper/mapperCut.c File Reference

#include "mapperInt.h"
Include dependency graph for mapperCut.c:

Go to the source code of this file.

Data Structures

struct  Map_CutTableStrutct_t

Defines

#define MAP_CUTS_MAX_COMPUTE   1000
#define MAP_CUTS_MAX_USE   250
#define Map_ListForEachCut(pList, pCut)
#define Map_ListForEachCutSafe(pList, pCut, pCut2)

Typedefs

typedef struct
Map_CutTableStrutct_t 
Map_CutTable_t

Functions

static Map_Cut_tMap_CutCompute (Map_Man_t *p, Map_CutTable_t *pTable, Map_Node_t *pNode)
static void Map_CutFilter (Map_Man_t *p, Map_Node_t *pNode)
static Map_Cut_tMap_CutMergeLists (Map_Man_t *p, Map_CutTable_t *pTable, Map_Cut_t *pList1, Map_Cut_t *pList2, int fComp1, int fComp2)
static int Map_CutMergeTwo (Map_Cut_t *pCut1, Map_Cut_t *pCut2, Map_Node_t *ppNodes[], int nNodesMax)
static Map_Cut_tMap_CutUnionLists (Map_Cut_t *pList1, Map_Cut_t *pList2)
static int Map_CutBelongsToList (Map_Cut_t *pList, Map_Node_t *ppNodes[], int nNodes)
static void Map_CutListPrint (Map_Man_t *pMan, Map_Node_t *pRoot)
static void Map_CutListPrint2 (Map_Man_t *pMan, Map_Node_t *pRoot)
static void Map_CutPrint_ (Map_Man_t *pMan, Map_Cut_t *pCut, Map_Node_t *pRoot)
static Map_CutTable_tMap_CutTableStart (Map_Man_t *pMan)
static void Map_CutTableStop (Map_CutTable_t *p)
static unsigned Map_CutTableHash (Map_Node_t *ppNodes[], int nNodes)
static int Map_CutTableLookup (Map_CutTable_t *p, Map_Node_t *ppNodes[], int nNodes)
static Map_Cut_tMap_CutTableConsider (Map_Man_t *pMan, Map_CutTable_t *p, Map_Node_t *ppNodes[], int nNodes)
static void Map_CutTableRestart (Map_CutTable_t *p)
static Map_Cut_tMap_CutSortCuts (Map_Man_t *pMan, Map_CutTable_t *p, Map_Cut_t *pList)
static int Map_CutList2Array (Map_Cut_t **pArray, Map_Cut_t *pList)
static Map_Cut_tMap_CutArray2List (Map_Cut_t **pArray, int nCuts)
static unsigned Map_CutComputeTruth (Map_Man_t *p, Map_Cut_t *pCut, Map_Cut_t *pTemp0, Map_Cut_t *pTemp1, int fComp0, int fComp1)
void Map_MappingCuts (Map_Man_t *p)
Map_Cut_tMap_CutMergeLists2 (Map_Man_t *p, Map_CutTable_t *pTable, Map_Cut_t *pList1, Map_Cut_t *pList2, int fComp1, int fComp2)
int Map_MappingCountAllCuts (Map_Man_t *pMan)
int Map_CutSortCutsCompare (Map_Cut_t **pC1, Map_Cut_t **pC2)

Variables

static int s_HashPrimes [10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 }

Define Documentation

#define MAP_CUTS_MAX_COMPUTE   1000

CFile****************************************************************

FileName [mapperCut.c]

PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]

Synopsis [Generic technology mapping engine.]

Author [MVSIS Group]

Affiliation [UC Berkeley]

Date [Ver. 2.0. Started - June 1, 2004.]

Revision [

Id
mapperCut.c,v 1.12 2005/02/28 05:34:27 alanmi Exp

] DECLARATIONS ///

Definition at line 26 of file mapperCut.c.

#define MAP_CUTS_MAX_USE   250

Definition at line 28 of file mapperCut.c.

#define Map_ListForEachCut ( pList,
pCut   ) 
Value:
for ( pCut = pList;                                   \
          pCut;                                           \
          pCut = pCut->pNext )

Definition at line 71 of file mapperCut.c.

#define Map_ListForEachCutSafe ( pList,
pCut,
pCut2   ) 
Value:
for ( pCut = pList,                                   \
          pCut2 = pCut? pCut->pNext: NULL;                \
          pCut;                                           \
          pCut = pCut2,                                   \
          pCut2 = pCut? pCut->pNext: NULL )

Definition at line 75 of file mapperCut.c.


Typedef Documentation

Definition at line 31 of file mapperCut.c.


Function Documentation

Map_Cut_t * Map_CutArray2List ( Map_Cut_t **  pArray,
int  nCuts 
) [static]

Function*************************************************************

Synopsis [Moves the nodes from the array into the list.]

Description []

SideEffects []

SeeAlso []

Definition at line 1048 of file mapperCut.c.

01049 {
01050     Map_Cut_t * pListNew, ** ppListNew;
01051     int i;
01052     pListNew  = NULL;
01053     ppListNew = &pListNew;
01054     for ( i = 0; i < nCuts; i++ )
01055     {
01056         // connect these lists
01057         *ppListNew = pArray[i];
01058         ppListNew  = &pArray[i]->pNext;
01059     }
01060 //printf( "\n" );
01061 
01062     *ppListNew = NULL;
01063     return pListNew;
01064 }

int Map_CutBelongsToList ( Map_Cut_t pList,
Map_Node_t ppNodes[],
int  nNodes 
) [static]

Function*************************************************************

Synopsis [Checks whether the given cut belongs to the list.]

Description [This procedure takes most of the runtime in the cut computation.]

SideEffects []

SeeAlso []

Definition at line 664 of file mapperCut.c.

00665 {
00666     Map_Cut_t * pTemp;
00667     int i;
00668     for ( pTemp = pList; pTemp; pTemp = pTemp->pNext )
00669     {
00670         for ( i = 0; i < nNodes; i++ )
00671             if ( pTemp->ppLeaves[i] != ppNodes[i] )
00672                 break;
00673         if ( i == nNodes )
00674             return 1;
00675     }
00676     return 0;
00677 }

Map_Cut_t * Map_CutCompute ( Map_Man_t p,
Map_CutTable_t pTable,
Map_Node_t pNode 
) [static]

Function*************************************************************

Synopsis [Computes the cuts for one node.]

Description []

SideEffects []

SeeAlso []

Definition at line 172 of file mapperCut.c.

00173 {
00174     Map_Node_t * pTemp;
00175     Map_Cut_t * pList, * pList1, * pList2;
00176     Map_Cut_t * pCut;
00177 
00178     // if the cuts are computed return them
00179     if ( pNode->pCuts )
00180         return pNode->pCuts;
00181 
00182     // compute the cuts for the children
00183     pList1 = Map_Regular(pNode->p1)->pCuts;
00184     pList2 = Map_Regular(pNode->p2)->pCuts;
00185     // merge the lists
00186     pList = Map_CutMergeLists( p, pTable, pList1, pList2, 
00187         Map_IsComplement(pNode->p1), Map_IsComplement(pNode->p2) );
00188     // if there are functionally equivalent nodes, union them with this list
00189     assert( pList );
00190     // only add to the list of cuts if the node is a representative one
00191     if ( pNode->pRepr == NULL )
00192     {
00193         for ( pTemp = pNode->pNextE; pTemp; pTemp = pTemp->pNextE )
00194         {
00195             assert( pTemp->pCuts );
00196             pList = Map_CutUnionLists( pList, pTemp->pCuts );
00197             assert( pTemp->pCuts );
00198             pList = Map_CutSortCuts( p, pTable, pList );
00199         }
00200     }
00201     // add the new cut
00202     pCut = Map_CutAlloc( p );
00203     pCut->nLeaves = 1;
00204     pCut->ppLeaves[0] = pNode;
00205     pCut->uTruth = 0xAAAAAAAA;
00206     // append (it is important that the elementary cut is appended first)
00207     pCut->pNext = pList;
00208     // set at the node
00209     pNode->pCuts = pCut;
00210     // remove the dominated cuts
00211     Map_CutFilter( p, pNode );
00212     // set the phase correctly
00213     if ( pNode->pRepr && Map_NodeComparePhase(pNode, pNode->pRepr) )
00214     {
00215         Map_ListForEachCut( pNode->pCuts, pCut )
00216             pCut->Phase = 1;
00217     }
00218 /*
00219     { 
00220         int i, Counter = 0;;
00221         for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
00222             for ( i = 0; i < pCut->nLeaves; i++ )
00223                 Counter += (pCut->ppLeaves[i]->Level >= pNode->Level);
00224 //        if ( Counter )
00225 //            printf( " %d", Counter );
00226     }
00227 */
00228     return pCut;
00229 }

unsigned Map_CutComputeTruth ( Map_Man_t p,
Map_Cut_t pCut,
Map_Cut_t pTemp0,
Map_Cut_t pTemp1,
int  fComp0,
int  fComp1 
) [static]

Function*************************************************************

Synopsis [Computes the truth table of the 5-input cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 1078 of file mapperCut.c.

01079 {
01080     static unsigned ** pPerms53 = NULL;
01081     static unsigned ** pPerms54 = NULL;
01082 
01083     unsigned uPhase, uTruth, uTruth0, uTruth1;
01084     int i, k;
01085 
01086     if ( pPerms53 == NULL )
01087     {
01088         pPerms53 = (unsigned **)Extra_TruthPerm53();
01089         pPerms54 = (unsigned **)Extra_TruthPerm54();
01090     }
01091 
01092     // find the mapping from the old nodes to the new
01093     if ( pTemp0->nLeaves == pCut->nLeaves )
01094         uTruth0 = pTemp0->uTruth;
01095     else
01096     {
01097         assert( pTemp0->nLeaves < pCut->nLeaves );
01098         uPhase = 0;
01099         for ( i = 0; i < (int)pTemp0->nLeaves; i++ )
01100         {
01101             for ( k = 0; k < pCut->nLeaves; k++ )
01102                 if ( pTemp0->ppLeaves[i] == pCut->ppLeaves[k] )
01103                     break;
01104             uPhase |= (1 << k);
01105         }
01106         assert( uPhase < 32 );
01107         if ( pTemp0->nLeaves == 4 )
01108         {
01109             if ( uPhase == 31-16 ) // 01111
01110                 uTruth0 = pTemp0->uTruth;
01111             else if ( uPhase == 31-8 ) // 10111
01112                 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][0];
01113             else if ( uPhase == 31-4 ) // 11011
01114                 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][1];
01115             else if ( uPhase == 31-2 ) // 11101
01116                 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][2];
01117             else if ( uPhase == 31-1 ) // 11110
01118                 uTruth0 = pPerms54[pTemp0->uTruth & 0xFFFF][3];
01119             else
01120                 assert( 0 );
01121         }
01122         else
01123             uTruth0 = pPerms53[pTemp0->uTruth & 0xFF][uPhase];
01124     }
01125     uTruth0 = fComp0? ~uTruth0: uTruth0;
01126 
01127     // find the mapping from the old nodes to the new
01128     if ( pTemp1->nLeaves == pCut->nLeaves )
01129         uTruth1 = pTemp1->uTruth;
01130     else
01131     {
01132         assert( pTemp1->nLeaves < pCut->nLeaves );
01133         uPhase = 0;
01134         for ( i = 0; i < (int)pTemp1->nLeaves; i++ )
01135         {
01136             for ( k = 0; k < pCut->nLeaves; k++ )
01137                 if ( pTemp1->ppLeaves[i] == pCut->ppLeaves[k] )
01138                     break;
01139             uPhase |= (1 << k);
01140         }
01141         assert( uPhase < 32 );
01142         if ( pTemp1->nLeaves == 4 )
01143         {
01144             if ( uPhase == 31-16 ) // 01111
01145                 uTruth1 = pTemp1->uTruth;
01146             else if ( uPhase == 31-8 ) // 10111
01147                 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][0];
01148             else if ( uPhase == 31-4 ) // 11011
01149                 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][1];
01150             else if ( uPhase == 31-2 ) // 11101
01151                 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][2];
01152             else if ( uPhase == 31-1 ) // 11110
01153                 uTruth1 = pPerms54[pTemp1->uTruth & 0xFFFF][3];
01154             else
01155                 assert( 0 );
01156         }
01157         else
01158             uTruth1 = pPerms53[pTemp1->uTruth & 0xFF][uPhase];
01159     }
01160     uTruth1 = fComp1? ~uTruth1: uTruth1;
01161     uTruth  = uTruth0 & uTruth1;
01162     return uTruth;
01163 }

void Map_CutFilter ( Map_Man_t p,
Map_Node_t pNode 
) [static]

Function*************************************************************

Synopsis [Filter the cuts using dominance.]

Description []

SideEffects []

SeeAlso []

Definition at line 242 of file mapperCut.c.

00243 { 
00244     Map_Cut_t * pTemp, * pPrev, * pCut, * pCut2;
00245     int i, k, Counter;
00246 
00247     Counter = 0;
00248     pPrev = pNode->pCuts;
00249     Map_ListForEachCutSafe( pNode->pCuts->pNext, pCut, pCut2 )
00250     {
00251         // go through all the previous cuts up to pCut
00252         for ( pTemp = pNode->pCuts->pNext; pTemp != pCut; pTemp = pTemp->pNext )
00253         {
00254             // check if every node in pTemp is contained in pCut
00255             for ( i = 0; i < pTemp->nLeaves; i++ )
00256             {
00257                 for ( k = 0; k < pCut->nLeaves; k++ )
00258                     if ( pTemp->ppLeaves[i] == pCut->ppLeaves[k] )
00259                         break;
00260                 if ( k == pCut->nLeaves ) // node i in pTemp is not contained in pCut
00261                     break;
00262             }
00263             if ( i == pTemp->nLeaves ) // every node in pTemp is contained in pCut
00264             {
00265                 Counter++;
00266                 break;
00267             }
00268         }
00269         if ( pTemp != pCut ) // pTemp contain pCut
00270         {
00271             pPrev->pNext = pCut->pNext;  // skip pCut
00272             // recycle pCut
00273             Map_CutFree( p, pCut );
00274         }
00275         else 
00276             pPrev = pCut; 
00277     }
00278 //  printf( "Dominated = %3d. \n", Counter );
00279 }

int Map_CutList2Array ( Map_Cut_t **  pArray,
Map_Cut_t pList 
) [static]

Function*************************************************************

Synopsis [Moves the nodes from the list into the array.]

Description []

SideEffects []

SeeAlso []

Definition at line 1029 of file mapperCut.c.

01030 {
01031     int i;
01032     for ( i = 0; pList; pList = pList->pNext, i++ )
01033         pArray[i] = pList;
01034     return i;
01035 }

void Map_CutListPrint ( Map_Man_t pMan,
Map_Node_t pRoot 
) [static]

Function*************************************************************

Synopsis [Prints the cuts in the list.]

Description []

SideEffects []

SeeAlso []

Definition at line 736 of file mapperCut.c.

00737 {
00738     Map_Cut_t * pTemp;
00739     int Counter;
00740     for ( Counter = 0, pTemp = pRoot->pCuts; pTemp; pTemp = pTemp->pNext, Counter++ )
00741     {
00742         printf( "%2d : ", Counter + 1 );
00743         Map_CutPrint_( pMan, pTemp, pRoot );
00744     }
00745 }

void Map_CutListPrint2 ( Map_Man_t pMan,
Map_Node_t pRoot 
) [static]

Function*************************************************************

Synopsis [Prints the cuts in the list.]

Description []

SideEffects []

SeeAlso []

Definition at line 758 of file mapperCut.c.

00759 {
00760     Map_Cut_t * pTemp;
00761     int Counter;
00762     for ( Counter = 0, pTemp = pRoot->pCuts; pTemp; pTemp = pTemp->pNext, Counter++ )
00763     {
00764         printf( "%2d : ", Counter + 1 );
00765         Map_CutPrint_( pMan, pTemp, pRoot );
00766     }
00767 }

Map_Cut_t * Map_CutMergeLists ( Map_Man_t p,
Map_CutTable_t pTable,
Map_Cut_t pList1,
Map_Cut_t pList2,
int  fComp1,
int  fComp2 
) [static]

Function*************************************************************

Synopsis [Merges two lists of cuts.]

Description []

SideEffects []

SeeAlso []

Definition at line 292 of file mapperCut.c.

00294 {
00295     Map_Node_t * ppNodes[6];
00296     Map_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL };
00297     Map_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2;
00298     int nNodes, Counter, i;
00299     Map_Cut_t ** ppArray1, ** ppArray2, ** ppArray3;
00300     int nCuts1, nCuts2, nCuts3, k, fComp3;
00301 
00302     ppArray1 = pTable->pCuts1;
00303     ppArray2 = pTable->pCuts2;
00304     nCuts1 = Map_CutList2Array( ppArray1, pList1 );
00305     nCuts2 = Map_CutList2Array( ppArray2, pList2 );
00306     // swap the lists based on their length
00307     if ( nCuts1 > nCuts2 )
00308     {
00309          ppArray3 = ppArray1;
00310          ppArray1 = ppArray2;
00311          ppArray2 = ppArray3;
00312 
00313          nCuts3 = nCuts1;
00314          nCuts1 = nCuts2;
00315          nCuts2 = nCuts3;
00316 
00317          fComp3 = fComp1;
00318          fComp1 = fComp2;
00319          fComp2 = fComp3;
00320     }
00321     // pList1 is shorter or equal length compared to pList2
00322  
00323     // prepare the manager for the cut computation
00324     Map_CutTableRestart( pTable );
00325     // go through the cut pairs
00326     Counter = 0;
00327 //    for ( pTemp1 = pList1; pTemp1; pTemp1 = fPivot1? NULL: pTemp1->pNext )
00328 //        for ( pTemp2 = pList2; pTemp2; pTemp2 = fPivot2? NULL: pTemp2->pNext )
00329     for ( i = 0; i < nCuts1; i++ )
00330     {
00331         for ( k = 0; k <= i; k++ )
00332         {
00333             pTemp1 = ppArray1[i];
00334             pTemp2 = ppArray2[k];
00335 
00336             if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
00337             {
00338                 if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
00339                     continue;
00340                 if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
00341                     continue;
00342             }
00343 
00344             // check if k-feasible cut exists
00345             nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00346             if ( nNodes == 0 )
00347                 continue;
00348             // consider the cut for possible addition to the set of new cuts
00349             pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00350             if ( pCut == NULL )
00351                 continue;
00352             // add data to the cut
00353             pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00354             pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00355 //            if ( p->nVarsMax == 5 )
00356 //            pCut->uTruth = Map_CutComputeTruth( p, pCut, pTemp1, pTemp2, fComp1, fComp2 );
00357             // add it to the corresponding list
00358             pCut->pNext = pLists[pCut->nLeaves];
00359             pLists[pCut->nLeaves] = pCut;
00360             // count this cut and quit if limit is reached
00361             Counter++;
00362             if ( Counter == MAP_CUTS_MAX_COMPUTE )
00363                 goto QUITS;
00364         }
00365         for ( k = 0; k < i; k++ )
00366         {
00367             pTemp1 = ppArray1[k];
00368             pTemp2 = ppArray2[i];
00369 
00370             if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
00371             {
00372                 if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
00373                     continue;
00374                 if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
00375                     continue;
00376             }
00377 
00378             // check if k-feasible cut exists
00379             nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00380             if ( nNodes == 0 )
00381                 continue;
00382             // consider the cut for possible addition to the set of new cuts
00383             pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00384             if ( pCut == NULL )
00385                 continue;
00386             // add data to the cut
00387             pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00388             pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00389 //            if ( p->nVarsMax == 5 )
00390 //            pCut->uTruth = Map_CutComputeTruth( p, pCut, pTemp1, pTemp2, fComp1, fComp2 );
00391             // add it to the corresponding list
00392             pCut->pNext = pLists[pCut->nLeaves];
00393             pLists[pCut->nLeaves] = pCut;
00394             // count this cut and quit if limit is reached
00395             Counter++;
00396             if ( Counter == MAP_CUTS_MAX_COMPUTE )
00397                 goto QUITS;
00398         }
00399     }
00400     // consider the rest of them
00401     for ( i = nCuts1; i < nCuts2; i++ )
00402         for ( k = 0; k < nCuts1; k++ )
00403         {
00404             pTemp1 = ppArray1[k];
00405             pTemp2 = ppArray2[i];
00406 
00407             if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
00408             {
00409                 if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
00410                     continue;
00411                 if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
00412                     continue;
00413             }
00414 
00415             // check if k-feasible cut exists
00416             nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00417             if ( nNodes == 0 )
00418                 continue;
00419             // consider the cut for possible addition to the set of new cuts
00420             pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00421             if ( pCut == NULL )
00422                 continue;
00423             // add data to the cut
00424             pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00425             pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00426 //            if ( p->nVarsMax == 5 )
00427 //            pCut->uTruth = Map_CutComputeTruth( p, pCut, pTemp1, pTemp2, fComp1, fComp2 );
00428             // add it to the corresponding list
00429             pCut->pNext = pLists[pCut->nLeaves];
00430             pLists[pCut->nLeaves] = pCut;
00431             // count this cut and quit if limit is reached
00432             Counter++;
00433             if ( Counter == MAP_CUTS_MAX_COMPUTE )
00434                 goto QUITS;
00435         }
00436 QUITS :
00437     // combine all the lists into one
00438     pListNew  = NULL;
00439     ppListNew = &pListNew;
00440     for ( i = 1; i <= p->nVarsMax; i++ )
00441     {
00442         if ( pLists[i] == NULL )
00443             continue;
00444         // find the last entry
00445         for ( pPrev = pLists[i], pCut = pPrev->pNext; pCut; 
00446             pPrev = pCut, pCut = pCut->pNext );
00447         // connect these lists
00448         *ppListNew = pLists[i];
00449         ppListNew  = &pPrev->pNext;
00450     }
00451     *ppListNew = NULL;
00452     // soft the cuts by arrival times and use only the first MAP_CUTS_MAX_USE
00453     pListNew = Map_CutSortCuts( p, pTable, pListNew );
00454     return pListNew;
00455 }

Map_Cut_t* Map_CutMergeLists2 ( Map_Man_t p,
Map_CutTable_t pTable,
Map_Cut_t pList1,
Map_Cut_t pList2,
int  fComp1,
int  fComp2 
)

Function*************************************************************

Synopsis [Merges two lists of cuts.]

Description []

SideEffects []

SeeAlso []

Definition at line 469 of file mapperCut.c.

00471 {
00472     Map_Node_t * ppNodes[6];
00473     Map_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL };
00474     Map_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2;
00475     int nNodes, Counter, i;
00476 
00477     // prepare the manager for the cut computation
00478     Map_CutTableRestart( pTable );
00479     // go through the cut pairs
00480     Counter = 0;
00481     for ( pTemp1 = pList1; pTemp1; pTemp1 = pTemp1->pNext )
00482         for ( pTemp2 = pList2; pTemp2; pTemp2 = pTemp2->pNext )
00483         {
00484             // check if k-feasible cut exists
00485             nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
00486             if ( nNodes == 0 )
00487                 continue;
00488             // consider the cut for possible addition to the set of new cuts
00489             pCut = Map_CutTableConsider( p, pTable, ppNodes, nNodes );
00490             if ( pCut == NULL )
00491                 continue;
00492             // add data to the cut
00493             pCut->pOne = Map_CutNotCond( pTemp1, fComp1 );
00494             pCut->pTwo = Map_CutNotCond( pTemp2, fComp2 );
00495             // add it to the corresponding list
00496             pCut->pNext = pLists[pCut->nLeaves];
00497             pLists[pCut->nLeaves] = pCut;
00498             // count this cut and quit if limit is reached
00499             Counter++;
00500             if ( Counter == MAP_CUTS_MAX_COMPUTE )
00501                 goto QUITS;
00502         }
00503 QUITS :
00504     // combine all the lists into one
00505     pListNew  = NULL;
00506     ppListNew = &pListNew;
00507     for ( i = 1; i <= p->nVarsMax; i++ )
00508     {
00509         if ( pLists[i] == NULL )
00510             continue;
00511         // find the last entry
00512         for ( pPrev = pLists[i], pCut = pPrev->pNext; pCut; 
00513             pPrev = pCut, pCut = pCut->pNext );
00514         // connect these lists
00515         *ppListNew = pLists[i];
00516         ppListNew  = &pPrev->pNext;
00517     }
00518     *ppListNew = NULL;
00519     // soft the cuts by arrival times and use only the first MAP_CUTS_MAX_USE
00520     pListNew = Map_CutSortCuts( p, pTable, pListNew );
00521     return pListNew;
00522 }

int Map_CutMergeTwo ( Map_Cut_t pCut1,
Map_Cut_t pCut2,
Map_Node_t ppNodes[],
int  nNodesMax 
) [static]

Function*************************************************************

Synopsis [Merges two cuts.]

Description [Returns the number of nodes in the resulting cut, or 0 if the cut is infeasible. Returns the resulting nodes in the array ppNodes[].]

SideEffects []

SeeAlso []

Definition at line 536 of file mapperCut.c.

00537 {
00538     Map_Node_t * pNodeTemp;
00539     int nTotal, i, k, min, fMismatch;
00540 
00541     // check the special case when at least of the cuts is the largest
00542     if ( pCut1->nLeaves == nNodesMax )
00543     {
00544         if ( pCut2->nLeaves == nNodesMax )
00545         {
00546             // return 0 if the cuts are different
00547             for ( i = 0; i < nNodesMax; i++ )
00548                 if ( pCut1->ppLeaves[i] != pCut2->ppLeaves[i] )
00549                     return 0;
00550             // return nNodesMax if they are the same
00551             for ( i = 0; i < nNodesMax; i++ )
00552                 ppNodes[i] = pCut1->ppLeaves[i];
00553             return nNodesMax;
00554         }
00555         else if ( pCut2->nLeaves == nNodesMax - 1 ) 
00556         {
00557             // return 0 if the cuts are different
00558             fMismatch = 0;
00559             for ( i = 0; i < nNodesMax; i++ )
00560                 if ( pCut1->ppLeaves[i] != pCut2->ppLeaves[i - fMismatch] )
00561                 {
00562                     if ( fMismatch == 1 )
00563                         return 0;
00564                     fMismatch = 1;
00565                 }
00566             // return nNodesMax if they are the same
00567             for ( i = 0; i < nNodesMax; i++ )
00568                 ppNodes[i] = pCut1->ppLeaves[i];
00569             return nNodesMax;
00570         }
00571     }
00572     else if ( pCut1->nLeaves == nNodesMax - 1 && pCut2->nLeaves == nNodesMax )
00573     {
00574         // return 0 if the cuts are different
00575         fMismatch = 0;
00576         for ( i = 0; i < nNodesMax; i++ )
00577             if ( pCut1->ppLeaves[i - fMismatch] != pCut2->ppLeaves[i] )
00578             {
00579                 if ( fMismatch == 1 )
00580                     return 0;
00581                 fMismatch = 1;
00582             }
00583         // return nNodesMax if they are the same
00584         for ( i = 0; i < nNodesMax; i++ )
00585             ppNodes[i] = pCut2->ppLeaves[i];
00586         return nNodesMax;
00587     }
00588 
00589     // count the number of unique entries in pCut2
00590     nTotal = pCut1->nLeaves;
00591     for ( i = 0; i < pCut2->nLeaves; i++ )
00592     {
00593         // try to find this entry among the leaves of pCut1
00594         for ( k = 0; k < pCut1->nLeaves; k++ )
00595             if ( pCut2->ppLeaves[i] == pCut1->ppLeaves[k] )
00596                 break;
00597         if ( k < pCut1->nLeaves ) // found
00598             continue;
00599         // we found a new entry to add
00600         if ( nTotal == nNodesMax )
00601             return 0;
00602         ppNodes[nTotal++] = pCut2->ppLeaves[i];
00603     }
00604     // we know that the feasible cut exists
00605 
00606     // add the starting entries
00607     for ( k = 0; k < pCut1->nLeaves; k++ )
00608         ppNodes[k] = pCut1->ppLeaves[k];
00609 
00610     // selection-sort the entries
00611     for ( i = 0; i < nTotal - 1; i++ )
00612     {
00613         min = i;
00614         for ( k = i+1; k < nTotal; k++ )
00615 //            if ( ppNodes[k] < ppNodes[min] ) // reported bug fix (non-determinism!)
00616             if ( ppNodes[k]->Num < ppNodes[min]->Num )
00617                 min = k;
00618         pNodeTemp    = ppNodes[i];
00619         ppNodes[i]   = ppNodes[min];
00620         ppNodes[min] = pNodeTemp;
00621     }
00622 
00623     return nTotal;
00624 }

void Map_CutPrint_ ( Map_Man_t pMan,
Map_Cut_t pCut,
Map_Node_t pRoot 
) [static]

Function*************************************************************

Synopsis [Prints the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 780 of file mapperCut.c.

00781 {
00782     int i;
00783     printf( "(%3d)  {", pRoot->Num );
00784     for ( i = 0; i < pMan->nVarsMax; i++ )
00785         if ( pCut->ppLeaves[i] )
00786             printf( " %3d", pCut->ppLeaves[i]->Num );
00787     printf( " }\n" );
00788 }

Map_Cut_t * Map_CutSortCuts ( Map_Man_t pMan,
Map_CutTable_t p,
Map_Cut_t pList 
) [static]

Function*************************************************************

Synopsis [Sorts the cuts by average arrival time.]

Description []

SideEffects []

SeeAlso []

Definition at line 992 of file mapperCut.c.

00993 {
00994     Map_Cut_t * pListNew;
00995     int nCuts, i;
00996 //    int clk;
00997     // move the cuts from the list into the array
00998     nCuts = Map_CutList2Array( p->pCuts1, pList );
00999     assert( nCuts <= MAP_CUTS_MAX_COMPUTE );
01000     // sort the cuts
01001 //clk = clock();
01002     qsort( (void *)p->pCuts1, nCuts, sizeof(Map_Cut_t *), 
01003             (int (*)(const void *, const void *)) Map_CutSortCutsCompare );
01004 //pMan->time2 += clock() - clk;
01005     // move them back into the list
01006     if ( nCuts > MAP_CUTS_MAX_USE - 1 )
01007     {
01008         // free the remaining cuts
01009         for ( i = MAP_CUTS_MAX_USE - 1; i < nCuts; i++ )
01010             Extra_MmFixedEntryRecycle( pMan->mmCuts, (char *)p->pCuts1[i] );
01011         // update the number of cuts
01012         nCuts = MAP_CUTS_MAX_USE - 1;
01013     }
01014     pListNew = Map_CutArray2List( p->pCuts1, nCuts );
01015     return pListNew;
01016 }

int Map_CutSortCutsCompare ( Map_Cut_t **  pC1,
Map_Cut_t **  pC2 
)

Function*************************************************************

Synopsis [Compares the cuts by the number of leaves and then by delay.]

Description []

SideEffects []

SeeAlso []

Definition at line 972 of file mapperCut.c.

00973 {
00974     if ( (*pC1)->nLeaves < (*pC2)->nLeaves )
00975         return -1;
00976     if ( (*pC1)->nLeaves > (*pC2)->nLeaves )
00977         return 1;
00978     return 0;
00979 }

Map_Cut_t * Map_CutTableConsider ( Map_Man_t pMan,
Map_CutTable_t p,
Map_Node_t ppNodes[],
int  nNodes 
) [static]

Function*************************************************************

Synopsis [Starts the hash table to canonicize cuts.]

Description [Considers addition of the cut to the hash table.]

SideEffects []

SeeAlso []

Definition at line 911 of file mapperCut.c.

00912 {
00913     Map_Cut_t * pCut;
00914     int Place, i;
00915 //    int clk;
00916     // check the cut
00917     Place = Map_CutTableLookup( p, ppNodes, nNodes );
00918     if ( Place == -1 )
00919         return NULL;
00920     assert( nNodes > 0 );
00921     // create the new cut
00922 //clk = clock();
00923     pCut = Map_CutAlloc( pMan );
00924 //pMan->time1 += clock() - clk;
00925     pCut->nLeaves = nNodes;
00926     for ( i = 0; i < nNodes; i++ )
00927         pCut->ppLeaves[i] = ppNodes[i];
00928     // add the cut to the table
00929     assert( p->pBins[Place] == NULL );
00930     p->pBins[Place] = pCut;
00931     // add the cut to the new list
00932     p->pCuts[ p->nCuts++ ] = Place;
00933     return pCut;
00934 }

unsigned Map_CutTableHash ( Map_Node_t ppNodes[],
int  nNodes 
) [static]

Function*************************************************************

Synopsis [Computes the hash value of the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 856 of file mapperCut.c.

00857 {
00858     unsigned uRes;
00859     int i;
00860     uRes = 0;
00861     for ( i = 0; i < nNodes; i++ )
00862         uRes += s_HashPrimes[i] * ppNodes[i]->Num;
00863     return uRes;
00864 }

int Map_CutTableLookup ( Map_CutTable_t p,
Map_Node_t ppNodes[],
int  nNodes 
) [static]

Function*************************************************************

Synopsis [Looks up the table for the available cut.]

Description [Returns -1 if the same cut is found. Returns the index of the cell where the cut should be added, if it does not exist.]

SideEffects []

SeeAlso []

Definition at line 878 of file mapperCut.c.

00879 {
00880     Map_Cut_t * pCut;
00881     unsigned Key;
00882     int b, i;
00883 
00884     Key = Map_CutTableHash(ppNodes, nNodes) % p->nBins; 
00885     for ( b = Key; p->pBins[b]; b = (b+1) % p->nBins )
00886     {
00887         pCut = p->pBins[b];
00888         if ( pCut->nLeaves != nNodes )
00889             continue;
00890         for ( i = 0; i < nNodes; i++ )
00891             if ( pCut->ppLeaves[i] != ppNodes[i] )
00892                 break;
00893         if ( i == nNodes )
00894             return -1;
00895     }
00896     return b;
00897 }

void Map_CutTableRestart ( Map_CutTable_t p  )  [static]

Function*************************************************************

Synopsis [Prepares the table to be used with other cuts.]

Description [Restarts the table by cleaning the info about cuts stored when the previous node was considered.]

SideEffects []

SeeAlso []

Definition at line 948 of file mapperCut.c.

00949 {
00950     int i;
00951     for ( i = 0; i < p->nCuts; i++ )
00952     {
00953         assert( p->pBins[ p->pCuts[i] ] );
00954         p->pBins[ p->pCuts[i] ] = NULL;
00955     }
00956     p->nCuts = 0;
00957 }

Map_CutTable_t * Map_CutTableStart ( Map_Man_t pMan  )  [static]

Function*************************************************************

Synopsis [Starts the hash table to canonicize cuts.]

Description []

SideEffects []

SeeAlso []

Definition at line 808 of file mapperCut.c.

00809 {
00810     Map_CutTable_t * p;
00811     // allocate the table
00812     p = ALLOC( Map_CutTable_t, 1 );
00813     memset( p, 0, sizeof(Map_CutTable_t) );
00814     p->nBins = Cudd_Prime( 10 * MAP_CUTS_MAX_COMPUTE );
00815     p->pBins = ALLOC( Map_Cut_t *, p->nBins );
00816     memset( p->pBins, 0, sizeof(Map_Cut_t *) * p->nBins );
00817     p->pCuts = ALLOC( int, 2 * MAP_CUTS_MAX_COMPUTE );
00818     p->pArray = ALLOC( Map_Cut_t *, 2 * MAP_CUTS_MAX_COMPUTE );
00819     p->pCuts1 = ALLOC( Map_Cut_t *, 2 * MAP_CUTS_MAX_COMPUTE );
00820     p->pCuts2 = ALLOC( Map_Cut_t *, 2 * MAP_CUTS_MAX_COMPUTE );
00821     return p;
00822 }

void Map_CutTableStop ( Map_CutTable_t p  )  [static]

Function*************************************************************

Synopsis [Stops the hash table.]

Description []

SideEffects []

SeeAlso []

Definition at line 835 of file mapperCut.c.

00836 {
00837     free( p->pCuts1 );
00838     free( p->pCuts2 );
00839     free( p->pArray );
00840     free( p->pBins );
00841     free( p->pCuts );
00842     free( p );
00843 }

Map_Cut_t * Map_CutUnionLists ( Map_Cut_t pList1,
Map_Cut_t pList2 
) [static]

Function*************************************************************

Synopsis [Computes the union of the two lists of cuts.]

Description []

SideEffects []

SeeAlso []

Definition at line 637 of file mapperCut.c.

00638 {
00639     Map_Cut_t * pTemp, * pRoot;
00640     // find the last cut in the first list
00641     pRoot = pList1;
00642     Map_ListForEachCut( pList1, pTemp )
00643         pRoot = pTemp;
00644     // attach the non-trival part of the second cut to the end of the first
00645     assert( pRoot->pNext == NULL );
00646     pRoot->pNext = pList2->pNext;   
00647     pList2->pNext = NULL;
00648     return pList1;
00649 }

int Map_MappingCountAllCuts ( Map_Man_t pMan  ) 

Function*************************************************************

Synopsis [Counts all the cuts.]

Description []

SideEffects []

SeeAlso []

Definition at line 690 of file mapperCut.c.

00691 {
00692     Map_Node_t * pNode;
00693     Map_Cut_t * pCut;
00694     int i, nCuts;
00695 //    int nCuts55 = 0, nCuts5x = 0, nCuts4x = 0, nCuts3x = 0;
00696 //    int pCounts[7] = {0};
00697     nCuts = 0;
00698     for ( i = 0; i < pMan->nBins; i++ )
00699         for ( pNode = pMan->pBins[i]; pNode; pNode = pNode->pNext )
00700             for ( pCut = pNode->pCuts; pCut; pCut = pCut->pNext )
00701                 if ( pCut->nLeaves > 1 ) // skip the elementary cuts
00702                 {
00703                     nCuts++;
00704 /*
00705                     if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 && Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
00706                         nCuts55++;
00707                     if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 || Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
00708                         nCuts5x++;
00709                     else if ( Map_CutRegular(pCut->pOne)->nLeaves == 4 || Map_CutRegular(pCut->pTwo)->nLeaves == 4 )
00710                         nCuts4x++;
00711                     else if ( Map_CutRegular(pCut->pOne)->nLeaves == 3 || Map_CutRegular(pCut->pTwo)->nLeaves == 3 )
00712                         nCuts3x++;
00713 */                  
00714 //                    pCounts[ Map_CutRegular(pCut->pOne)->nLeaves ]++;
00715 //                    pCounts[ Map_CutRegular(pCut->pTwo)->nLeaves ]++;
00716                 }
00717 //    printf( "Total cuts = %6d. 55 = %6d. 5x = %6d. 4x = %6d. 3x = %6d.\n", nCuts, nCuts55, nCuts5x, nCuts4x, nCuts3x );
00718 
00719 //    printf( "Total cuts = %6d. 6= %6d. 5= %6d. 4= %6d. 3= %6d. 2= %6d. 1= %6d.\n", 
00720 //        nCuts, pCounts[6], pCounts[5], pCounts[4], pCounts[3], pCounts[2], pCounts[1] );
00721     return nCuts;
00722 }

void Map_MappingCuts ( Map_Man_t p  ) 

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Computes the cuts for each node in the object graph.]

Description [The cuts are computed in one sweep over the mapping graph. First, the elementary cuts, which include the node itself, are assigned to the PI nodes. The internal nodes are considered in the DFS order. Each node is two-input AND-gate. So to compute the cuts at a node, we need to merge the sets of cuts of its two predecessors. The merged set contains only unique cuts with the number of inputs equal to k or less. Finally, the elementary cut, composed of the node itself, is added to the set of cuts for the node.

This procedure is pretty fast for 5-feasible cuts, but it dramatically slows down on some "dense" networks when computing 6-feasible cuts. The problem is that there are too many cuts in this case. We should think how to heuristically trim the number of cuts in such cases, to have reasonable runtime.]

SideEffects []

SeeAlso []

Definition at line 110 of file mapperCut.c.

00111 {
00112     ProgressBar * pProgress;
00113     Map_CutTable_t * pTable;
00114     Map_Node_t * pNode;
00115     Map_Cut_t * pCut;
00116     int nCuts, nNodes, i;
00117     int clk = clock();
00118     // set the elementary cuts for the PI variables
00119     assert( p->nVarsMax > 1 && p->nVarsMax < 7 );
00120     for ( i = 0; i < p->nInputs; i++ )
00121     {
00122         pCut = Map_CutAlloc( p );
00123         pCut->nLeaves = 1;
00124         pCut->ppLeaves[0] = p->pInputs[i];
00125         p->pInputs[i]->pCuts   = pCut;
00126         p->pInputs[i]->pCutBest[0] = NULL; // negative polarity is not mapped
00127         p->pInputs[i]->pCutBest[1] = pCut; // positive polarity is a trivial cut
00128         pCut->uTruth = 0xAAAAAAAA;         // the first variable "10101010"
00129         pCut->M[0].AreaFlow = 0.0;
00130         pCut->M[1].AreaFlow = 0.0;
00131     }
00132 
00133     // compute the cuts for the internal nodes
00134     nNodes = p->vAnds->nSize;
00135     pProgress = Extra_ProgressBarStart( stdout, nNodes );
00136     pTable = Map_CutTableStart( p );
00137     for ( i = 0; i < nNodes; i++ )
00138     {
00139         pNode = p->vAnds->pArray[i];
00140         if ( !Map_NodeIsAnd( pNode ) )
00141             continue;
00142         Map_CutCompute( p, pTable, pNode );
00143         Extra_ProgressBarUpdate( pProgress, i, "Cuts ..." );
00144     }
00145     Extra_ProgressBarStop( pProgress );
00146     Map_CutTableStop( pTable );
00147 
00148     // report the stats
00149     if ( p->fVerbose )
00150     {
00151         nCuts = Map_MappingCountAllCuts(p);
00152         printf( "Nodes = %6d.  Total %d-feasible cuts = %10d.  Per node = %.1f. ", 
00153                p->nNodes, p->nVarsMax, nCuts, ((float)nCuts)/p->nNodes );
00154         PRT( "Time", clock() - clk );
00155     }
00156 
00157     // print the cuts for the first primary output
00158 //    Map_CutListPrint( p, Map_Regular(p->pOutputs[0]) );
00159 }


Variable Documentation

int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 } [static]

Definition at line 44 of file mapperCut.c.


Generated on Tue Jan 5 12:19:05 2010 for abc70930 by  doxygen 1.6.1