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