Commit d8c47d56 by Alan Mishchenko

Fixing mismatch in exact NPN computation (by XueGong Zhou)

parent 677c984e
...@@ -60,6 +60,7 @@ typedef enum { ...@@ -60,6 +60,7 @@ typedef enum {
typedef struct Dss_Man_t_ Dss_Man_t; typedef struct Dss_Man_t_ Dss_Man_t;
typedef struct Abc_TtHieMan_t_ Abc_TtHieMan_t; typedef struct Abc_TtHieMan_t_ Abc_TtHieMan_t;
typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS /// /// MACRO DEFINITIONS ///
...@@ -83,6 +84,9 @@ extern int Abc_TtCountOnesInCofsSimple( word * pTruth, int nVars, int ...@@ -83,6 +84,9 @@ extern int Abc_TtCountOnesInCofsSimple( word * pTruth, int nVars, int
extern unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int fExact ); extern unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int fExact );
extern Abc_TtHieMan_t * Abc_TtHieManStart( int nVars, int nLevels ); extern Abc_TtHieMan_t * Abc_TtHieManStart( int nVars, int nLevels );
extern void Abc_TtHieManStop(Abc_TtHieMan_t * p ); extern void Abc_TtHieManStop(Abc_TtHieMan_t * p );
extern unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
extern unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres);
extern unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t * p, word * pTruthInit, int nVars, char * pCanonPerm, int fExact);
/*=== dauCount.c ==========================================================*/ /*=== dauCount.c ==========================================================*/
extern int Abc_TtCountOnesInCofsQuick( word * pTruth, int nVars, int * pStore ); extern int Abc_TtCountOnesInCofsQuick( word * pTruth, int nVars, int * pStore );
/*=== dauDsd.c ==========================================================*/ /*=== dauDsd.c ==========================================================*/
......
...@@ -292,13 +292,24 @@ static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar, ...@@ -292,13 +292,24 @@ static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar,
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
#define DO_SMALL_TRUTHTABLE 0 void Abc_TtNormalizeSmallTruth(word * pTruth, int nVars)
{
if (nVars < 6) {
int shift, bits = (1 << nVars);
word base = *pTruth = *pTruth & ((((word)1) << bits) - 1);
for (shift = bits; shift < 64; shift += bits)
*pTruth |= base << shift;
}
}
static inline void Abc_TtNormalizeSmallTruth(word * pTruth, int nVars) inline void Abc_TtVerifySmallTruth(word * pTruth, int nVars)
{ {
#if DO_SMALL_TRUTHTABLE #ifndef NDEBUG
if (nVars < 6) if (nVars < 6) {
*pTruth &= (1ULL << (1 << nVars)) - 1; word nTruth = *pTruth;
Abc_TtNormalizeSmallTruth(&nTruth, nVars);
assert(*pTruth == nTruth);
}
#endif #endif
} }
...@@ -306,7 +317,7 @@ static inline int Abc_TtCountOnesInTruth( word * pTruth, int nVars ) ...@@ -306,7 +317,7 @@ static inline int Abc_TtCountOnesInTruth( word * pTruth, int nVars )
{ {
int nWords = Abc_TtWordNum( nVars ); int nWords = Abc_TtWordNum( nVars );
int k, Counter = 0; int k, Counter = 0;
Abc_TtNormalizeSmallTruth(pTruth, nVars); Abc_TtVerifySmallTruth(pTruth, nVars);
for ( k = 0; k < nWords; k++ ) for ( k = 0; k < nWords; k++ )
if ( pTruth[k] ) if ( pTruth[k] )
Counter += Abc_TtCountOnes( pTruth[k] ); Counter += Abc_TtCountOnes( pTruth[k] );
...@@ -318,7 +329,7 @@ static inline void Abc_TtCountOnesInCofs( word * pTruth, int nVars, int * pStore ...@@ -318,7 +329,7 @@ static inline void Abc_TtCountOnesInCofs( word * pTruth, int nVars, int * pStore
int i, k, Counter, nWords; int i, k, Counter, nWords;
if ( nVars <= 6 ) if ( nVars <= 6 )
{ {
Abc_TtNormalizeSmallTruth(pTruth, nVars); Abc_TtVerifySmallTruth(pTruth, nVars);
for ( i = 0; i < nVars; i++ ) for ( i = 0; i < nVars; i++ )
pStore[i] = Abc_TtCountOnes( pTruth[0] & s_Truths6Neg[i] ); pStore[i] = Abc_TtCountOnes( pTruth[0] & s_Truths6Neg[i] );
return; return;
...@@ -1193,6 +1204,7 @@ int Abc_TtHieRetrieveOrInsert(Abc_TtHieMan_t * p, int level, word * pTruth, word ...@@ -1193,6 +1204,7 @@ int Abc_TtHieRetrieveOrInsert(Abc_TtHieMan_t * p, int level, word * pTruth, word
{ {
int i, iSpot, truthId; int i, iSpot, truthId;
word * pRepTruth; word * pRepTruth;
if (!p) return -1;
if (level < 0) level += p->nLastLevel + 1; if (level < 0) level += p->nLastLevel + 1;
if (level < 0 || level > p->nLastLevel) return -1; if (level < 0 || level > p->nLastLevel) return -1;
iSpot = *Vec_MemHashLookup(p->vTtMem[level], pTruth); iSpot = *Vec_MemHashLookup(p->vTtMem[level], pTruth);
...@@ -1224,7 +1236,8 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, ...@@ -1224,7 +1236,8 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars,
{ {
int fNaive = 1; int fNaive = 1;
int pStore[17]; int pStore[17];
static word pTruth[1024]; //static word pTruth[1024];
word * pTruth = pTruthInit;
unsigned uCanonPhase = 0; unsigned uCanonPhase = 0;
int nOnes, nWords = Abc_TtWordNum( nVars ); int nOnes, nWords = Abc_TtWordNum( nVars );
int i, k; int i, k;
...@@ -1237,7 +1250,7 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, ...@@ -1237,7 +1250,7 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars,
return 0; return 0;
} }
Abc_TtCopy( pTruth, pTruthInit, nWords, 0 ); //Abc_TtCopy( pTruth, pTruthInit, nWords, 0 );
for ( i = 0; i < nVars; i++ ) for ( i = 0; i < nVars; i++ )
pCanonPerm[i] = i; pCanonPerm[i] = i;
...@@ -1435,10 +1448,10 @@ unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * ...@@ -1435,10 +1448,10 @@ unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word *
char pCanonPerm2[16]; char pCanonPerm2[16];
static word pTruth2[1024]; static word pTruth2[1024];
if (Abc_TtCountOnesInTruth(pTruth, nVars) != (1 << (nVars - 1))) Abc_TtNormalizeSmallTruth(pTruth, nVars);
if (Abc_TtCountOnesInTruth(pTruth, nVars) != nWords * 32)
return func(p, pTruth, nVars, pCanonPerm, flag); return func(p, pTruth, nVars, pCanonPerm, flag);
Abc_TtCopy(pTruth2, pTruth, nWords, 1); Abc_TtCopy(pTruth2, pTruth, nWords, 1);
Abc_TtNormalizeSmallTruth(pTruth2, nVars);
uCanonPhase1 = func(p, pTruth, nVars, pCanonPerm, flag); uCanonPhase1 = func(p, pTruth, nVars, pCanonPerm, flag);
uCanonPhase2 = func(p, pTruth2, nVars, pCanonPerm2, flag); uCanonPhase2 = func(p, pTruth2, nVars, pCanonPerm2, flag);
if (Abc_TtCompareRev(pTruth, pTruth2, nWords) <= 0) if (Abc_TtCompareRev(pTruth, pTruth2, nWords) <= 0)
...@@ -1455,10 +1468,10 @@ static int Abc_TtCannonVerify(word* pTruth, int nVars, char * pCanonPerm, unsign ...@@ -1455,10 +1468,10 @@ static int Abc_TtCannonVerify(word* pTruth, int nVars, char * pCanonPerm, unsign
int nWords = Abc_TtWordNum(nVars); int nWords = Abc_TtWordNum(nVars);
char pCanonPermCopy[16]; char pCanonPermCopy[16];
static word pCopy2[1024]; static word pCopy2[1024];
Abc_TtVerifySmallTruth(pTruth, nVars);
Abc_TtCopy(pCopy2, pTruth, nWords, 0); Abc_TtCopy(pCopy2, pTruth, nWords, 0);
memcpy(pCanonPermCopy, pCanonPerm, sizeof(char) * nVars); memcpy(pCanonPermCopy, pCanonPerm, sizeof(char) * nVars);
Abc_TtImplementNpnConfig(pCopy2, nVars, pCanonPermCopy, uCanonPhase); Abc_TtImplementNpnConfig(pCopy2, nVars, pCanonPermCopy, uCanonPhase);
Abc_TtNormalizeSmallTruth(pCopy2, nVars);
return Abc_TtEqual(gpVerCopy, pCopy2, nWords); return Abc_TtEqual(gpVerCopy, pCopy2, nWords);
#else #else
return 1; return 1;
...@@ -1573,7 +1586,7 @@ static void Abc_TgImplementPerm(Abc_TgMan_t* pMan, const char *pPermDest) ...@@ -1573,7 +1586,7 @@ static void Abc_TgImplementPerm(Abc_TgMan_t* pMan, const char *pPermDest)
pRev[(int)pPerm[i]] = i; pRev[(int)pPerm[i]] = i;
Abc_TtImplementNpnConfig(pMan->pTruth, nVars, pRev, 0); Abc_TtImplementNpnConfig(pMan->pTruth, nVars, pRev, 0);
Abc_TtNormalizeSmallTruth(pMan->pTruth, nVars); // Abc_TtVerifySmallTruth(pMan->pTruth, nVars);
for (i = 0; i < nVars; i++) for (i = 0; i < nVars; i++)
{ {
...@@ -1682,10 +1695,10 @@ static void Abc_TgCreateGroups(Abc_TgMan_t * pMan) ...@@ -1682,10 +1695,10 @@ static void Abc_TgCreateGroups(Abc_TgMan_t * pMan)
assert(nVars <= 16); assert(nVars <= 16);
// normalize polarity // normalize polarity
nOnes = Abc_TtCountOnesInTruth(pMan->pTruth, nVars); nOnes = Abc_TtCountOnesInTruth(pMan->pTruth, nVars);
if (nOnes > (1 << (nVars - 1))) if (nOnes > nWords * 32)
{ {
Abc_TtNot(pMan->pTruth, nWords); Abc_TtNot(pMan->pTruth, nWords);
nOnes = (1 << nVars) - nOnes; nOnes = nWords * 64 - nOnes;
pMan->uPhase |= (1 << nVars); pMan->uPhase |= (1 << nVars);
} }
// normalize phase // normalize phase
...@@ -2105,15 +2118,12 @@ static int Abc_TgNextPermutation(Abc_TgMan_t * pMan) ...@@ -2105,15 +2118,12 @@ static int Abc_TgNextPermutation(Abc_TgMan_t * pMan)
static inline unsigned grayCode(unsigned a) { return a ^ (a >> 1); } static inline unsigned grayCode(unsigned a) { return a ^ (a >> 1); }
static int grayFlip(unsigned a, int n) static int grayFlip(unsigned a)
{ {
unsigned d = grayCode(a) ^ grayCode(a + 1);
int i; int i;
for (i = 0; i < n; i++) for (i = 0, a++; ; i++)
if (d == 1U << i) return i; if (a & (1 << i)) return i;
assert(0); }
return -1;
}
static inline void Abc_TgSaveBest(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest) static inline void Abc_TgSaveBest(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest)
{ {
...@@ -2141,7 +2151,7 @@ static void Abc_TgPhaseEnumeration(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest) ...@@ -2141,7 +2151,7 @@ static void Abc_TgPhaseEnumeration(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest)
for (i = 0; i < (1 << n) - 1; i++) for (i = 0; i < (1 << n) - 1; i++)
{ {
Abc_TgFlipSymGroupByVar(pMan, pFGrps[grayFlip(i, n)]); Abc_TgFlipSymGroupByVar(pMan, pFGrps[grayFlip(i)]);
Abc_TgSaveBest(pMan, pBest); Abc_TgSaveBest(pMan, pBest);
} }
} }
...@@ -2155,19 +2165,26 @@ static void Abc_TgFullEnumeration(Abc_TgMan_t * pWork, Abc_TgMan_t * pBest) ...@@ -2155,19 +2165,26 @@ static void Abc_TgFullEnumeration(Abc_TgMan_t * pWork, Abc_TgMan_t * pBest)
Abc_TgFirstPermutation(pWork); Abc_TgFirstPermutation(pWork);
do Abc_TgPhaseEnumeration(pWork, pBest); do Abc_TgPhaseEnumeration(pWork, pBest);
while (Abc_TgNextPermutation(pWork)); while (Abc_TgNextPermutation(pWork));
pBest->uPhase |= 1U << 30; pBest->uPhase |= 1 << 30;
} }
unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres) unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres)
{ {
int nWords = Abc_TtWordNum(nVars); int nWords = Abc_TtWordNum(nVars);
unsigned fExac = 0, fHash = 1U << 29; unsigned fExac = 0, fHash = 1 << 29;
static word pCopy[1024]; static word pCopy[1024];
Abc_TgMan_t tgMan, tgManCopy; Abc_TgMan_t tgMan, tgManCopy;
int iCost; int iCost;
const int MaxCost = 84; // maximun posible cost for function with 16 inputs const int MaxCost = 84; // maximun posible cost for function with 16 inputs
const int doHigh = iThres / 100, iEnumThres = iThres % 100; const int doHigh = iThres / 100, iEnumThres = iThres % 100;
// handle constant
if ( nVars == 0 ) {
Abc_TtClear( pTruth, nWords );
return 0;
}
Abc_TtVerifySmallTruth(pTruth, nVars);
#ifdef CANON_VERIFY #ifdef CANON_VERIFY
Abc_TtCopy(gpVerCopy, pTruth, nWords, 0); Abc_TtCopy(gpVerCopy, pTruth, nWords, 0);
#endif #endif
...@@ -2193,7 +2210,7 @@ unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char ...@@ -2193,7 +2210,7 @@ unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char
} }
else { else {
iCost = Abc_TgEnumerationCost(&tgMan); iCost = Abc_TgEnumerationCost(&tgMan);
if (iCost < iEnumThres) fExac = 1U << 30; if (iCost < iEnumThres) fExac = 1 << 30;
if (Abc_TtHieRetrieveOrInsert(p, -3, pTruth, pTruth) > 0) return fHash + fExac; if (Abc_TtHieRetrieveOrInsert(p, -3, pTruth, pTruth) > 0) return fHash + fExac;
Abc_TgManCopy(&tgManCopy, pCopy, &tgMan); Abc_TgManCopy(&tgManCopy, pCopy, &tgMan);
Abc_TgSimpleEnumeration(&tgMan); Abc_TgSimpleEnumeration(&tgMan);
......
...@@ -604,16 +604,8 @@ int Dau_PrintStats( int nNodes, int nInputs, int nVars, Vec_Int_t * vNodSup, int ...@@ -604,16 +604,8 @@ int Dau_PrintStats( int nNodes, int nInputs, int nVars, Vec_Int_t * vNodSup, int
fflush(stdout); fflush(stdout);
return nNew; return nNew;
} }
int Dau_RunNpn( Abc_TtHieMan_t * pMan, word * pTruth, int nVars, char * pCanonPerm )
{
typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres);
if ( nVars < 6 )
return Abc_TtCanonicizeWrap( Abc_TtCanonicizeAda, NULL, pTruth, nVars, pCanonPerm, 99 );
else
return Abc_TtCanonicizeWrap( Abc_TtCanonicizeAda, pMan, pTruth, nVars, pCanonPerm, 99 );
}
int Dau_InsertFunction( Abc_TtHieMan_t * pMan, word * pCur, int nNodes, int nInputs, int nVars0, int nVars, int Dau_InsertFunction( Abc_TtHieMan_t * pMan, word * pCur, int nNodes, int nInputs, int nVars0, int nVars,
Vec_Mem_t * vTtMem, Vec_Int_t * vNodSup, int nFronts, abctime clk ) Vec_Mem_t * vTtMem, Vec_Int_t * vNodSup, int nFronts, abctime clk )
{ {
...@@ -621,7 +613,7 @@ int Dau_InsertFunction( Abc_TtHieMan_t * pMan, word * pCur, int nNodes, int nInp ...@@ -621,7 +613,7 @@ int Dau_InsertFunction( Abc_TtHieMan_t * pMan, word * pCur, int nNodes, int nInp
char Perm[16] = {0}; char Perm[16] = {0};
int nVarsNew = Abc_TtMinBase( pCur, NULL, nVars, nInputs ); int nVarsNew = Abc_TtMinBase( pCur, NULL, nVars, nInputs );
//unsigned Phase = Abc_TtCanonicizeHie( pMan, pCur, nVarsNew, Perm, 1 ); //unsigned Phase = Abc_TtCanonicizeHie( pMan, pCur, nVarsNew, Perm, 1 );
unsigned Phase = Dau_RunNpn( pMan, pCur, nInputs, Perm ); unsigned Phase = Abc_TtCanonicizeWrap( Abc_TtCanonicizeAda, pMan, pCur, nVarsNew, Perm, 99 );
int nEntries = Vec_MemEntryNum(vTtMem); int nEntries = Vec_MemEntryNum(vTtMem);
int Entry = Vec_MemHashInsert( vTtMem, pCur ); int Entry = Vec_MemHashInsert( vTtMem, pCur );
if ( nEntries == Vec_MemEntryNum(vTtMem) ) // found in the table - not new if ( nEntries == Vec_MemEntryNum(vTtMem) ) // found in the table - not new
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment