diff options
Diffstat (limited to 'src/misc')
-rw-r--r-- | src/misc/extra/extra.h | 1 | ||||
-rw-r--r-- | src/misc/extra/extraUtilFile.c | 17 | ||||
-rw-r--r-- | src/misc/extra/extraUtilMaj.c | 386 | ||||
-rw-r--r-- | src/misc/extra/extraUtilPath.c | 607 | ||||
-rw-r--r-- | src/misc/extra/module.make | 2 | ||||
-rw-r--r-- | src/misc/util/utilTruth.h | 97 | ||||
-rw-r--r-- | src/misc/vec/vecMem.h | 14 |
7 files changed, 1124 insertions, 0 deletions
diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h index 3dee5f4e..6c0fd74a 100644 --- a/src/misc/extra/extra.h +++ b/src/misc/extra/extra.h @@ -119,6 +119,7 @@ extern char * Extra_StringAppend( char * pStrGiven, char * pStrAdd ); extern void Extra_StringClean( char * pStrGiven, char * pCharKeep ); extern unsigned Extra_ReadBinary( char * Buffer ); extern void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits ); +extern void Extra_PrintBinary2( FILE * pFile, unsigned Sign[], int nBits ); extern int Extra_ReadHex( unsigned Sign[], char * pString, int nDigits ); extern int Extra_ReadHexadecimal( unsigned Sign[], char * pString, int nVars ); extern void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars ); diff --git a/src/misc/extra/extraUtilFile.c b/src/misc/extra/extraUtilFile.c index 6568c305..8f60f421 100644 --- a/src/misc/extra/extraUtilFile.c +++ b/src/misc/extra/extraUtilFile.c @@ -508,6 +508,23 @@ void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits ) // fprintf( pFile, "\n" ); } +void Extra_PrintBinary2( FILE * pFile, unsigned Sign[], int nBits ) +{ + int Remainder, nWords; + int w, i; + + Remainder = (nBits%(sizeof(unsigned)*8)); + nWords = (nBits/(sizeof(unsigned)*8)) + (Remainder>0); + + for ( w = 0; w < nWords; w++ ) + { + int Limit = w == nWords-1 ? Remainder : 32; + for ( i = 0; i < Limit; i++ ) + fprintf( pFile, "%c", '0' + (int)((Sign[w] & (1<<i)) > 0) ); + } + +// fprintf( pFile, "\n" ); +} /**Function************************************************************* diff --git a/src/misc/extra/extraUtilMaj.c b/src/misc/extra/extraUtilMaj.c new file mode 100644 index 00000000..8bdb0818 --- /dev/null +++ b/src/misc/extra/extraUtilMaj.c @@ -0,0 +1,386 @@ +/**CFile**************************************************************** + + FileName [extraUtilMaj.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [extra] + + Synopsis [Path enumeration.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: extraUtilMaj.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "misc/vec/vec.h" +#include "misc/vec/vecMem.h" +#include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" +#include "opt/dau/dau.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gem_Man_t_ Gem_Man_t; +typedef struct Gem_Obj_t_ Gem_Obj_t; + +struct Gem_Man_t_ +{ + int nVars; // max variable count + int nWords; // truth tabel word count + int nObjsAlloc; // allocated objects + int nObjs; // used objects + Gem_Obj_t * pObjs; // function objects + Vec_Mem_t * vTtMem; // truth table memory and hash table + word ** pTtElems; // elementary truth tables + int fVerbose; +}; + +struct Gem_Obj_t_ // 8 bytes +{ + unsigned nVars : 4; // variable count + unsigned nNodes : 4; // node count + unsigned History : 8; // (i < j) ? {vi, vj} : {vi, 0} + unsigned Groups : 16; // mask with last vars in each symmetric group + int Predec; // predecessor +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gem_PrintNode( Gem_Man_t * p, int f, char * pLabel, int fUpdate ) +{ + Gem_Obj_t * pObj = p->pObjs + f; + int GroupsMod = pObj->Groups; + if ( !p->fVerbose ) + return; + printf( "Node %6d : %s Pred = %6d Vars = %d Nodes = %d History = %d%d Profile: ", + f, pLabel, pObj->Predec, pObj->nVars, pObj->nNodes, pObj->History & 0xF, pObj->History >> 4 ); + Extra_PrintBinary2( stdout, (unsigned*)&GroupsMod, p->nVars ); printf("%s\n", fUpdate?" *":""); +} +Gem_Man_t * Gem_ManAlloc( int nVars, int fVerbose ) +{ + Gem_Man_t * p; + assert( nVars <= 16 ); + p = ABC_CALLOC( Gem_Man_t, 1 ); + p->nVars = nVars; + p->nWords = Abc_TtWordNum( nVars ); + p->nObjsAlloc = 10000000; + p->nObjs = 2; + p->pObjs = ABC_CALLOC( Gem_Obj_t, p->nObjsAlloc ); + p->pObjs[1].nVars = p->pObjs[1].Groups = 1; // buffer + p->vTtMem = Vec_MemAllocForTT( nVars, 0 ); + p->pTtElems = (word **)Extra_ArrayAlloc( nVars + 4, p->nWords, sizeof(word) ); + p->fVerbose = fVerbose; + Abc_TtElemInit( p->pTtElems, nVars ); + Gem_PrintNode( p, 1, "Original", 0 ); + return p; +} +int Gem_ManFree( Gem_Man_t * p ) +{ + Vec_MemHashFree( p->vTtMem ); + Vec_MemFree( p->vTtMem ); + ABC_FREE( p->pTtElems ); + ABC_FREE( p->pObjs ); + ABC_FREE( p ); + return 1; +} +void Gem_ManRealloc( Gem_Man_t * p ) +{ + int nObjNew = Abc_MinInt( 2 * p->nObjsAlloc, 0x7FFFFFFF ); + assert( p->nObjs == p->nObjsAlloc ); + if ( p->nObjs == 0x7FFFFFFF ) + printf( "Hard limit on the number of nodes (0x7FFFFFFF) is reached. Quitting...\n" ), exit(1); + assert( p->nObjs < nObjNew ); + printf("Extending object storage: %d -> %d.\n", p->nObjsAlloc, nObjNew ); + p->pObjs = ABC_REALLOC( Gem_Obj_t, p->pObjs, nObjNew ); + memset( p->pObjs + p->nObjsAlloc, 0, sizeof(Gem_Obj_t) * (nObjNew - p->nObjsAlloc) ); + p->nObjsAlloc = nObjNew; +} + +/**Function************************************************************* + + Synopsis [Derive groups using symmetry info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_GroupsDerive( word * pTruth, int nVars, word * pCof0, word * pCof1 ) +{ + int v, Res = 1 << (nVars-1); + for ( v = 0; v < nVars-1; v++ ) + if ( !Abc_TtVarsAreSymmetric(pTruth, nVars, v, v+1, pCof0, pCof1) ) + Res |= (1 << v); + return Res; +} + +/**Function************************************************************* + + Synopsis [Extends function f by replacing var i with a new gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_GroupVarRemove( int Groups, int i ) // remove i-th var +{ + int Mask = i ? Abc_InfoMask( i ) : 0; + assert( i >= 0 ); + assert( (Groups >> i) & 1 ); + return (Groups & Mask) | ((Groups & ~Mask) >> 1); +} +int Gem_GroupVarsInsert1( int Groups, int i, int fGroup ) // insert one bit after i +{ + int Mask = i+1 ? Abc_InfoMask( i+1 ) : 0; + assert( i+1 >= 0 ); + assert( !fGroup || i == -1 || ((Groups >> i) & 1) ); + assert( fGroup == 0 || fGroup == 1 ); + return (Groups & Mask) | ((Groups & ~Mask) << 1) | (fGroup << (i+1)); +} +int Gem_GroupVarsInsert3( int Groups, int i ) // insert group of 3 bits after i +{ + int Mask = i+1 ? Abc_InfoMask( i+1 ) : 0; + assert( i+1 >= 0 ); + assert( i == -1 || (Groups >> i) & 1 ); + return (Groups & Mask) | ((Groups & ~Mask) << 3) | (0x4 << (i+1)); +} +int Gem_GroupUnpack( int Groups, int * pVars ) +{ + int v, nGroups = 0; + for ( v = 0; Groups; v++, Groups >>= 1 ) + if ( Groups & 1 ) + pVars[nGroups++] = v; + return nGroups; +} +int Gem_FuncFindPlace( word * pTruth, int nWords, int Groups, word * pBest, int fOneVar ) +{ + int pLast[16], nGroups = Gem_GroupUnpack( Groups, pLast ); + int g, v, Value, BestPlace = nGroups ? pLast[nGroups - 1] : -1; + assert( nGroups >= 0 ); + Abc_TtCopy( pBest, pTruth, nWords, 0 ); + for ( g = nGroups - 1; g >= 0; g-- ) + { + int Limit = g ? pLast[g-1] : -1; + for ( v = pLast[g]; v > Limit; v-- ) + { + Abc_TtSwapAdjacent( pTruth, nWords, v+0 ); + if ( fOneVar ) + continue; + Abc_TtSwapAdjacent( pTruth, nWords, v+1 ); + Abc_TtSwapAdjacent( pTruth, nWords, v+2 ); + } + Value = memcmp(pBest, pTruth, sizeof(word)*nWords); + if ( Value < 0 ) + { + Abc_TtCopy( pBest, pTruth, nWords, 0 ); + BestPlace = Limit; + } + } + return BestPlace; +} +void Gem_FuncExpand( Gem_Man_t * p, int f, int i ) +{ + Gem_Obj_t * pNew = p->pObjs + p->nObjs, * pObj = p->pObjs + f; + word * pTruth = Vec_MemReadEntry( p->vTtMem, f ); + word * pResult = p->pTtElems[p->nVars]; + word * pCofs[2] = { p->pTtElems[p->nVars+2], p->pTtElems[p->nVars+3] }; + int v, iFunc; + char pCanonPermC[16]; + assert( i < (int)pObj->nVars ); + assert( (int)pObj->nVars + 2 <= p->nVars ); + Abc_TtCopy( pResult, pTruth, p->nWords, 0 ); + // move i variable to the end + for ( v = i; v < (int)pObj->nVars-1; v++ ) + Abc_TtSwapAdjacent( pResult, p->nWords, v ); + // create new symmetric group + assert( v == (int)pObj->nVars-1 ); + Abc_TtCofactor0p( pCofs[0], pResult, p->nWords, v ); + Abc_TtCofactor1p( pCofs[1], pResult, p->nWords, v ); + Abc_TtMaj( pResult, p->pTtElems[v], p->pTtElems[v+1], p->pTtElems[v+2], p->nWords ); + Abc_TtMux( pResult, pResult, pCofs[1], pCofs[0], p->nWords ); + // canonicize + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars + 2 ); printf("\n"); + Abc_TtCanonicizePerm( pResult, pObj->nVars + 2, pCanonPermC ); + Abc_TtStretch6( pResult, Abc_MaxInt(6, pObj->nVars+2), p->nVars ); + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars + 2 ); printf("\n\n"); + iFunc = Vec_MemHashInsert( p->vTtMem, pResult ); + if ( iFunc < p->nObjs ) + return; + assert( iFunc == p->nObjs ); + pNew->nVars = pObj->nVars + 2; + pNew->nNodes = pObj->nNodes + 1; + pNew->Groups = Gem_GroupsDerive( pResult, pNew->nVars, pCofs[0], pCofs[1] ); + pNew->Predec = f; + pNew->History = i; + Gem_PrintNode( p, iFunc, "Expand ", 0 ); + + assert( p->nObjs < p->nObjsAlloc ); + if ( ++p->nObjs == p->nObjsAlloc ) + Gem_ManRealloc( p ); +} + +/**Function************************************************************* + + Synopsis [Reduces function f by crossbaring variables i and j.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_FuncCheckMajority( Gem_Man_t * p, int f ) +{ + Gem_Obj_t * pObj = p->pObjs + f; + word * pTruth = Vec_MemReadEntry( p->vTtMem, f ); + int Polar = Abc_TtIsFullySymmetric( pTruth, pObj->nVars ); + if ( Polar != -1 ) + { + int nHalfVars = (pObj->nVars+1) >> 1; + int Mask = Abc_Tt6Mask( nHalfVars ); + printf( "Found symmetric %d-variable function: ", pObj->nVars ); + Extra_PrintBinary2( stdout, (unsigned *)&Polar, pObj->nVars + 1 ); + printf( " " ); + if ( (pObj->nVars & 1) && Polar == (Mask << nHalfVars) ) + { + printf( "This is majority-%d.\n", pObj->nVars ); + return 0; + } + printf( "\n" ); + } + return 0; +} +int Gem_FuncReduce( Gem_Man_t * p, int f, int i, int j ) +{ + Gem_Obj_t * pNew = p->pObjs + p->nObjs, * pObj = p->pObjs + f; + word * pTruth = Vec_MemReadEntry( p->vTtMem, f ); + word * pResult = p->pTtElems[p->nVars]; + word * pCofs[2] = { p->pTtElems[p->nVars+2], p->pTtElems[p->nVars+3] }; + int v, iFunc; + char pCanonPermC[16]; + assert( i < j && j < 16 ); + Abc_TtCopy( pResult, pTruth, p->nWords, 0 ); + // move j variable to the end + for ( v = j; v < (int)pObj->nVars-1; v++ ) + Abc_TtSwapAdjacent( pResult, p->nWords, v ); + assert( v == (int)pObj->nVars-1 ); + // move i variable to the end + for ( v = i; v < (int)pObj->nVars-2; v++ ) + Abc_TtSwapAdjacent( pResult, p->nWords, v ); + assert( v == (int)pObj->nVars-2 ); + // create new variable + Abc_TtCofactor0p( pCofs[0], pResult, p->nWords, v+1 ); + Abc_TtCofactor1p( pCofs[1], pResult, p->nWords, v+1 ); + Abc_TtCofactor0( pCofs[0], p->nWords, v ); + Abc_TtCofactor1( pCofs[1], p->nWords, v ); + Abc_TtMux( pResult, p->pTtElems[v], pCofs[1], pCofs[0], p->nWords ); + // canonicize + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars - 1 ); printf("\n"); + Abc_TtCanonicizePerm( pResult, pObj->nVars - 1, pCanonPermC ); + Abc_TtStretch6( pResult, Abc_MaxInt(6, pObj->nVars-1), p->nVars ); + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars - 1 ); printf("\n\n"); + iFunc = Vec_MemHashInsert( p->vTtMem, pResult ); + if ( iFunc < p->nObjs ) + return 0; + assert( iFunc == p->nObjs ); + pNew->nVars = pObj->nVars - 1; + pNew->nNodes = pObj->nNodes; + pNew->Groups = Gem_GroupsDerive( pResult, pNew->nVars, pCofs[0], pCofs[1] ); + pNew->Predec = f; + pNew->History = (j << 4) | i; + Gem_PrintNode( p, iFunc, "Crossbar", 0 ); + Gem_FuncCheckMajority( p, iFunc ); + + assert( p->nObjs < p->nObjsAlloc ); + if ( ++p->nObjs == p->nObjsAlloc ) + Gem_ManRealloc( p ); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_Enumerate( int nVars, int fDump, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gem_Man_t * p = Gem_ManAlloc( nVars, fVerbose ); + int v, f, i, j, nObjsStop = 1; + for ( v = 1; v <= nVars-2; v++ ) + { + // expand functions by adding a gate + int nObjsStopPrev = nObjsStop; + nObjsStop = p->nObjs; + printf( "Expanding var %2d (functions = %10d) ", v, p->nObjs ); + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + for ( f = 0; f < nObjsStop; f++ ) + if ( v == (int)p->pObjs[f].nVars || (v > (int)p->pObjs[f].nVars && f >= nObjsStopPrev) ) + for ( i = 0; i < v; i++ ) + if ( (int)p->pObjs[f].Groups & (1 << i) ) + Gem_FuncExpand( p, f, i ); + // reduce functions by adding a crossbar + printf( "Connecting var %2d (functions = %10d) ", v, p->nObjs ); + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + for ( f = nObjsStop; f < p->nObjs; f++ ) + for ( i = 0; i < (int)p->pObjs[f].nVars; i++ ) + if ( (int)p->pObjs[f].Groups & (1 << i) ) + for ( j = i+1; j < (int)p->pObjs[f].nVars; j++ ) + if ( (int)p->pObjs[f].Groups & (1 << j) ) + if ( Gem_FuncReduce( p, f, i, j ) ) + return Gem_ManFree( p ); + } + printf( "Finished (functions = %10d) ", p->nObjs ); + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + if ( fDump ) Vec_MemDumpTruthTables( p->vTtMem, "enum", nVars ); + Gem_ManFree( p ); + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/misc/extra/extraUtilPath.c b/src/misc/extra/extraUtilPath.c new file mode 100644 index 00000000..c7231a05 --- /dev/null +++ b/src/misc/extra/extraUtilPath.c @@ -0,0 +1,607 @@ +/**CFile**************************************************************** + + FileName [extraUtilPath.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [extra] + + Synopsis [Path enumeration.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: extraUtilPath.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "aig/gia/gia.h" +#include "misc/vec/vecHsh.h" + +#include <math.h> +#include "sat/bmc/bmc.h" +#include "sat/cnf/cnf.h" +#include "sat/bsat/satStore.h" +#include "misc/extra/extra.h" + + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes AIG representing the set of all paths in the graph.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeVarX( int nSize, int y, int x ) +{ + return Abc_Var2Lit( nSize * y + x, 0 ); +} +int Abc_NodeVarY( int nSize, int y, int x ) +{ + return Abc_Var2Lit( nSize * (nSize + 1) + nSize * x + y, 0 ); +} + +Gia_Man_t * Abc_EnumeratePaths( int nSize ) +{ + Gia_Man_t * pTemp, * pGia = Gia_ManStart( 10000 ); + int * pNodes = ABC_CALLOC( int, nSize+1 ); + int x, y, nVars = 2*nSize*(nSize+1); + for ( x = 0; x < nVars; x++ ) + Gia_ManAppendCi( pGia ); + Gia_ManHashAlloc( pGia ); + // y = 0; x = 0; + pNodes[0] = 1; + // y = 0; x > 0 + for ( x = 1; x <= nSize; x++ ) + pNodes[x] = Gia_ManHashAnd( pGia, pNodes[x-1], Abc_NodeVarX(nSize, 0, x) ); + // y > 0; x >= 0 + for ( y = 1; y <= nSize; y++ ) + { + // y > 0; x = 0 + pNodes[0] = Gia_ManHashAnd( pGia, pNodes[0], Abc_NodeVarY(nSize, y, 0) ); + // y > 0; x > 0 + for ( x = 1; x <= nSize; x++ ) + { + int iHor = Gia_ManHashAnd( pGia, pNodes[x-1], Abc_NodeVarX(nSize, y, x) ); + int iVer = Gia_ManHashAnd( pGia, pNodes[x], Abc_NodeVarY(nSize, y, x) ); + pNodes[x] = Gia_ManHashOr( pGia, iHor, iVer ); + } + } + Gia_ManAppendCo( pGia, pNodes[nSize] ); + pGia = Gia_ManCleanup( pTemp = pGia ); + Gia_ManStop( pTemp ); + ABC_FREE( pNodes ); + return pGia; +} +void Abc_EnumeratePathsTest() +{ + int nSize = 2; + Gia_Man_t * pGia = Abc_EnumeratePaths( nSize ); + Gia_AigerWrite( pGia, "testpath.aig", 0, 0 ); + Gia_ManStop( pGia ); +} + + +/**Function************************************************************* + + Synopsis [Generate NxN grid.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_GraphGrid( int n ) +{ + Vec_Int_t * vEdges = Vec_IntAlloc( 4*n*(n-1) ); // two nodes per edge + int i, k; + for ( i = 0; i < n; i++ ) + { + for ( k = 0; k < n-1; k++ ) + Vec_IntPushTwo( vEdges, i*n+k, i*n+k+1 ); + if ( i == n-1 ) break; + for ( k = 0; k < n; k++ ) + Vec_IntPushTwo( vEdges, i*n+k, i*n+k+n ); + } + //Vec_IntPrint( vEdges ); + return vEdges; +} +Vec_Int_t * Abc_GraphNodeLife( Vec_Int_t * vEdges, int n ) +{ + Vec_Int_t * vLife = Vec_IntStartFull( 2*n*n ); // start/stop per node + int One, Two, i; + Vec_IntForEachEntryDouble( vEdges, One, Two, i ) + { + if ( Vec_IntEntry(vLife, 2*One) == -1 ) + Vec_IntWriteEntry(vLife, 2*One, i/2); + if ( Vec_IntEntry(vLife, 2*Two) == -1 ) + Vec_IntWriteEntry(vLife, 2*Two, i/2); + Vec_IntWriteEntry(vLife, 2*One+1, i/2); + Vec_IntWriteEntry(vLife, 2*Two+1, i/2); + } + //Vec_IntPrint( vLife ); + return vLife; +} +Vec_Wec_t * Abc_GraphFrontiers( Vec_Int_t * vEdges, Vec_Int_t * vLife ) +{ + Vec_Wec_t * vFronts = Vec_WecAlloc( Vec_IntSize(vEdges)/2 ); // front for each edge + Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(vLife)/2 ); + int e, n; + Vec_WecPushLevel(vFronts); + for ( e = 0; e < Vec_IntSize(vEdges)/2; e++ ) + { + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + for ( n = 0; n < 2; n++ ) + if ( Vec_IntEntry(vLife, 2*pNodes[n]) == e ) // first time + Vec_IntPush( vTemp, pNodes[n] ); + else if ( Vec_IntEntry(vLife, 2*pNodes[n]+1) == e ) // last time + Vec_IntRemove( vTemp, pNodes[n] ); + Vec_IntAppend( Vec_WecPushLevel(vFronts), vTemp ); + } + //Vec_WecPrint( vFronts, 0 ); + Vec_IntFree( vTemp ); + return vFronts; +} + +/**Function************************************************************* + + Synopsis [Print grid.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_GraphPathPrint4( int * pBuffer, Vec_Int_t * vEdges ) +{ + char Box[13][13]; + int x, y; + int e, nEdges = Vec_IntSize(vEdges)/2; + for ( y = 0; y < 13; y++ ) + for ( x = 0; x < 13; x++ ) + if ( y % 4 == 0 && x % 4 == 0 ) + Box[y][x] = '*'; + else + Box[y][x] = ' '; + for ( e = 0; e < nEdges; e++ ) + { + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + int y0 = 4*(pNodes[0]/4); + int x0 = 4*(pNodes[0]%4); + int y1 = 4*(pNodes[1]/4); + int x1 = 4*(pNodes[1]%4); + if ( !pBuffer[e] ) + continue; + if ( y0 == y1 ) + { + for ( x = x0+1; x < x1; x++ ) + Box[y0][x] = '-'; + } + else if ( x0 == x1 ) + { + for ( y = y0+1; y < y1; y++ ) + Box[y][x0] = '|'; + } + else assert( 0 ); + } + for ( y = 0; y < 13; y++, printf("\n") ) + for ( x = 0; x < 13; x++ ) + printf( "%c", Box[y][x] ); + printf( "\n\n=================================\n\n" ); +} +void Abc_GraphPathPrint5( int * pBuffer, Vec_Int_t * vEdges ) +{ + char Box[17][17]; + int x, y; + int e, nEdges = Vec_IntSize(vEdges)/2; + for ( y = 0; y < 17; y++ ) + for ( x = 0; x < 17; x++ ) + if ( y % 4 == 0 && x % 4 == 0 ) + Box[y][x] = '*'; + else + Box[y][x] = ' '; + for ( e = 0; e < nEdges; e++ ) + { + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + int y0 = 4*(pNodes[0]/5); + int x0 = 4*(pNodes[0]%5); + int y1 = 4*(pNodes[1]/5); + int x1 = 4*(pNodes[1]%5); + if ( !pBuffer[e] ) + continue; + if ( y0 == y1 ) + { + for ( x = x0+1; x < x1; x++ ) + Box[y0][x] = '-'; + } + else if ( x0 == x1 ) + { + for ( y = y0+1; y < y1; y++ ) + Box[y][x0] = '|'; + } + else assert( 0 ); + } + for ( y = 0; y < 17; y++, printf("\n") ) + for ( x = 0; x < 17; x++ ) + printf( "%c", Box[y][x] ); + printf( "\n\n=================================\n\n" ); +} + +/**Function************************************************************* + + Synopsis [Count paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +double Abc_GraphCountPaths_rec( int Lev, int Node, Vec_Wec_t * vNodes, double ** pCache, int * pBuffer, Vec_Int_t * vEdges ) +{ + double Res0, Res1; +// if ( Node == -2 ) Abc_GraphPathPrint4( pBuffer, vEdges ); + if ( Node == -2 ) + return 1; + if ( Node == -1 ) + return 0; + if ( pCache[Lev][Node] != -1.0 ) + return pCache[Lev][Node]; + pBuffer[Lev] = 0; + Res0 = Abc_GraphCountPaths_rec( Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node ), vNodes, pCache, pBuffer, vEdges ); + pBuffer[Lev] = 1; + Res1 = Abc_GraphCountPaths_rec( Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node+1 ), vNodes, pCache, pBuffer, vEdges ); + return (pCache[Lev][Node] = Res0 + Res1); +} +double Abc_GraphCountPaths( Vec_Wec_t * vNodes, Vec_Int_t * vEdges ) +{ + int i, k, pBuffer[1000] = {0}; + double ** pCache = ABC_ALLOC( double *, Vec_WecSize(vNodes) ); + Vec_Int_t * vLevel; double Value; + Vec_WecForEachLevel( vNodes, vLevel, i ) + { + pCache[i] = ABC_ALLOC( double, Vec_IntSize(vLevel) ); + for ( k = 0; k < Vec_IntSize(vLevel); k++ ) + pCache[i][k] = -1.0; + } + Value = Abc_GraphCountPaths_rec( 0, 0, vNodes, pCache, pBuffer, vEdges ); + for ( i = 0; i < Vec_WecSize(vNodes); i++ ) + ABC_FREE( pCache[i] ); + ABC_FREE( pCache ); + return Value; +} + +/**Function************************************************************* + + Synopsis [Build AIG for paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_GraphDeriveGia_rec( Gia_Man_t * p, int Lev, int Node, Vec_Wec_t * vNodes, int ** pCache, int * pBuffer, Vec_Int_t * vEdges ) +{ + int Res0, Res1; + if ( Node == -2 ) + return 1; + if ( Node == -1 ) + return 0; + if ( pCache[Lev][Node] != -1 ) + return pCache[Lev][Node]; + pBuffer[Lev] = 0; + Res0 = Abc_GraphDeriveGia_rec( p, Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node ), vNodes, pCache, pBuffer, vEdges ); + pBuffer[Lev] = 1; + Res1 = Abc_GraphDeriveGia_rec( p, Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node+1 ), vNodes, pCache, pBuffer, vEdges ); + return ( pCache[Lev][Node] = Gia_ManHashMux(p, Gia_Obj2Lit(p, Gia_ManCi(p, Lev)), Res1, Res0) ); +} +Gia_Man_t * Abc_GraphDeriveGia( Vec_Wec_t * vNodes, Vec_Int_t * vEdges ) +{ + int ** pCache; + int i, Value, pBuffer[1000] = {0}; + Vec_Int_t * vLevel; + // start AIG + Gia_Man_t * pTemp, * p = Gia_ManStart( 1000 ); + p->pName = Abc_UtilStrsav("paths"); + for ( i = 0; i < Vec_IntSize(vEdges)/2; i++ ) + Gia_ManAppendCi(p); + Gia_ManHashAlloc(p); + // alloc cache + pCache = ABC_ALLOC( int *, Vec_WecSize(vNodes) ); + Vec_WecForEachLevel( vNodes, vLevel, i ) + pCache[i] = ABC_FALLOC( int, Vec_IntSize(vLevel) ); + Value = Abc_GraphDeriveGia_rec( p, 0, 0, vNodes, pCache, pBuffer, vEdges ); + for ( i = 0; i < Vec_WecSize(vNodes); i++ ) + ABC_FREE( pCache[i] ); + ABC_FREE( pCache ); + // cleanup + Gia_ManAppendCo( p, Value ); + p = Gia_ManCleanup( pTemp = p ); + Gia_ManStop( pTemp ); + return p; +} +void Abc_GraphDeriveGiaDump( Vec_Wec_t * vNodes, Vec_Int_t * vEdges, int Size ) +{ + char pFileName[100]; + Gia_Man_t * pGia = Abc_GraphDeriveGia( vNodes, vEdges ); + sprintf( pFileName, "grid_%dx%d_e%03d.aig", Size, Size, Vec_IntSize(vEdges)/2 ); + Gia_AigerWrite( pGia, pFileName, 0, 0 ); + Gia_ManStop( pGia ); + printf( "Finished dumping AIG into file \"%s\".\n", pFileName ); +} + +/**Function************************************************************* + + Synopsis [Build frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_GraphBuildState( Vec_Int_t * vState, int e, int x, Vec_Int_t * vEdges, Vec_Int_t * vLife, Vec_Wec_t * vFronts, int * pFront, Vec_Int_t * vStateNew, int fVerbose ) +{ + Vec_Int_t * vFront = Vec_WecEntry( vFronts, e ); + Vec_Int_t * vFront2 = Vec_WecEntry( vFronts, e+1 ); + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + int nNodes = Vec_IntSize(vLife)/2; + int i, n, Node, First, pEquivs[2]; + assert( pNodes[0] < pNodes[1] ); + if ( fVerbose ) printf( "Edge = %d. Arc = %d.\nCurrent state: ", e, x ); + Vec_IntForEachEntry( vFront, Node, i ) + { + pFront[Node] = Vec_IntEntry(vState, i); + if ( fVerbose ) printf( "%d(%d) ", pFront[Node] & 0xFFFF, pFront[Node] >> 16 ); + } + if ( fVerbose ) printf( "\n" ); + for ( n = 0; n < 2; n++ ) + if ( Vec_IntEntry(vLife, 2*pNodes[n]) == e ) // first time + pFront[pNodes[n]] = pNodes[n]; // degree = 0; comp = singleton + if ( x ) + { + if ( (pFront[pNodes[0]] & 0xFFFF) == (pFront[pNodes[1]] & 0xFFFF) ) // the same comp + return -1; // const 0 + for ( n = 0; n < 2; n++ ) + { + int Degree = pFront[pNodes[n]] >> 16; + if ( (pNodes[n] == 0 || pNodes[n] == nNodes-1) ? Degree >= 1 : Degree >= 2 ) + return -1; // const 0 + pFront[pNodes[n]] += (1 << 16); // degree++ + } + } + // remember equivalence classes + pEquivs[0] = pFront[pNodes[0]] & 0xFFFF; + pEquivs[1] = pFront[pNodes[1]] & 0xFFFF; + // remove some nodes from the frontier + for ( n = 0; n < 2; n++ ) + if ( Vec_IntEntry(vLife, 2*pNodes[n]+1) == e ) // last time + { + int Degree = pFront[pNodes[n]] >> 16; + if ( (pNodes[n] == 0 || pNodes[n] == nNodes-1) ? Degree != 1 : Degree != 0 && Degree != 2 ) + return -1; // const 0 + // if it is part of the comp, update + First = -1; + Vec_IntForEachEntry( vFront2, Node, i ) + { + assert( Node != pNodes[n] ); + if ( (pFront[Node] & 0xFFFF) == pEquivs[n] ) + { + if ( First == -1 ) + First = Node; + pFront[Node] = (pFront[Node] & 0xFFFF0000) | First; + } + } + if ( First != -1 ) + pEquivs[n] = First; + } + if ( x ) + { + // union comp + int First = -1; + Vec_IntForEachEntry( vFront2, Node, i ) + if ( (pFront[Node] & 0xFFFF) == pEquivs[0] || (pFront[Node] & 0xFFFF) == pEquivs[1] ) + { + if ( First == -1 ) + First = Node; + pFront[Node] = (pFront[Node] & 0xFFFF0000) | First; + } + } + // create next state + Vec_IntClear( vStateNew ); + if ( fVerbose ) printf( "Next state: " ); + Vec_IntForEachEntry( vFront2, Node, i ) + { + Vec_IntPush( vStateNew, pFront[Node] ); + if ( fVerbose ) printf( "%d(%d) ", pFront[Node] & 0xFFFF, pFront[Node] >> 16 ); + } + if ( fVerbose ) printf( "\n\n" ); + return 1; +} +void Abc_GraphBuildFrontier( int nSize, Vec_Int_t * vEdges, Vec_Int_t * vLife, Vec_Wec_t * vFronts, int fVerbose ) +{ + abctime clk = Abc_Clock(); + double nPaths; + int nEdges = Vec_IntSize(vEdges)/2; + int nNodes = Vec_IntSize(vLife)/2; + Vec_Wec_t * vNodes = Vec_WecAlloc( nEdges ); + Vec_Int_t * vStateNew = Vec_IntAlloc( nNodes ); + Vec_Int_t * vStateCount = Vec_IntAlloc( nEdges ); + int e, s, x, Next, * pFront = ABC_CALLOC( int, nNodes ); + Hsh_VecMan_t * pThis = Hsh_VecManStart( 1000 ); + Hsh_VecMan_t * pNext = Hsh_VecManStart( 1000 ); + Hsh_VecManAdd( pThis, vStateNew ); + for ( e = 0; e < nEdges; e++ ) + { + Vec_Int_t * vNode = Vec_WecPushLevel(vNodes); + int nStates = Hsh_VecSize( pThis ); + Vec_IntPush( vStateCount, nStates ); + if ( fVerbose ) + { + printf( "\n" ); + printf( "Processing edge %d = {%d %d}\n", e, Vec_IntEntry(vEdges, 2*e), Vec_IntEntry(vEdges, 2*e+1) ); + printf( "Frontier: " ); Vec_IntPrint( Vec_WecEntry(vFronts, e) ); + printf( "\n" ); + } + for ( s = 0; s < nStates; s++ ) + { + Vec_Int_t * vState = Hsh_VecReadEntry(pThis, s); + for ( x = 0; x < 2; x++ ) + { + Next = Abc_GraphBuildState(vState, e, x, vEdges, vLife, vFronts, pFront, vStateNew, fVerbose); + if ( Next == 1 ) + { + if ( e == nEdges - 1 ) // last edge + Next = -2; // const1 + else + Next = Hsh_VecManAdd( pNext, vStateNew ); + } + if ( fVerbose ) printf( "Return value = %d\n", Next ); + Vec_IntPush( vNode, Next ); + } + } + Hsh_VecManStop( pThis ); + pThis = pNext; + pNext = Hsh_VecManStart( 1000 ); + } + nPaths = Abc_GraphCountPaths(vNodes, vEdges); + printf( "States = %8d Paths = %24.0f ", Vec_IntSum(vStateCount), nPaths ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( fVerbose ) + Vec_IntPrint( vStateCount ); + Abc_GraphDeriveGiaDump( vNodes, vEdges, nSize ); + ABC_FREE( pFront ); + Vec_WecFree( vNodes ); + Vec_IntFree( vStateNew ); + Vec_IntFree( vStateCount ); + Hsh_VecManStop( pThis ); + Hsh_VecManStop( pNext ); +} +void Abc_EnumerateFrontierTest( int nSize ) +{ + //int nSize = 3; + int fVerbose = 0; + Vec_Int_t * vEdges = Abc_GraphGrid( nSize ); + Vec_Int_t * vLife = Abc_GraphNodeLife( vEdges, nSize ); + Vec_Wec_t * vFronts = Abc_GraphFrontiers( vEdges, vLife ); + + Abc_GraphBuildFrontier( nSize, vEdges, vLife, vFronts, fVerbose ); + + Vec_WecFree( vFronts ); + Vec_IntFree( vLife ); + Vec_IntFree( vEdges ); +} + + +/**Function************************************************************* + + Synopsis [Performs SAT-based path enumeration.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +double Abc_Word2Double( word w ) +{ + double Res = 0; int i; + for ( i = 0; i < 64; i++ ) + if ( (w >> i) & 1 ) + Res += pow(2,i); + return Res; +} +void Abc_GraphSolve( Gia_Man_t * pGia ) +{ + int nIters = 1000; + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); + sat_solver * pSat; Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + int i, k, iLit, nVars = Gia_ManCiNum(pGia); + int iCiVarBeg = pCnf->nVars - nVars; + word Total = 0; + word Mint1 = 0; + word Mint2 = 0; + + // restart the SAT solver + pSat = sat_solver_new(); + sat_solver_setnvars( pSat, pCnf->nVars ); + // add timeframe clauses + for ( i = 0; i < pCnf->nClauses; i++ ) + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + assert( 0 ); + // create trivial assignment + Vec_IntClear( vLits ); + for ( k = 0; k < nVars; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iCiVarBeg+k, 1) ); + // generate random assignment + for ( i = 0; i < nIters; i++ ) + { + int Status = sat_solver_solve_lexsat( pSat, Vec_IntArray(vLits), Vec_IntSize(vLits) ); + if ( Status != l_True ) + break; + assert( Status == l_True ); + // block this assignment + Vec_IntForEachEntry( vLits, iLit, k ) + Vec_IntWriteEntry( vLits, k, Abc_LitNot(iLit) ); + if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ) ) + break; + Vec_IntForEachEntry( vLits, iLit, k ) + Vec_IntWriteEntry( vLits, k, Abc_LitNot(iLit) ); + // collect new minterm + Mint2 = 0; + Vec_IntForEachEntry( vLits, iLit, k ) + if ( !Abc_LitIsCompl(iLit) ) + Mint2 |= ((word)1) << (nVars-1-k); + if ( Mint1 == 0 ) + Mint1 = Mint2; + // report + //printf( "Iter %3d : ", i ); + //Extra_PrintBinary( stdout, (unsigned *)&Mint2, Abc_MinInt(64, nVars) ); printf( "\n" ); + } + //Mint1 = 0; + Total = (Mint2-Mint1)/nIters; + printf( "Vars = %d Iters = %d Ave = %.0f Total = %.0f ", nVars, nIters, Abc_Word2Double(Mint2-Mint1), Abc_Word2Double(Total) ); + printf( "Estimate = %.0f\n", (pow(2,nVars)-Abc_Word2Double(Mint1))/Abc_Word2Double((Mint2-Mint1)/nIters) ); + + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + Vec_IntFree( vLits ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/misc/extra/module.make b/src/misc/extra/module.make index c8d70f26..9db290e5 100644 --- a/src/misc/extra/module.make +++ b/src/misc/extra/module.make @@ -4,9 +4,11 @@ SRC += src/misc/extra/extraUtilBitMatrix.c \ src/misc/extra/extraUtilDsd.c \ src/misc/extra/extraUtilEnum.c \ src/misc/extra/extraUtilFile.c \ + src/misc/extra/extraUtilMaj.c \ src/misc/extra/extraUtilMemory.c \ src/misc/extra/extraUtilMisc.c \ src/misc/extra/extraUtilMult.c \ + src/misc/extra/extraUtilPath.c \ src/misc/extra/extraUtilPerm.c \ src/misc/extra/extraUtilProgress.c \ src/misc/extra/extraUtilReader.c \ diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index 36da1271..3d3f80b8 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1154,6 +1154,10 @@ static inline int Abc_Tt6HasVar( word t, int iVar ) { return ((t >> (1<<iVar)) & s_Truths6Neg[iVar]) != (t & s_Truths6Neg[iVar]); } +static inline int Abc_Tt6XorVar( word t, int iVar ) +{ + return ((t >> (1<<iVar)) & s_Truths6Neg[iVar]) == ~(t & s_Truths6Neg[iVar]); +} static inline int Abc_TtHasVar( word * t, int nVars, int iVar ) { assert( iVar < nVars ); @@ -3094,6 +3098,99 @@ static inline int Abc_Tt4Check( int t ) return 0; } + +/**Function************************************************************* + + Synopsis [Returns symmetry profile of the function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_Tt6VarsAreSymmetric( word t, int iVar, int jVar ) +{ + word * s_PMasks = s_PPMasks[iVar][jVar]; + int shift = (1 << jVar) - (1 << iVar); + assert( iVar < jVar ); + return ((t & s_PMasks[1]) << shift) == (t & s_PMasks[2]); +} +static inline int Abc_Tt6VarsAreAntiSymmetric( word t, int iVar, int jVar ) +{ + word * s_PMasks = s_PPMasks[iVar][jVar]; + int shift = (1 << jVar) + (1 << iVar); + assert( iVar < jVar ); + return ((t & (s_PMasks[1] >> (1 << iVar))) << shift) == (t & (s_PMasks[2] << (1 << iVar))); +} +static inline int Abc_TtVarsAreSymmetric( word * pTruth, int nVars, int i, int j, word * pCof0, word * pCof1 ) +{ + int nWords = Abc_TtWordNum( nVars ); + assert( i < nVars && j < nVars ); + Abc_TtCofactor0p( pCof0, pTruth, nWords, i ); + Abc_TtCofactor1p( pCof1, pTruth, nWords, i ); + Abc_TtCofactor1( pCof0, nWords, j ); + Abc_TtCofactor0( pCof1, nWords, j ); + return Abc_TtEqual( pCof0, pCof1, nWords ); +} +static inline int Abc_TtVarsAreAntiSymmetric( word * pTruth, int nVars, int i, int j, word * pCof0, word * pCof1 ) +{ + int nWords = Abc_TtWordNum( nVars ); + assert( i < nVars && j < nVars ); + Abc_TtCofactor0p( pCof0, pTruth, nWords, i ); + Abc_TtCofactor1p( pCof1, pTruth, nWords, i ); + Abc_TtCofactor0( pCof0, nWords, j ); + Abc_TtCofactor1( pCof1, nWords, j ); + return Abc_TtEqual( pCof0, pCof1, nWords ); +} +static inline int Abc_TtIsFullySymmetric( word * pTruth, int nVars ) +{ + int m, v, Polar = 0, Seen = 0; + for ( m = 0; m < (1<<nVars); m++ ) + { + int Count = 0; + int Value = Abc_TtGetBit( pTruth, m ); + for ( v = 0; v < nVars; v++ ) + Count += ((m >> v) & 1); + if ( (Seen >> Count) & 1 ) // seen this count + { + if ( Value != ((Polar >> Count) & 1) ) + return -1; + } + else // new count + { + Seen |= 1 << Count; + if ( Value ) + Polar |= 1 << Count; + } + } + return Polar; +} +static inline void Abc_TtGenFullySymmetric( word * pTruth, int nVars, int Polar ) +{ + int m, v, nWords = Abc_TtWordNum( nVars ); + Abc_TtClear( pTruth, nWords ); + for ( m = 0; m < (1<<nVars); m++ ) + { + int Count = 0; + for ( v = 0; v < nVars; v++ ) + Count += ((m >> v) & 1); + if ( (Polar >> Count) & 1 ) + Abc_TtSetBit( pTruth, m ); + } +} +static inline void Abc_TtTestFullySymmetric() +{ + word pTruth[4]; // 8-var function + int PolarOut, PolarIn = 271; + Abc_TtGenFullySymmetric( pTruth, 8, PolarIn ); + //Abc_TtXorBit( pTruth, 171 ); + PolarOut = Abc_TtIsFullySymmetric( pTruth, 8 ); + assert( PolarIn == PolarOut ); +} + + /*=== utilTruth.c ===========================================================*/ diff --git a/src/misc/vec/vecMem.h b/src/misc/vec/vecMem.h index 72b653b7..c2bd06f0 100644 --- a/src/misc/vec/vecMem.h +++ b/src/misc/vec/vecMem.h @@ -341,10 +341,24 @@ static int * Vec_MemHashLookup( Vec_Mem_t * p, word * pEntry ) return pSpot; return pSpot; } +static void Vec_MemHashProfile( Vec_Mem_t * p ) +{ + int e; + for ( e = 0; e < 1000; e++ ) + { + int Count = 0; + int * pSpot = Vec_IntEntryP( p->vTable, e ); + for ( ; *pSpot != -1; pSpot = Vec_IntEntryP(p->vNexts, *pSpot) ) + Count++; + printf( "%d ", Count ); + } + printf( "\n" ); +} static void Vec_MemHashResize( Vec_Mem_t * p ) { word * pEntry; int i, * pSpot; + //Vec_MemHashProfile( p ); Vec_IntFill( p->vTable, Abc_PrimeCudd(2 * Vec_IntSize(p->vTable)), -1 ); Vec_IntClear( p->vNexts ); Vec_MemForEachEntry( p, pEntry, i ) |