diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2013-10-10 12:35:27 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2013-10-10 12:35:27 -0700 |
commit | 33695bed11237e8b2e04e75daa0659070d5605a6 (patch) | |
tree | 4b8052282ac3adccc70824798a733ea8f38c6565 | |
parent | 4c62b0028816cda59edf796577056d6d27e1be8d (diff) | |
download | abc-33695bed11237e8b2e04e75daa0659070d5605a6.tar.gz abc-33695bed11237e8b2e04e75daa0659070d5605a6.tar.bz2 abc-33695bed11237e8b2e04e75daa0659070d5605a6.zip |
Improvements to the canonical form computation.
-rw-r--r-- | src/aig/gia/giaJf.c | 22 | ||||
-rw-r--r-- | src/base/abci/abc.c | 1 | ||||
-rw-r--r-- | src/base/abci/abcNpn.c | 22 | ||||
-rw-r--r-- | src/misc/util/utilTruth.h | 1 | ||||
-rw-r--r-- | src/opt/dau/dau.h | 1 | ||||
-rw-r--r-- | src/opt/dau/dauCanon.c | 99 |
6 files changed, 133 insertions, 13 deletions
diff --git a/src/aig/gia/giaJf.c b/src/aig/gia/giaJf.c index 454a1b3d..252a8187 100644 --- a/src/aig/gia/giaJf.c +++ b/src/aig/gia/giaJf.c @@ -357,6 +357,16 @@ Jf_Man_t * Jf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars ) p->clkStart = Abc_Clock(); return p; } +void Jf_ManDumpTruthTables( Jf_Man_t * p ) +{ + char * pFileName = "truths.txt"; + FILE * pFile = fopen( pFileName, "wb" ); + Vec_MemDump( pFile, p->vTtMem ); + fclose( pFile ); + printf( "Dumped %d %d-var truth tables into file \"%s\" (%.2f MB).\n", + Vec_MemEntryNum(p->vTtMem), p->pPars->nLutSize, pFileName, + 17.0 * Vec_MemEntryNum(p->vTtMem) / (1 << 20) ); +} void Jf_ManFree( Jf_Man_t * p ) { if ( p->pPars->fVerbose && p->pDsd ) @@ -365,16 +375,6 @@ void Jf_ManFree( Jf_Man_t * p ) printf( "Unique truth tables = %d. Memory = %.2f MB\n", Vec_MemEntryNum(p->vTtMem), Vec_MemMemory(p->vTtMem) / (1<<20) ); if ( p->pPars->fVeryVerbose && p->pPars->fCutMin && p->pPars->fFuncDsd ) Jf_ManProfileClasses( p ); - if ( p->pPars->fVeryVerbose && p->pPars->fCutMin && !p->pPars->fFuncDsd ) - { - char * pFileName = "truths.txt"; - FILE * pFile = fopen( pFileName, "wb" ); - Vec_MemDump( pFile, p->vTtMem ); - fclose( pFile ); - printf( "Dumped %d %d-var truth tables into file \"%s\" (%.2f MB).\n", - Vec_MemEntryNum(p->vTtMem), p->pPars->nLutSize, pFileName, - 17.0 * Vec_MemEntryNum(p->vTtMem) / (1 << 20) ); - } if ( p->pPars->fCoarsen ) Gia_ManCleanMark0( p->pGia ); ABC_FREE( p->pGia->pRefs ); @@ -1689,6 +1689,8 @@ Gia_Man_t * Jf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) Jf_ManPropagateEla( p, 0 ); Jf_ManPrintStats( p, "Area " ); Jf_ManPropagateEla( p, 1 ); Jf_ManPrintStats( p, "Edge " ); } + if ( p->pPars->fVeryVerbose && p->pPars->fCutMin && !p->pPars->fFuncDsd ) + Jf_ManDumpTruthTables( p ); if ( p->pPars->fPureAig ) pNew = Jf_ManDeriveGia(p); else if ( p->pPars->fCutMin ) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dec99fc0..ad44f2e9 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -5388,6 +5388,7 @@ usage: Abc_Print( -2, "\t 3: Jake's hybrid semi-canonical form (fast)\n" ); Abc_Print( -2, "\t 4: Jake's hybrid semi-canonical form (high-effort)\n" ); Abc_Print( -2, "\t 5: new fast hybrid semi-canonical form\n" ); + Abc_Print( -2, "\t 6: new phase canonical form\n" ); Abc_Print( -2, "\t-N <num> : the number of support variables (binary files only) [default = unused]\n" ); Abc_Print( -2, "\t-d : toggle dumping resulting functions into a file [default = %s]\n", fDumpRes? "yes": "no" ); Abc_Print( -2, "\t-b : toggle dumping in binary format [default = %s]\n", fBinary? "yes": "no" ); diff --git a/src/base/abci/abcNpn.c b/src/base/abci/abcNpn.c index 7157b856..87a00651 100644 --- a/src/base/abci/abcNpn.c +++ b/src/base/abci/abcNpn.c @@ -151,9 +151,12 @@ int Abc_TruthNpnCountUniqueSort( Abc_TtStore_t * p ) SeeAlso [] ***********************************************************************/ -void Abc_TruthNpnPrint( char * pCanonPerm, unsigned uCanonPhase, int nVars ) +void Abc_TruthNpnPrint( char * pCanonPermInit, unsigned uCanonPhase, int nVars ) { - int i; + char pCanonPerm[16]; int i; + assert( nVars <= 16 ); + for ( i = 0; i < nVars; i++ ) + pCanonPerm[i] = pCanonPermInit ? pCanonPermInit[i] : 'a' + i; printf( " %c = ( ", Abc_InfoHasBit(&uCanonPhase, nVars) ? 'Z':'z' ); for ( i = 0; i < nVars; i++ ) printf( "%c%s", pCanonPerm[i] + ('A'-'a') * Abc_InfoHasBit(&uCanonPhase, pCanonPerm[i]-'a'), i == nVars-1 ? "":"," ); @@ -193,6 +196,8 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) pAlgoName = "Jake's hybrid good "; else if ( NpnType == 5 ) pAlgoName = "new hybrid fast "; + else if ( NpnType == 6 ) + pAlgoName = "new phase flipping "; assert( p->nVars <= 16 ); if ( pAlgoName ) @@ -273,6 +278,17 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" ); } } + else if ( NpnType == 6 ) + { + for ( i = 0; i < p->nFuncs; i++ ) + { + if ( fVerbose ) + printf( "%7d : ", i ); + uCanonPhase = Abc_TtCanonicizePhase( p->pFuncs[i], p->nVars ); + if ( fVerbose ) + Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(NULL, uCanonPhase, p->nVars), printf( "\n" ); + } + } else assert( 0 ); clk = Abc_Clock() - clk; printf( "Classes =%9d ", Abc_TruthNpnCountUnique(p) ); @@ -336,7 +352,7 @@ int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int f { if ( fVerbose ) printf( "Using truth tables from file \"%s\"...\n", pFileName ); - if ( NpnType >= 0 && NpnType <= 5 ) + if ( NpnType >= 0 && NpnType <= 6 ) Abc_TruthNpnTest( pFileName, NpnType, nVarNum, fDumpRes, fBinary, fVerbose ); else printf( "Unknown canonical form value (%d).\n", NpnType ); diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index 5561a2c6..7010bf2d 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1200,6 +1200,7 @@ static inline void Abc_TtImplementNpnConfig( word * pTruth, int nVars, char * pC for ( i = 0; i < nVars; i++ ) if ( (uCanonPhase >> i) & 1 ) Abc_TtFlip( pTruth, nWords, i ); + if ( pCanonPerm ) for ( i = 0; i < nVars; i++ ) { for ( k = i; k < nVars; k++ ) diff --git a/src/opt/dau/dau.h b/src/opt/dau/dau.h index 92641b71..cf2beb97 100644 --- a/src/opt/dau/dau.h +++ b/src/opt/dau/dau.h @@ -76,6 +76,7 @@ static inline int Dau_DsdReadVar( char * p ) { if ( *p == '!' ) p++; return *p /*=== dauCanon.c ==========================================================*/ extern unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm ); +extern unsigned Abc_TtCanonicizePhase( word * pTruth, int nVars ); /*=== dauDsd.c ==========================================================*/ extern int * Dau_DsdComputeMatches( char * p ); extern int Dau_DsdDecompose( word * pTruth, int nVarsInit, int fSplitPrime, int fWriteTruth, char * pRes ); diff --git a/src/opt/dau/dauCanon.c b/src/opt/dau/dauCanon.c index d37c44b1..26edca9b 100644 --- a/src/opt/dau/dauCanon.c +++ b/src/opt/dau/dauCanon.c @@ -941,6 +941,105 @@ unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm ) return uCanonPhase; } +/**Function************************************************************* + + Synopsis [Semi-canonical form computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_TtCanonicizePhaseVar6( word * pTruth, int nVars, int v ) +{ + int w, nWords = Abc_TtWordNum( nVars ); + int s, nStep = 1 << (v-6); + assert( v >= 6 ); + for ( w = nWords - 1, s = nWords - nStep; w > 0; w-- ) + { + if ( pTruth[w-nStep] == pTruth[w] ) + { + if ( w == s ) { w = s - nStep; s = w - nStep; } + continue; + } + if ( pTruth[w-nStep] > pTruth[w] ) + return -1; + for ( ; w > 0; w-- ) + { + ABC_SWAP( word, pTruth[w-nStep], pTruth[w] ); + if ( w == s ) { w = s - nStep; s = w - nStep; } + } + assert( w == -1 ); + return 1; + } + return 0; +} +static inline int Abc_TtCanonicizePhaseVar5( word * pTruth, int nVars, int v ) +{ + int w, nWords = Abc_TtWordNum( nVars ); + int Shift = 1 << v; + word Mask = s_Truths6[v]; + assert( v < 6 ); + for ( w = nWords - 1; w >= 0; w-- ) + { + if ( ((pTruth[w] << Shift) & Mask) == (pTruth[w] & Mask) ) + continue; + if ( ((pTruth[w] << Shift) & Mask) > (pTruth[w] & Mask) ) + return -1; +// Extra_PrintHex( stdout, (unsigned *)pTruth, nVars ); printf("\n" ); + for ( ; w >= 0; w-- ) + pTruth[w] = ((pTruth[w] << Shift) & Mask) | ((pTruth[w] & Mask) >> Shift); +// Extra_PrintHex( stdout, (unsigned *)pTruth, nVars ); printf( " changed %d", v ), printf("\n" ); + return 1; + } + return 0; +} +unsigned Abc_TtCanonicizePhase( word * pTruth, int nVars ) +{ + unsigned uCanonPhase = 0; + int v, nWords = Abc_TtWordNum( nVars ); +// static int Counter = 0; +// Counter++; + +#ifdef CANON_VERIFY + static word pCopy1[1024]; + static word pCopy2[1024]; + Abc_TtCopy( pCopy1, pTruth, nWords, 0 ); +#endif + + if ( (pTruth[nWords-1] >> 63) & 1 ) + { + Abc_TtNot( pTruth, nWords ); + uCanonPhase ^= (1 << nVars); + } + +// while ( 1 ) +// { +// unsigned uCanonPhase2 = uCanonPhase; + for ( v = nVars - 1; v >= 6; v-- ) + if ( Abc_TtCanonicizePhaseVar6( pTruth, nVars, v ) == 1 ) + uCanonPhase ^= 1 << v; + for ( ; v >= 0; v-- ) + if ( Abc_TtCanonicizePhaseVar5( pTruth, nVars, v ) == 1 ) + uCanonPhase ^= 1 << v; +// if ( uCanonPhase2 == uCanonPhase ) +// break; +// } + +// for ( v = 5; v >= 0; v-- ) +// assert( Abc_TtCanonicizePhaseVar5( pTruth, nVars, v ) != 1 ); + +#ifdef CANON_VERIFY + Abc_TtCopy( pCopy2, pTruth, nWords, 0 ); + Abc_TtImplementNpnConfig( pCopy2, nVars, NULL, uCanonPhase ); + if ( !Abc_TtEqual( pCopy1, pCopy2, nWords ) ) + printf( "Canonical form verification failed!\n" ); +#endif + return uCanonPhase; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// |