Commit a677a679 by Alan Mishchenko

Gate combination precomputation with delay profile.

parent b3f16496
...@@ -175,7 +175,7 @@ Sfm_Dec_t * Sfm_DecStart( Sfm_Par_t * pPars ) ...@@ -175,7 +175,7 @@ Sfm_Dec_t * Sfm_DecStart( Sfm_Par_t * pPars )
for ( i = 0; i < SFM_SUPP_MAX; i++ ) for ( i = 0; i < SFM_SUPP_MAX; i++ )
p->pTtElems[i] = p->TtElems[i]; p->pTtElems[i] = p->TtElems[i];
Abc_TtElemInit( p->pTtElems, SFM_SUPP_MAX ); Abc_TtElemInit( p->pTtElems, SFM_SUPP_MAX );
p->pLib = Sfm_LibPrepare( pPars->nMffcMax + 1, 1, pPars->fVerbose ); p->pLib = Sfm_LibPrepare( pPars->nMffcMax + 1, 1, !pPars->fArea, pPars->fVerbose );
if ( pPars->fVeryVerbose ) if ( pPars->fVeryVerbose )
// if ( pPars->fVerbose ) // if ( pPars->fVerbose )
Sfm_LibPrint( p->pLib ); Sfm_LibPrint( p->pLib );
......
...@@ -192,7 +192,7 @@ extern void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_In ...@@ -192,7 +192,7 @@ extern void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_In
/*=== sfmCore.c ==========================================================*/ /*=== sfmCore.c ==========================================================*/
/*=== sfmLib.c ==========================================================*/ /*=== sfmLib.c ==========================================================*/
extern int Sfm_LibFindComplInputGate( Vec_Wrd_t * vFuncs, int iGate, int nFanins, int iFanin, int * piFaninNew ); extern int Sfm_LibFindComplInputGate( Vec_Wrd_t * vFuncs, int iGate, int nFanins, int iFanin, int * piFaninNew );
extern Sfm_Lib_t * Sfm_LibPrepare( int nVars, int fTwo, int fVerbose ); extern Sfm_Lib_t * Sfm_LibPrepare( int nVars, int fTwo, int fDelay, int fVerbose );
extern void Sfm_LibPrint( Sfm_Lib_t * p ); extern void Sfm_LibPrint( Sfm_Lib_t * p );
extern void Sfm_LibStop( Sfm_Lib_t * p ); extern void Sfm_LibStop( Sfm_Lib_t * p );
extern int Sfm_LibImplement( Sfm_Lib_t * p, word uTruth, int * pFanins, int nFanins, int AreaMffc, Vec_Int_t * vGates, Vec_Wec_t * vFanins, int fZeroCost ); extern int Sfm_LibImplement( Sfm_Lib_t * p, word uTruth, int * pFanins, int nFanins, int AreaMffc, Vec_Int_t * vGates, Vec_Wec_t * vFanins, int fZeroCost );
......
...@@ -46,15 +46,22 @@ struct Sfm_Lib_t_ ...@@ -46,15 +46,22 @@ struct Sfm_Lib_t_
{ {
Mio_Cell2_t * pCells; // library gates Mio_Cell2_t * pCells; // library gates
int nCells; // library gate count int nCells; // library gate count
int fDelay; // uses delay profile
int nObjs; // object count int nObjs; // object count
int nObjsAlloc; // object count int nObjsAlloc; // object count
Sfm_Fun_t * pObjs; // objects Sfm_Fun_t * pObjs; // objects
Vec_Mem_t * vTtMem; // truth tables Vec_Mem_t * vTtMem; // truth tables
Vec_Int_t vLists; // lists of funcs for each truth table Vec_Int_t vLists; // lists of funcs for each truth table
Vec_Int_t vCounts; // counters of functions for each truth table Vec_Int_t vCounts; // counters of functions for each truth table
Vec_Int_t vProfs; // area/delay profiles
Vec_Int_t vStore; // storage for area/delay profiles
Vec_Int_t vTemp; // temporary storage for candidates
int nObjSkipped;
int nObjRemoved;
}; };
static inline Sfm_Fun_t * Sfm_LibFun( Sfm_Lib_t * p, int i ) { return i == -1 ? NULL : p->pObjs + i; } static inline Sfm_Fun_t * Sfm_LibFun( Sfm_Lib_t * p, int i ) { return i == -1 ? NULL : p->pObjs + i; }
static inline int Sfm_LibFunId( Sfm_Lib_t * p, Sfm_Fun_t * pFun ) { return pFun - p->pObjs; }
#define Sfm_LibForEachSuper( p, pObj, Func ) \ #define Sfm_LibForEachSuper( p, pObj, Func ) \
for ( pObj = Sfm_LibFun(p, Vec_IntEntry(&p->vLists, Func)); pObj; pObj = Sfm_LibFun(p, pObj->Next) ) for ( pObj = Sfm_LibFun(p, Vec_IntEntry(&p->vLists, Func)); pObj; pObj = Sfm_LibFun(p, pObj->Next) )
...@@ -178,7 +185,7 @@ int Sfm_LibFindComplInputGate( Vec_Wrd_t * vFuncs, int iGate, int nFanins, int i ...@@ -178,7 +185,7 @@ int Sfm_LibFindComplInputGate( Vec_Wrd_t * vFuncs, int iGate, int nFanins, int i
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Sfm_Lib_t * Sfm_LibStart( int nVars ) Sfm_Lib_t * Sfm_LibStart( int nVars, int fDelay )
{ {
Sfm_Lib_t * p = ABC_CALLOC( Sfm_Lib_t, 1 ); Sfm_Lib_t * p = ABC_CALLOC( Sfm_Lib_t, 1 );
p->vTtMem = Vec_MemAllocForTT( nVars, 0 ); p->vTtMem = Vec_MemAllocForTT( nVars, 0 );
...@@ -188,6 +195,10 @@ Sfm_Lib_t * Sfm_LibStart( int nVars ) ...@@ -188,6 +195,10 @@ Sfm_Lib_t * Sfm_LibStart( int nVars )
Vec_IntFill( &p->vCounts, 2, -1 ); Vec_IntFill( &p->vCounts, 2, -1 );
p->nObjsAlloc = (1 << 16); p->nObjsAlloc = (1 << 16);
p->pObjs = ABC_CALLOC( Sfm_Fun_t, p->nObjsAlloc ); p->pObjs = ABC_CALLOC( Sfm_Fun_t, p->nObjsAlloc );
p->fDelay = fDelay;
if ( fDelay ) Vec_IntGrow( &p->vProfs, (1 << 16) );
if ( fDelay ) Vec_IntGrow( &p->vStore, (1 << 18) );
Vec_IntGrow( &p->vTemp, 16 );
return p; return p;
} }
void Sfm_LibStop( Sfm_Lib_t * p ) void Sfm_LibStop( Sfm_Lib_t * p )
...@@ -196,6 +207,9 @@ void Sfm_LibStop( Sfm_Lib_t * p ) ...@@ -196,6 +207,9 @@ void Sfm_LibStop( Sfm_Lib_t * p )
Vec_MemFree( p->vTtMem ); Vec_MemFree( p->vTtMem );
Vec_IntErase( &p->vLists ); Vec_IntErase( &p->vLists );
Vec_IntErase( &p->vCounts ); Vec_IntErase( &p->vCounts );
Vec_IntErase( &p->vProfs );
Vec_IntErase( &p->vStore );
Vec_IntErase( &p->vTemp );
ABC_FREE( p->pCells ); ABC_FREE( p->pCells );
ABC_FREE( p->pObjs ); ABC_FREE( p->pObjs );
ABC_FREE( p ); ABC_FREE( p );
...@@ -238,11 +252,43 @@ word Sfm_LibTruthTwo( Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop ...@@ -238,11 +252,43 @@ word Sfm_LibTruthTwo( Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline void Sfm_LibCellProfile( Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop, int nFanins, int * Perm, int * pProf )
{
int i, DelayAdd = (int)(pCellTop ? pCellTop->Delays[InTop] : 0);
for ( i = 0; i < nFanins; i++ )
if ( Perm[i] < (int)pCellBot->nFanins )
pProf[i] = (int)pCellBot->Delays[Perm[i]] + DelayAdd;
else if ( Perm[i] < (int)pCellBot->nFanins + InTop )
pProf[i] = (int)pCellTop->Delays[Perm[i] - (int)pCellBot->nFanins];
else // if ( Perm[i] >= (int)pCellBot->nFanins + InTop )
pProf[i] = (int)pCellTop->Delays[Perm[i] - (int)pCellBot->nFanins + 1];
}
static inline int Sfm_LibNewIsContained( Sfm_Fun_t * pObj, int * pProf, int Area, int * pProfNew, int nFanins )
{
int k;
if ( Area < pObj->Area )
return 0;
for ( k = 0; k < nFanins; k++ )
if ( pProfNew[k] < pProf[k] )
return 0;
return 1;
}
static inline int Sfm_LibNewContains( Sfm_Fun_t * pObj, int * pProf, int Area, int * pProfNew, int nFanins )
{
int k;
if ( Area > pObj->Area )
return 0;
for ( k = 0; k < nFanins; k++ )
if ( pProfNew[k] > pProf[k] )
return 0;
return 1;
}
void Sfm_LibPrepareAdd( Sfm_Lib_t * p, word uTruth, int * Perm, int nFanins, Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop ) void Sfm_LibPrepareAdd( Sfm_Lib_t * p, word uTruth, int * Perm, int nFanins, Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop )
{ {
Sfm_Fun_t * pObj; Sfm_Fun_t * pObj;
int InvPerm[6], Area = (int)pCellBot->Area + (pCellTop ? (int)pCellTop->Area : 0); int InvPerm[6], Profile[6];
int i, k, iFunc = Vec_MemHashInsert( p->vTtMem, &uTruth ); int Area = (int)pCellBot->Area + (pCellTop ? (int)pCellTop->Area : 0);
int i, k, Id, Prev, Offset, * pProf, iFunc = Vec_MemHashInsert( p->vTtMem, &uTruth );
if ( iFunc == Vec_IntSize(&p->vLists) ) if ( iFunc == Vec_IntSize(&p->vLists) )
{ {
Vec_IntPush( &p->vLists, -1 ); Vec_IntPush( &p->vLists, -1 );
...@@ -250,13 +296,69 @@ void Sfm_LibPrepareAdd( Sfm_Lib_t * p, word uTruth, int * Perm, int nFanins, Mio ...@@ -250,13 +296,69 @@ void Sfm_LibPrepareAdd( Sfm_Lib_t * p, word uTruth, int * Perm, int nFanins, Mio
} }
assert( pCellBot != NULL ); assert( pCellBot != NULL );
// iterate through the supergates of this truth table // iterate through the supergates of this truth table
if ( p->fDelay )
{
assert( Vec_IntSize(&p->vProfs) == p->nObjs );
Sfm_LibCellProfile( pCellBot, pCellTop, InTop, nFanins, Perm, Profile );
// check if new one is contained in old ones
Vec_IntClear( &p->vTemp );
Sfm_LibForEachSuper( p, pObj, iFunc )
{
Vec_IntPush( &p->vTemp, Sfm_LibFunId(p, pObj) );
Offset = Vec_IntEntry( &p->vProfs, Sfm_LibFunId(p, pObj) );
pProf = Vec_IntEntryP( &p->vStore, Offset );
if ( Sfm_LibNewIsContained(pObj, pProf, Area, Profile, nFanins) )
{
p->nObjSkipped++;
return;
}
}
// check if old ones are contained in new one
k = 0;
Vec_IntForEachEntry( &p->vTemp, Id, i )
{
Offset = Vec_IntEntry( &p->vProfs, Id );
pProf = Vec_IntEntryP( &p->vStore, Offset );
if ( !Sfm_LibNewContains(Sfm_LibFun(p, Id), pProf, Area, Profile, nFanins) )
Vec_IntWriteEntry( &p->vTemp, k++, Id );
else
p->nObjRemoved++;
}
if ( k < i ) // change
{
if ( k == 0 )
Vec_IntWriteEntry( &p->vLists, iFunc, -1 );
else
{
Vec_IntShrink( &p->vTemp, k );
Prev = Vec_IntEntry(&p->vTemp, 0);
Vec_IntWriteEntry( &p->vLists, iFunc, Prev );
Vec_IntForEachEntryStart( &p->vTemp, Id, i, 1 )
{
Sfm_LibFun(p, Prev)->Next = Id;
Prev = Id;
}
Sfm_LibFun(p, Prev)->Next = -1;
}
}
}
else
{
Sfm_LibForEachSuper( p, pObj, iFunc ) Sfm_LibForEachSuper( p, pObj, iFunc )
{ {
if ( Area >= pObj->Area ) if ( Area >= pObj->Area )
return; return;
} }
}
for ( k = 0; k < nFanins; k++ ) for ( k = 0; k < nFanins; k++ )
InvPerm[Perm[k]] = k; InvPerm[Perm[k]] = k;
// create delay profile
if ( p->fDelay )
{
Vec_IntPush( &p->vProfs, Vec_IntSize(&p->vStore) );
for ( k = 0; k < nFanins; k++ )
Vec_IntPush( &p->vStore, Profile[k] );
}
// create new object // create new object
if ( p->nObjs == p->nObjsAlloc ) if ( p->nObjs == p->nObjsAlloc )
{ {
...@@ -283,10 +385,10 @@ void Sfm_LibPrepareAdd( Sfm_Lib_t * p, word uTruth, int * Perm, int nFanins, Mio ...@@ -283,10 +385,10 @@ void Sfm_LibPrepareAdd( Sfm_Lib_t * p, word uTruth, int * Perm, int nFanins, Mio
pObj->pFansT[i+1] = (char)(i == InTop ? 16 : InvPerm[k++]); pObj->pFansT[i+1] = (char)(i == InTop ? 16 : InvPerm[k++]);
assert( k == nFanins ); assert( k == nFanins );
} }
Sfm_Lib_t * Sfm_LibPrepare( int nVars, int fTwo, int fVerbose ) Sfm_Lib_t * Sfm_LibPrepare( int nVars, int fTwo, int fDelay, int fVerbose )
{ {
abctime clk = Abc_Clock(); abctime clk = Abc_Clock();
Sfm_Lib_t * p = Sfm_LibStart( nVars ); Sfm_Lib_t * p = Sfm_LibStart( nVars, fDelay );
Mio_Cell2_t * pCell1, * pCell2, * pLimit; Mio_Cell2_t * pCell1, * pCell2, * pLimit;
int * pPerm[7], * Perm1, * Perm2, Perm[6]; int * pPerm[7], * Perm1, * Perm2, Perm[6];
int nPerms[7], i, f, n; int nPerms[7], i, f, n;
...@@ -366,7 +468,10 @@ Sfm_Lib_t * Sfm_LibPrepare( int nVars, int fTwo, int fVerbose ) ...@@ -366,7 +468,10 @@ Sfm_Lib_t * Sfm_LibPrepare( int nVars, int fTwo, int fVerbose )
Vec_IntFree( vUseful ); Vec_IntFree( vUseful );
if ( fVerbose ) if ( fVerbose )
{ {
printf( "Library processing: Var = %d. Cells = %d. Func = %6d. Obj = %8d. Ave = %8.2f ", nVars, p->nCells, Vec_MemEntryNum(p->vTtMem), p->nObjs, 1.0*p->nObjs/Vec_MemEntryNum(p->vTtMem) ); printf( "Library processing: Var = %d. Cell = %d. Fun = %d. Obj = %d. Ave = %.2f. Skip = %d. Rem = %d. ",
nVars, p->nCells, Vec_MemEntryNum(p->vTtMem)-2,
p->nObjs-p->nObjRemoved, 1.0*(p->nObjs-p->nObjRemoved)/(Vec_MemEntryNum(p->vTtMem)-2),
p->nObjSkipped, p->nObjRemoved );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
} }
return p; return p;
...@@ -386,12 +491,20 @@ void Sfm_LibPrintObj( Sfm_Lib_t * p, Sfm_Fun_t * pObj ) ...@@ -386,12 +491,20 @@ void Sfm_LibPrintObj( Sfm_Lib_t * p, Sfm_Fun_t * pObj )
{ {
Mio_Cell2_t * pCellB = p->pCells + (int)pObj->pFansB[0]; Mio_Cell2_t * pCellB = p->pCells + (int)pObj->pFansB[0];
Mio_Cell2_t * pCellT = p->pCells + (int)pObj->pFansT[0]; Mio_Cell2_t * pCellT = p->pCells + (int)pObj->pFansT[0];
int nFanins = pCellB->nFanins + (pCellT == p->pCells ? 0 : pCellT->nFanins); int i, nFanins = pCellB->nFanins + (pCellT == p->pCells ? 0 : pCellT->nFanins - 1);
printf( " Area = %6.2f Fanins = %d ", MIO_NUMINV*pObj->Area, nFanins ); printf( " Area = %6.2f Fanins = %d ", MIO_NUMINV*pObj->Area, nFanins );
if ( pCellT == p->pCells ) if ( pCellT == p->pCells )
Sfm_LibPrintGate( pCellB, pObj->pFansB + 1, NULL, NULL ); Sfm_LibPrintGate( pCellB, pObj->pFansB + 1, NULL, NULL );
else else
Sfm_LibPrintGate( pCellT, pObj->pFansT + 1, pCellB, pObj->pFansB + 1 ); Sfm_LibPrintGate( pCellT, pObj->pFansT + 1, pCellB, pObj->pFansB + 1 );
// get hold of delay info
if ( p->fDelay )
{
int Offset = Vec_IntEntry( &p->vProfs, Sfm_LibFunId(p, pObj) );
int * pProf = Vec_IntEntryP( &p->vStore, Offset );
for ( i = 0; i < nFanins; i++ )
printf( "%6.2f ", MIO_NUMINV*pProf[i] );
}
printf( "\n" ); printf( "\n" );
} }
void Sfm_LibPrint( Sfm_Lib_t * p ) void Sfm_LibPrint( Sfm_Lib_t * p )
...@@ -409,11 +522,18 @@ void Sfm_LibPrint( Sfm_Lib_t * p ) ...@@ -409,11 +522,18 @@ void Sfm_LibPrint( Sfm_Lib_t * p )
Sfm_LibPrintObj( p, pObj ); Sfm_LibPrintObj( p, pObj );
} }
} }
void Sfm_LibTest( int nVars, int fTwo, int fVerbose ) void Sfm_LibTest()
{ {
Sfm_Lib_t * p = Sfm_LibPrepare( nVars, fTwo, 1 ); Sfm_Lib_t * p;
if ( fVerbose ) int fVerbose = 1;
Sfm_LibPrint( p ); if ( Abc_FrameReadLibGen() == NULL )
{
printf( "There is no current library.\n" );
return;
}
p = Sfm_LibPrepare( 6, 1, 1, fVerbose );
//if ( fVerbose )
// Sfm_LibPrint( p );
Sfm_LibStop( p ); Sfm_LibStop( p );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment