Commit f59788f6 by Bruno Schmitt

Several updates to FXCH including:

- Cube Grouping
- New sub-cube hash table
parent fd8eb8c8
......@@ -15,7 +15,6 @@
Revision []
***********************************************************************/
#include "Fxch.h"
ABC_NAMESPACE_IMPL_START
......@@ -26,6 +25,125 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxch_CubesGruping(Fxch_Man_t* pFxchMan)
{
Vec_Int_t* vCube;
int iCube;
/* Identify the number of Outputs and create the translation table */
pFxchMan->vTranslation = Vec_IntAlloc( 32 );
Vec_WecForEachLevel( pFxchMan->vCubes, vCube, iCube )
{
int Id = Vec_IntEntry( vCube, 0 );
int iTranslation = Vec_IntFind( pFxchMan->vTranslation, Id );
if ( iTranslation == -1 )
Vec_IntPush( pFxchMan->vTranslation, Id );
}
int nOutputs = Vec_IntSize( pFxchMan->vTranslation );
/* Size of the OutputID in number o ints */
int SizeOutputID = ( nOutputs >> 5 ) + ( ( nOutputs & 31 ) > 0 );
/* Initialize needed structures */
pFxchMan->vOutputID = Vec_IntAlloc( 4096 );
pFxchMan->pTempOutputID = ABC_CALLOC( int, SizeOutputID );
pFxchMan->nSizeOutputID = SizeOutputID;
Hsh_VecMan_t* pCubeHash = Hsh_VecManStart( 1024 );
/* Identify equal cubes */
Vec_WecForEachLevel( pFxchMan->vCubes, vCube, iCube )
{
int Id = Vec_IntEntry( vCube, 0 );
int iTranslation = Vec_IntFind( pFxchMan->vTranslation, Id );
Vec_IntWriteEntry( vCube, 0, 0 ); // Clear ID, Outputs will be identified by it later
int iCubeNoID = Hsh_VecManAdd( pCubeHash, vCube );
int Temp = ( 1 << ( iTranslation & 31 ) );
if ( iCubeNoID == Vec_IntSize( pFxchMan->vOutputID ) / SizeOutputID )
{
for ( int i = 0; i < SizeOutputID; i++ )
pFxchMan->pTempOutputID[i] = 0;
pFxchMan->pTempOutputID[ iTranslation >> 5 ] = Temp;
Vec_IntPushArray( pFxchMan->vOutputID, pFxchMan->pTempOutputID, SizeOutputID );
}
else
{
Vec_IntClear( vCube );
int* pEntry = Vec_IntEntryP( pFxchMan->vOutputID, ( iCubeNoID * SizeOutputID ) + ( iTranslation >> 5 ) );
*pEntry |= Temp;
}
}
Hsh_VecManStop( pCubeHash );
Vec_WecRemoveEmpty( pFxchMan->vCubes );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxch_CubesUnGruping(Fxch_Man_t* pFxchMan)
{
int iCube;
int i, j;
Vec_Int_t* vCube;
Vec_Int_t* vNewCube;
assert( Vec_WecSize( pFxchMan->vCubes ) == ( Vec_IntSize( pFxchMan->vOutputID ) / pFxchMan->nSizeOutputID ) );
Vec_WecForEachLevel( pFxchMan->vCubes, vCube, iCube )
{
if ( Vec_IntSize( vCube ) == 0 || Vec_IntEntry( vCube, 0 ) != 0 )
continue;
int* pOutputID = Vec_IntEntryP( pFxchMan->vOutputID, iCube * pFxchMan->nSizeOutputID );
int nOnes = 0;
for ( i = 0; i < pFxchMan->nSizeOutputID; i++ )
nOnes += Fxch_CountOnes( (unsigned int) pOutputID[i] );
for ( i = 0; i < pFxchMan->nSizeOutputID && nOnes; i++ )
for ( j = 0; j < 32 && nOnes; j++ )
if ( pOutputID[i] & ( 1 << j ) )
{
if ( nOnes == 1 )
Vec_IntWriteEntry( vCube, 0, Vec_IntEntry( pFxchMan->vTranslation, ( i << 5 ) | j ) );
else
{
vNewCube = Vec_WecPushLevel( pFxchMan->vCubes );
Vec_IntAppend( vNewCube, vCube );
Vec_IntWriteEntry( vNewCube, 0, Vec_IntEntry( pFxchMan->vTranslation, (i << 5 ) | j ) );
}
nOnes -= 1;
}
}
Vec_IntFree( pFxchMan->vTranslation );
Vec_IntFree( pFxchMan->vOutputID );
ABC_FREE( pFxchMan->pTempOutputID );
return;
}
/**Function*************************************************************
Synopsis [ Performs fast extract with cube hashing on a set
of covers. ]
......@@ -47,6 +165,7 @@ int Fxch_FastExtract( Vec_Wec_t* vCubes,
int i;
TempTime = Abc_Clock();
Fxch_CubesGruping( pFxchMan );
Fxch_ManMapLiteralsIntoCubes( pFxchMan, ObjIdMax );
Fxch_ManGenerateLitHashKeys( pFxchMan );
Fxch_ManComputeLevel( pFxchMan );
......@@ -61,6 +180,7 @@ int Fxch_FastExtract( Vec_Wec_t* vCubes,
Fxch_ManPrintStats( pFxchMan );
TempTime = Abc_Clock();
for ( i = 0; (!nMaxDivExt || i < nMaxDivExt) && Vec_QueTopPriority( pFxchMan->vDivPrio ) > 0.0; i++ )
{
int iDiv = Vec_QuePop( pFxchMan->vDivPrio );
......@@ -70,6 +190,7 @@ int Fxch_FastExtract( Vec_Wec_t* vCubes,
Fxch_ManUpdate( pFxchMan, iDiv );
}
pFxchMan->timeExt = Abc_Clock() - TempTime;
if ( fVerbose )
......@@ -80,9 +201,12 @@ int Fxch_FastExtract( Vec_Wec_t* vCubes,
Abc_PrintTime( 1, "[FXCH] +-> Extr", pFxchMan->timeExt );
}
Fxch_CubesUnGruping( pFxchMan );
Fxch_ManSCHashTablesFree( pFxchMan );
Fxch_ManFree( pFxchMan );
Vec_WecRemoveEmpty( vCubes );
Vec_WecSortByFirstInt( vCubes, 0 );
return 1;
}
......
......@@ -52,25 +52,22 @@ typedef struct Fxch_SCHashTable_Entry_t_ Fxch_SCHashTable_Entry_t;
* its literals.
*
*/
struct Fxch_SubCube_t_
{
unsigned int Id,
iCube;
unsigned int iLit0 : 16,
iLit1 : 16;
uint32_t Id,
iCube;
uint32_t iLit0 : 16,
iLit1 : 16;
};
/* Sub-cube Hash Table
*
*/
struct Fxch_SCHashTable_Entry_t_
{
Fxch_SubCube_t SCData;
unsigned int iTable : 31,
Used : 1;
unsigned int iPrev,
iNext;
Fxch_SubCube_t* vSCData;
uint32_t Size : 16,
Cap : 16;
};
struct Fxch_SCHashTable_t_
......@@ -80,7 +77,6 @@ struct Fxch_SCHashTable_t_
Fxch_SCHashTable_Entry_t* pBins;
unsigned int nEntries,
SizeMask;
Vec_Int_t* vCubeLinks;
/* Temporary data */
Vec_Int_t vSubCube0;
......@@ -91,6 +87,7 @@ struct Fxch_Man_t_
{
/* user's data */
Vec_Wec_t* vCubes;
int nCubesInit;
int LitCountMax;
/* internal data */
......@@ -107,12 +104,21 @@ struct Fxch_Man_t_
Vec_Int_t* vLevels; /* variable levels */
// Cube Grouping
Vec_Int_t* vTranslation;
Vec_Int_t* vOutputID;
int* pTempOutputID;
int nSizeOutputID;
// temporary data to update the data-structure when a divisor is extracted
Vec_Int_t* vCubesS; /* cubes for the given single cube divisor */
Vec_Int_t* vPairs; /* cube pairs for the given double cube divisor */
Vec_Int_t* vCubeFree; // cube-free divisor
Vec_Int_t* vDiv; // selected divisor
Vec_Int_t* vSCC;
Vec_Int_t* vCubesS; /* cubes for the given single cube divisor */
Vec_Int_t* vPairs; /* cube pairs for the given double cube divisor */
Vec_Int_t* vCubeFree; // cube-free divisor
Vec_Int_t* vDiv; // selected divisor
Vec_Int_t* vCubesToRemove;
Vec_Int_t* vCubesToUpdate;
Vec_Int_t* vSCC;
/* Statistics */
abctime timeInit; /* Initialization time */
......@@ -135,6 +141,15 @@ extern Vec_Wec_t* Abc_NtkFxRetrieve( Abc_Ntk_t* pNtk );
extern void Abc_NtkFxInsert( Abc_Ntk_t* pNtk, Vec_Wec_t* vCubes );
extern int Abc_NtkFxCheck( Abc_Ntk_t* pNtk );
static inline int Fxch_CountOnes( unsigned num )
{
num = ( num & 0x55555555 ) + ( ( num >> 1) & 0x55555555 );
num = ( num & 0x33333333 ) + ( ( num >> 2) & 0x33333333 );
num = ( num & 0x0F0F0F0F ) + ( ( num >> 4) & 0x0F0F0F0F );
num = ( num & 0x00FF00FF ) + ( ( num >> 8) & 0x00FF00FF );
return ( num & 0x0000FFFF ) + ( num >> 16 );
}
/*===== Fxch.c =======================================================*/
int Abc_NtkFxchPerform( Abc_Ntk_t* pNtk, int nMaxDivExt, int fVerbose, int fVeryVerbose );
int Fxch_FastExtract( Vec_Wec_t* vCubes, int ObjIdMax, int nMaxDivExt, int fVerbose, int fVeryVerbose );
......@@ -177,26 +192,25 @@ static inline int Fxch_ManGetLit( Fxch_Man_t* pFxchMan,
}
/*===== FxchSCHashTable.c ============================================*/
Fxch_SCHashTable_t* Fxch_SCHashTableCreate( Fxch_Man_t* pFxchMan, Vec_Int_t* vCubeLinks, int nEntries );
Fxch_SCHashTable_t* Fxch_SCHashTableCreate( Fxch_Man_t* pFxchMan, int nEntries );
void Fxch_SCHashTableDelete( Fxch_SCHashTable_t* );
int Fxch_SCHashTableInsert( Fxch_SCHashTable_t* pSCHashTable,
Vec_Wec_t* vCubes,
unsigned int SubCubeID,
unsigned int iSubCube,
unsigned int iCube,
unsigned int iLit0,
unsigned int iLit1,
uint32_t SubCubeID,
uint32_t iCube,
uint32_t iLit0,
uint32_t iLit1,
char fUpdate );
int Fxch_SCHashTableRemove( Fxch_SCHashTable_t* pSCHashTable,
Vec_Wec_t* vCubes,
unsigned int SubCubeID,
unsigned int iSubCube,
unsigned int iCube,
unsigned int iLit0,
unsigned int iLit1,
uint32_t SubCubeID,
uint32_t iCube,
uint32_t iLit0,
uint32_t iLit1,
char fUpdate );
unsigned int Fxch_SCHashTableMemory( Fxch_SCHashTable_t* );
......
......@@ -142,10 +142,20 @@ int Fxch_DivCreate( Fxch_Man_t* pFxchMan,
SC0_Lit1 = Fxch_ManGetLit( pFxchMan, pSubCube0->iCube, pSubCube0->iLit1 );
SC1_Lit1 = Fxch_ManGetLit( pFxchMan, pSubCube1->iCube, pSubCube1->iLit1 );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC0_Lit0, 0 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC1_Lit0, 1 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC0_Lit1, 0 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC1_Lit1, 1 ) );
if ( SC0_Lit0 < SC1_Lit0 )
{
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC0_Lit0, 0 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC1_Lit0, 1 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC0_Lit1, 0 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC1_Lit1, 1 ) );
}
else
{
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC1_Lit0, 0 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC0_Lit0, 1 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC1_Lit1, 0 ) );
Vec_IntPush( pFxchMan->vCubeFree, Abc_Var2Lit( SC0_Lit1, 1 ) );
}
RetValue = Fxch_DivNormalize( pFxchMan->vCubeFree );
if ( RetValue == -1 )
......
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