| /**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 |