diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2021-07-10 10:50:33 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2021-07-10 10:50:33 -0700 |
commit | 9fac6c7a8b150792b67c3daabf672137942103ee (patch) | |
tree | d69721cefd0194b4f3f91bd03ca201ac9858cffd | |
parent | fdc9e89d6643743c0d03b8c6c9cbf480f585c7ee (diff) | |
download | abc-9fac6c7a8b150792b67c3daabf672137942103ee.tar.gz abc-9fac6c7a8b150792b67c3daabf672137942103ee.tar.bz2 abc-9fac6c7a8b150792b67c3daabf672137942103ee.zip |
Experiments with CEC.
-rw-r--r-- | src/aig/gia/giaAiger.c | 7 | ||||
-rw-r--r-- | src/aig/gia/giaSimBase.c | 139 | ||||
-rw-r--r-- | src/base/abci/abc.c | 30 | ||||
-rw-r--r-- | src/map/if/ifCut.c | 4 |
4 files changed, 171 insertions, 9 deletions
diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index fef5b6e4..593743d5 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -1513,7 +1513,7 @@ static inline void Aiger_WriteUnsigned( FILE * pFile, unsigned x ) } int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int * pnOuts, int * pnAnds ) { - int i, Temp, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs; + int i, Temp, Value = 0, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs; FILE * pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { @@ -1544,7 +1544,7 @@ int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int for ( i = 0; i < nLats; i++ ) { while ( fgetc(pFile) != '\n' ); - fscanf( pFile, "%d", &Temp ); + Value += fscanf( pFile, "%d", &Temp ); pObjs[2*(nObjs-nLats+i)+0] = Temp; pObjs[2*(nObjs-nLats+i)+1] = Temp; } @@ -1552,10 +1552,11 @@ int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int for ( i = 0; i < nOuts; i++ ) { while ( fgetc(pFile) != '\n' ); - fscanf( pFile, "%d", &Temp ); + Value += fscanf( pFile, "%d", &Temp ); pObjs[2*(nObjs-nOuts-nLats+i)+0] = Temp; pObjs[2*(nObjs-nOuts-nLats+i)+1] = Temp; } + assert( Value == nLats + nOuts ); // read the binary part while ( fgetc(pFile) != '\n' ); for ( i = 0; i < nAnds; i++ ) diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index 9e7033ab..18176305 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -239,6 +239,145 @@ Gia_Man_t * Gia_ManPerformMuxDec( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +int Gia_ManComputeTfos_rec( Gia_Man_t * p, int iObj, int iRoot, Vec_Int_t * vNode ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjIsTravIdPreviousId(p, iObj) ) + return 1; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 0; + pObj = Gia_ManObj( p, iObj ); + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(pObj, iObj), iRoot, vNode ) | + Gia_ManComputeTfos_rec( p, Gia_ObjFaninId1(pObj, iObj), iRoot, vNode ) ) + { + Gia_ObjSetTravIdPreviousId(p, iObj); + Vec_IntPush( vNode, iObj ); + return 1; + } + Gia_ObjSetTravIdCurrentId(p, iObj); + return 0; +} +Vec_Wec_t * Gia_ManComputeTfos( Gia_Man_t * p ) +{ + Vec_Wec_t * vNodes = Vec_WecStart( Gia_ManCiNum(p) ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + int i, o, IdCi, IdCo; + Gia_ManForEachCiId( p, IdCi, i ) + { + Vec_Int_t * vNode = Vec_WecEntry( vNodes, i ); + Gia_ManIncrementTravId( p ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdPreviousId(p, IdCi); + Vec_IntPush( vNode, IdCi ); + Vec_IntClear( vTemp ); + Gia_ManForEachCoId( p, IdCo, o ) + if ( Gia_ManComputeTfos_rec( p, Gia_ObjFaninId0(Gia_ManObj(p, IdCo), IdCo), IdCi, vNode ) ) + Vec_IntPush( vTemp, Gia_ManObjNum(p) + (o >> 1) ); + Vec_IntUniqify( vTemp ); + Vec_IntAppend( vNode, vTemp ); + } + Vec_IntFree( vTemp ); + Vec_WecSort( vNodes, 1 ); + //Vec_WecPrint( vNodes, 0 ); + //Gia_AigerWrite( p, "dump.aig", 0, 0, 0 ); + return vNodes; +} +int Gia_ManFindDividerVar( Gia_Man_t * p, int fVerbose ) +{ + int iVar, Target = 1 << 28; + for ( iVar = 6; iVar < Gia_ManCiNum(p); iVar++ ) + if ( (1 << (iVar-3)) * Gia_ManObjNum(p) > Target ) + break; + if ( iVar == Gia_ManCiNum(p) ) + iVar = Gia_ManCiNum(p) - 1; + if ( fVerbose ) + printf( "Split var = %d. Rounds = %d. Bytes per node = %d. Total = %.2f MB.\n", iVar, 1 << (Gia_ManCiNum(p) - iVar), 1 << (iVar-3), 1.0*(1 << (iVar-3)) * Gia_ManObjNum(p)/(1<<20) ); + return iVar; +} +int Gia_ManComparePair( Gia_Man_t * p, Vec_Wrd_t * vSims, int iOut, int nWords2 ) +{ + Gia_Obj_t * pObj0 = Gia_ManCo( p, 2*iOut+0 ); + Gia_Obj_t * pObj1 = Gia_ManCo( p, 2*iOut+1 ); + word * pSim0 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj0) ); + word * pSim1 = Vec_WrdEntryP( vSims, nWords2*Gia_ObjId(p, pObj1) ); + Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj0), pObj0, nWords2, vSims ); + Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj1), pObj1, nWords2, vSims ); + return Abc_TtEqual( pSim0, pSim1, nWords2 ); +} +int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose ) +{ + int Status = -1; + abctime clk = Abc_Clock(); int fWarning = 0; + //int nVars2 = (Gia_ManCiNum(p) + 6)/2; + int nVars2 = Gia_ManFindDividerVar( p, fVerbose ); + int nVars3 = Gia_ManCiNum(p) - nVars2; + int nWords2 = Abc_Truth6WordNum( nVars2 ); + Vec_Wrd_t * vSims = Vec_WrdStart( nWords2 * Gia_ManObjNum(p) ); + Vec_Wec_t * vNodes = Gia_ManComputeTfos( p ); + Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( nVars2 ); + Gia_Obj_t * pObj; Vec_Int_t * vNode; int i, m, iObj; + Vec_WecForEachLevelStop( vNodes, vNode, i, nVars2 ) + Abc_TtCopy( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), (word *)Vec_PtrEntry(vTruths, i), nWords2, 0 ); + Vec_PtrFree( vTruths ); + Gia_ManForEachAnd( p, pObj, i ) + Gia_ManSimPatSimAnd( p, i, pObj, nWords2, vSims ); + for ( i = 0; i < Gia_ManCoNum(p)/2; i++ ) + { + if ( !Gia_ManComparePair( p, vSims, i, nWords2 ) ) + { + printf( "Miter is asserted for output %d.\n", i ); + Vec_WecFree( vNodes ); + Vec_WrdFree( vSims ); + return 0; + } + } + for ( m = 0; m < (1 << nVars3); m++ ) + { + int iVar = m ? Abc_TtSuppFindFirst( m ^ (m >> 1) ^ (m-1) ^ ((m-1) >> 1) ) : 0; + vNode = Vec_WecEntry( vNodes, nVars2+iVar ); + Abc_TtNot( Vec_WrdEntryP(vSims, nWords2*Vec_IntEntry(vNode,0)), nWords2 ); + Vec_IntForEachEntryStart( vNode, iObj, i, 1 ) + { + if ( iObj < Gia_ManObjNum(p) ) + { + pObj = Gia_ManObj( p, iObj ); + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManSimPatSimAnd( p, iObj, pObj, nWords2, vSims ); + } + else if ( !Gia_ManComparePair( p, vSims, iObj - Gia_ManObjNum(p), nWords2 ) ) + { + printf( "Miter is asserted for output %d.\n", iObj - Gia_ManObjNum(p) ); + Vec_WecFree( vNodes ); + Vec_WrdFree( vSims ); + return 0; + } + } + //for ( i = 0; i < Gia_ManObjNum(p); i++ ) + // printf( "%3d : ", i), Extra_PrintHex2( stdout, (unsigned *)Vec_WrdEntryP(vSims, i), 6 ), printf( "\n" ); + if ( !fWarning && Abc_Clock() > clk + 5*CLOCKS_PER_SEC ) + printf( "The computation is expected to take about %.2f sec.\n", 5.0*(1 << nVars3)/m ), fWarning = 1; + //if ( (m & 0x3F) == 0x3F ) + if ( fVerbose && (m & 0xFF) == 0xFF ) + printf( "Finished %6d (out of %6d)...\n", m, 1 << nVars3 ); + } + Vec_WecFree( vNodes ); + Vec_WrdFree( vSims ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Gia_ManSimPatAssignInputs2( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsIn ) { int i, Id; diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 9e24d2c0..0350b671 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -37407,10 +37407,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pFile; Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; char ** pArgvNew; - int c, nArgcNew, fUseNew = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; + int c, nArgcNew, fUseSim = 0, fUseNew = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; Cec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxtvwh" ) ) != EOF ) { switch ( c ) { @@ -37454,6 +37454,9 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'x': fUseNew ^= 1; break; + case 't': + fUseSim ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -37605,7 +37608,25 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) pMiter->vSimsPi = Vec_WrdDup(pGias[0]->vSimsPi); pMiter->nSimWords = pGias[0]->nSimWords; } - if ( fUseNew ) + if ( fUseSim && Gia_ManCiNum(pMiter) > 40 ) + { + Abc_Print( -1, "This type of CEC can only be applied to AIGs with no more than 40 inputs.\n" ); + return 0; + } + if ( fUseSim ) + { + abctime clk = Abc_Clock(); + extern int Gia_ManCheckSimEquiv( Gia_Man_t * p, int fVerbose ); + int Status = Gia_ManCheckSimEquiv( pMiter, pPars->fVerbose ); + if ( Status == 1 ) + Abc_Print( 1, "Networks are equivalent. " ); + else if ( Status == 0 ) + Abc_Print( 1, "Networks are NOT equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + else if ( fUseNew ) { abctime clk = Abc_Clock(); extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); @@ -37630,7 +37651,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxvwh]\n" ); + Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxtvwh]\n" ); Abc_Print( -2, "\t new combinational equivalence checker\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); @@ -37640,6 +37661,7 @@ usage: Abc_Print( -2, "\t-a : toggle writing dual-output miter [default = %s]\n", fDumpMiter? "yes":"no"); Abc_Print( -2, "\t-s : toggle silent operation [default = %s]\n", pPars->fSilent ? "yes":"no"); Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no"); + Abc_Print( -2, "\t-t : toggle using simulation [default = %s]\n", fUseSim? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c index a2447521..2d6889c0 100644 --- a/src/map/if/ifCut.c +++ b/src/map/if/ifCut.c @@ -1141,8 +1141,8 @@ float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut ) return 0; aResult2 = If_CutAreaDeref( p, pCut ); aResult = If_CutAreaRef( p, pCut ); - assert( aResult > aResult2 - p->fEpsilon ); - assert( aResult < aResult2 + p->fEpsilon ); +// assert( aResult > aResult2 - p->fEpsilon ); +// assert( aResult < aResult2 + p->fEpsilon ); return aResult; } |