/**CFile**************************************************************** FileName [ Fxch.c ] PackageName [ Fast eXtract with Cube Hashing (FXCH) ] Synopsis [ The entrance into the fast extract module. ] Author [ Bruno Schmitt - boschmitt at inf.ufrgs.br ] Affiliation [ UFRGS ] Date [ Ver. 1.0. Started - March 6, 2016. ] Revision [] ***********************************************************************/ #include "Fxch.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fxch_CubesGruping(Fxch_Man_t* pFxchMan) { Vec_Int_t* vCube; int iCube, nOutputs, SizeOutputID; Hsh_VecMan_t* pCubeHash; /* 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 ); } nOutputs = Vec_IntSize( pFxchMan->vTranslation ); /* Size of the OutputID in number o ints */ SizeOutputID = ( nOutputs >> 5 ) + ( ( nOutputs & 31 ) > 0 ); /* Initialize needed structures */ pFxchMan->vOutputID = Vec_IntAlloc( 4096 ); pFxchMan->pTempOutputID = ABC_CALLOC( int, SizeOutputID ); pFxchMan->nSizeOutputID = SizeOutputID; 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 ); int i, iCubeNoID, Temp, * pEntry; Vec_IntWriteEntry( vCube, 0, 0 ); // Clear ID, Outputs will be identified by it later iCubeNoID = Hsh_VecManAdd( pCubeHash, vCube ); Temp = ( 1 << ( iTranslation & 31 ) ); if ( iCubeNoID == Vec_IntSize( pFxchMan->vOutputID ) / SizeOutputID ) { for ( 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 ); 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 ) { int * pOutputID, nOnes; if ( Vec_IntSize( vCube ) == 0 || Vec_IntEntry( vCube, 0 ) != 0 ) continue; pOutputID = Vec_IntEntryP( pFxchMan->vOutputID, iCube * pFxchMan->nSizeOutputID ); 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. ] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fxch_FastExtract( Vec_Wec_t* vCubes, int ObjIdMax, int nMaxDivExt, int fVerbose, int fVeryVerbose ) { abctime TempTime; Fxch_Man_t* pFxchMan = Fxch_ManAlloc( vCubes ); int i; TempTime = Abc_Clock(); Fxch_CubesGruping( pFxchMan ); Fxch_ManMapLiteralsIntoCubes( pFxchMan, ObjIdMax ); Fxch_ManGenerateLitHashKeys( pFxchMan ); Fxch_ManComputeLevel( pFxchMan ); Fxch_ManSCHashTablesInit( pFxchMan ); Fxch_ManDivCreate( pFxchMan ); pFxchMan->timeInit = Abc_Clock() - TempTime; if ( fVeryVerbose ) Fxch_ManPrintDivs( pFxchMan ); if ( fVerbose ) 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 ); if ( fVeryVerbose ) Fxch_DivPrint( pFxchMan, iDiv ); Fxch_ManUpdate( pFxchMan, iDiv ); } pFxchMan->timeExt = Abc_Clock() - TempTime; if ( fVerbose ) { Fxch_ManPrintStats( pFxchMan ); Abc_PrintTime( 1, "\n[FXCH] Elapsed Time", pFxchMan->timeInit + pFxchMan->timeExt ); Abc_PrintTime( 1, "[FXCH] +-> Init", pFxchMan->timeInit ); 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; } /**Function************************************************************* Synopsis [ Retrives the necessary information for the fast extract with cube hashing. ] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkFxchPerform( Abc_Ntk_t* pNtk, int nMaxDivExt, int fVerbose, int fVeryVerbose ) { Vec_Wec_t* vCubes; assert( Abc_NtkIsSopLogic( pNtk ) ); if ( !Abc_NtkFxCheck( pNtk ) ) { printf( "Abc_NtkFxchPerform(): Nodes have duplicated fanins. FXCH is not performed.\n" ); return 0; } vCubes = Abc_NtkFxRetrieve( pNtk ); if ( Fxch_FastExtract( vCubes, Abc_NtkObjNumMax( pNtk ), nMaxDivExt, fVerbose, fVeryVerbose ) > 0 ) { Abc_NtkFxInsert( pNtk, vCubes ); Vec_WecFree( vCubes ); if ( !Abc_NtkCheck( pNtk ) ) printf( "Abc_NtkFxchPerform(): The network check has failed.\n" ); return 1; } else printf( "Warning: The network has not been changed by \"fxch\".\n" ); Vec_WecFree( vCubes ); return 0; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END