Commit d8c47d56 by Alan Mishchenko

Fixing mismatch in exact NPN computation (by XueGong Zhou)

parent 677c984e
......@@ -60,6 +60,7 @@ typedef enum {
typedef struct Dss_Man_t_ Dss_Man_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 ///
......@@ -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 Abc_TtHieMan_t * Abc_TtHieManStart( int nVars, int nLevels );
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 ==========================================================*/
extern int Abc_TtCountOnesInCofsQuick( word * pTruth, int nVars, int * pStore );
/*=== dauDsd.c ==========================================================*/
......
......@@ -292,13 +292,24 @@ static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar,
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
if (nVars < 6)
*pTruth &= (1ULL << (1 << nVars)) - 1;
#ifndef NDEBUG
if (nVars < 6) {
word nTruth = *pTruth;
Abc_TtNormalizeSmallTruth(&nTruth, nVars);
assert(*pTruth == nTruth);
}
#endif
}
......@@ -306,7 +317,7 @@ static inline int Abc_TtCountOnesInTruth( word * pTruth, int nVars )
{
int nWords = Abc_TtWordNum( nVars );
int k, Counter = 0;
Abc_TtNormalizeSmallTruth(pTruth, nVars);
Abc_TtVerifySmallTruth(pTruth, nVars);
for ( k = 0; k < nWords; k++ )
if ( pTruth[k] )
Counter += Abc_TtCountOnes( pTruth[k] );
......@@ -318,7 +329,7 @@ static inline void Abc_TtCountOnesInCofs( word * pTruth, int nVars, int * pStore
int i, k, Counter, nWords;
if ( nVars <= 6 )
{
Abc_TtNormalizeSmallTruth(pTruth, nVars);
Abc_TtVerifySmallTruth(pTruth, nVars);
for ( i = 0; i < nVars; i++ )
pStore[i] = Abc_TtCountOnes( pTruth[0] & s_Truths6Neg[i] );
return;
......@@ -1193,6 +1204,7 @@ int Abc_TtHieRetrieveOrInsert(Abc_TtHieMan_t * p, int level, word * pTruth, word
{
int i, iSpot, truthId;
word * pRepTruth;
if (!p) return -1;
if (level < 0) level += p->nLastLevel + 1;
if (level < 0 || level > p->nLastLevel) return -1;
iSpot = *Vec_MemHashLookup(p->vTtMem[level], pTruth);
......@@ -1224,7 +1236,8 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars,
{
int fNaive = 1;
int pStore[17];
static word pTruth[1024];
//static word pTruth[1024];
word * pTruth = pTruthInit;
unsigned uCanonPhase = 0;
int nOnes, nWords = Abc_TtWordNum( nVars );
int i, k;
......@@ -1237,7 +1250,7 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars,
return 0;
}
Abc_TtCopy( pTruth, pTruthInit, nWords, 0 );
//Abc_TtCopy( pTruth, pTruthInit, nWords, 0 );
for ( i = 0; i < nVars; i++ )
pCanonPerm[i] = i;
......@@ -1435,10 +1448,10 @@ unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word *
char pCanonPerm2[16];
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);
Abc_TtCopy(pTruth2, pTruth, nWords, 1);
Abc_TtNormalizeSmallTruth(pTruth2, nVars);
uCanonPhase1 = func(p, pTruth, nVars, pCanonPerm, flag);
uCanonPhase2 = func(p, pTruth2, nVars, pCanonPerm2, flag);
if (Abc_TtCompareRev(pTruth, pTruth2, nWords) <= 0)
......@@ -1455,10 +1468,10 @@ static int Abc_TtCannonVerify(word* pTruth, int nVars, char * pCanonPerm, unsign
int nWords = Abc_TtWordNum(nVars);
char pCanonPermCopy[16];
static word pCopy2[1024];
Abc_TtVerifySmallTruth(pTruth, nVars);
Abc_TtCopy(pCopy2, pTruth, nWords, 0);
memcpy(pCanonPermCopy, pCanonPerm, sizeof(char) * nVars);
Abc_TtImplementNpnConfig(pCopy2, nVars, pCanonPermCopy, uCanonPhase);
Abc_TtNormalizeSmallTruth(pCopy2, nVars);
return Abc_TtEqual(gpVerCopy, pCopy2, nWords);
#else
return 1;
......@@ -1573,7 +1586,7 @@ static void Abc_TgImplementPerm(Abc_TgMan_t* pMan, const char *pPermDest)
pRev[(int)pPerm[i]] = i;
Abc_TtImplementNpnConfig(pMan->pTruth, nVars, pRev, 0);
Abc_TtNormalizeSmallTruth(pMan->pTruth, nVars);
// Abc_TtVerifySmallTruth(pMan->pTruth, nVars);
for (i = 0; i < nVars; i++)
{
......@@ -1682,10 +1695,10 @@ static void Abc_TgCreateGroups(Abc_TgMan_t * pMan)
assert(nVars <= 16);
// normalize polarity
nOnes = Abc_TtCountOnesInTruth(pMan->pTruth, nVars);
if (nOnes > (1 << (nVars - 1)))
if (nOnes > nWords * 32)
{
Abc_TtNot(pMan->pTruth, nWords);
nOnes = (1 << nVars) - nOnes;
nOnes = nWords * 64 - nOnes;
pMan->uPhase |= (1 << nVars);
}
// normalize phase
......@@ -2105,15 +2118,12 @@ static int Abc_TgNextPermutation(Abc_TgMan_t * pMan)
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;
for (i = 0; i < n; i++)
if (d == 1U << i) return i;
assert(0);
return -1;
}
for (i = 0, a++; ; i++)
if (a & (1 << i)) return i;
}
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)
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);
}
}
......@@ -2155,19 +2165,26 @@ static void Abc_TgFullEnumeration(Abc_TgMan_t * pWork, Abc_TgMan_t * pBest)
Abc_TgFirstPermutation(pWork);
do Abc_TgPhaseEnumeration(pWork, pBest);
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)
{
int nWords = Abc_TtWordNum(nVars);
unsigned fExac = 0, fHash = 1U << 29;
unsigned fExac = 0, fHash = 1 << 29;
static word pCopy[1024];
Abc_TgMan_t tgMan, tgManCopy;
int iCost;
const int MaxCost = 84; // maximun posible cost for function with 16 inputs
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
Abc_TtCopy(gpVerCopy, pTruth, nWords, 0);
#endif
......@@ -2193,7 +2210,7 @@ unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char
}
else {
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;
Abc_TgManCopy(&tgManCopy, pCopy, &tgMan);
Abc_TgSimpleEnumeration(&tgMan);
......
......@@ -604,16 +604,8 @@ int Dau_PrintStats( int nNodes, int nInputs, int nVars, Vec_Int_t * vNodSup, int
fflush(stdout);
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,
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
char Perm[16] = {0};
int nVarsNew = Abc_TtMinBase( pCur, NULL, nVars, nInputs );
//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 Entry = Vec_MemHashInsert( vTtMem, pCur );
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