summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Soeken <mathias.soeken@epfl.ch>2016-07-31 12:24:02 +0200
committerMathias Soeken <mathias.soeken@epfl.ch>2016-07-31 12:24:02 +0200
commit19e78a35d4ce12bf82f4093fdfa20eeb0329aae1 (patch)
tree2aaff9d2b3f24fa01f77933b64fc72f9e9fa8cab
parenta6352369a5583f18c8819a40fc2968f6d8dbe93c (diff)
downloadabc-19e78a35d4ce12bf82f4093fdfa20eeb0329aae1.tar.gz
abc-19e78a35d4ce12bf82f4093fdfa20eeb0329aae1.tar.bz2
abc-19e78a35d4ce12bf82f4093fdfa20eeb0329aae1.zip
Store for exact results.
-rw-r--r--src/base/abci/abcExact.c155
1 files changed, 150 insertions, 5 deletions
diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c
index 40f85b79..e0a09cf3 100644
--- a/src/base/abci/abcExact.c
+++ b/src/base/abci/abcExact.c
@@ -87,11 +87,49 @@ struct Ses_Man_t_
abctime timeTotal; /* all runtime */
};
+/***********************************************************************
+
+ Synopsis [Store truth tables based on normalized arrival times.]
+
+***********************************************************************/
+
+// The hash table is a list of pointers to Ses_TruthEntry_t elements, which
+// are arranged in a linked list, each of which pointing to a linked list
+// of Ses_TimesEntry_t elements which contain the char* representation of the
+// optimum netlist according to then normalized arrival times:
+
+typedef struct Ses_TimesEntry_t_ Ses_TimesEntry_t;
+struct Ses_TimesEntry_t_
+{
+ int pArrTimeProfile[8]; /* normalized arrival time profile */
+ Ses_TimesEntry_t * next; /* linked list pointer */
+ char * pNetwork; /* pointer to char array representation of optimum network */
+};
+
+typedef struct Ses_TruthEntry_t_ Ses_TruthEntry_t;
+struct Ses_TruthEntry_t_
+{
+ word pTruth[4]; /* truth table for comparison */
+ Ses_TruthEntry_t * next; /* linked list pointer */
+ Ses_TimesEntry_t * head; /* pointer to head of sub list with arrival times */
+};
+
+#define SES_STORE_TABLE_SIZE 1024
+typedef struct Ses_Store_t_ Ses_Store_t;
+struct Ses_Store_t_
+{
+ int nNumVars; /* store has been allocated for this number of variables */
+ int nWords; /* number of truth table words */
+ Ses_TruthEntry_t * pEntries[SES_STORE_TABLE_SIZE]; /* hash table for truth table entries */
+};
+
+static Ses_Store_t * s_pSesStore = NULL;
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-int NormalizeArrivalTimes( int * pArrTimeProfile, int nVars, int * maxNormalized )
+static int Abc_NormalizeArrivalTimes( int * pArrTimeProfile, int nVars, int * maxNormalized )
{
int * p = pArrTimeProfile, * pEnd = pArrTimeProfile + nVars;
int delta = *p;
@@ -115,6 +153,110 @@ int NormalizeArrivalTimes( int * pArrTimeProfile, int nVars, int * maxNormalized
return delta;
}
+static inline int Ses_StoreTableHash( Ses_Store_t * pStore, word * pTruth )
+{
+ static int s_Primes[4] = { 1291, 1699, 1999, 2357 };
+ int i;
+ unsigned uHash = 0;
+ for ( i = 0; i < pStore->nWords; ++i )
+ uHash ^= pTruth[i] * s_Primes[i & 0xf];
+ return (int)(uHash % SES_STORE_TABLE_SIZE );
+}
+
+static inline int Ses_StoreTruthEqual( Ses_Store_t * pStore, word * pTruth1, word * pTruth2 )
+{
+ int i;
+ for ( i = 0; i < pStore->nWords; ++i )
+ if ( pTruth1[i] != pTruth2[i] )
+ return 0;
+ return 1;
+}
+
+static inline void Ses_StoreTruthCopy( Ses_Store_t * pStore, word * pTruthDest, word * pTruthSrc )
+{
+ int i;
+ for ( i = 0; i < pStore->nWords; ++i )
+ pTruthDest[i] = pTruthSrc[i];
+}
+
+static inline int Ses_StoreTimesEqual( Ses_Store_t * pStore, int * pTimes1, int * pTimes2 )
+{
+ int i;
+ for ( i = 0; i < pStore->nNumVars; ++i )
+ if ( pTimes1[i] != pTimes2[i] )
+ return 0;
+ return 1;
+}
+
+static inline void Ses_StoreTimesCopy( Ses_Store_t * pStore, int * pTimesDest, int * pTimesSrc )
+{
+ int i;
+ for ( i = 0; i < pStore->nNumVars; ++i )
+ pTimesDest[i] = pTimesSrc[i];
+}
+
+// pArrTimeProfile is not normalized
+// returns 1 if and only if a new TimesEntry has been created
+int Ses_StoreAddEntry( Ses_Store_t * pStore, word * pTruth, int nVars, int * pArrTimeProfile, char * pSol )
+{
+ int maxNormalized, key;
+ Ses_TruthEntry_t * pTEntry;
+ Ses_TimesEntry_t * pTiEntry;
+
+ if ( pStore->nNumVars != nVars )
+ return 0;
+
+ Abc_NormalizeArrivalTimes( pArrTimeProfile, nVars, &maxNormalized );
+
+ key = Ses_StoreTableHash( pStore, pTruth );
+ pTEntry = pStore->pEntries[key];
+
+ /* does truth table already exist? */
+ while ( pTEntry )
+ {
+ if ( Ses_StoreTruthEqual( pStore, pTruth, pTEntry->pTruth ) )
+ break;
+ else
+ pTEntry = pTEntry->next;
+ }
+
+ /* entry does not yet exist, so create new one and enqueue */
+ if ( !pTEntry )
+ {
+ pTEntry = ABC_CALLOC( Ses_TruthEntry_t, 1 );
+ Ses_StoreTruthCopy( pStore, pTEntry->pTruth, pTruth );
+ pTEntry->next = pStore->pEntries[key];
+ pStore->pEntries[key] = pTEntry;
+ }
+
+ /* does arrival time already exist? */
+ pTiEntry = pTEntry->head;
+ while ( pTiEntry )
+ {
+ if ( Ses_StoreTimesEqual( pStore, pArrTimeProfile, pTiEntry->pArrTimeProfile ) )
+ break;
+ else
+ pTiEntry = pTiEntry->next;
+ }
+
+ /* entry does not yet exist, so create new one and enqueue */
+ if ( !pTiEntry )
+ {
+ pTiEntry = ABC_CALLOC( Ses_TimesEntry_t, 1 );
+ Ses_StoreTimesCopy( pStore, pTiEntry->pArrTimeProfile, pArrTimeProfile );
+ pTiEntry->pNetwork = pSol;
+ pTiEntry->next = pTEntry->head;
+ pTEntry->head = pTiEntry;
+
+ /* item has been added */
+ return 1;
+ }
+ else
+ /* item was already present */
+ return 0;
+}
+
+
static inline Ses_Man_t * Ses_ManAlloc( word * pTruth, int nVars, int nFunc, int nMaxDepth, int * pArrTimeProfile, int fMakeAIG, int fVerbose )
{
int h, i;
@@ -136,7 +278,7 @@ static inline Ses_Man_t * Ses_ManAlloc( word * pTruth, int nVars, int nFunc, int
p->nMaxDepth = nMaxDepth;
p->pArrTimeProfile = nMaxDepth >= 0 ? pArrTimeProfile : NULL;
if ( p->pArrTimeProfile )
- p->nArrTimeDelta = NormalizeArrivalTimes( p->pArrTimeProfile, nVars, &p->nArrTimeMax );
+ p->nArrTimeDelta = Abc_NormalizeArrivalTimes( p->pArrTimeProfile, nVars, &p->nArrTimeMax );
else
p->nArrTimeDelta = p->nArrTimeMax = 0;
p->fMakeAIG = fMakeAIG;
@@ -1096,13 +1238,14 @@ void Abc_ExactTest( int fVerbose )
// this procedure should return 1, if the engine/library are available, and 0 otherwise
int Abc_ExactIsRunning()
{
- return 0;
+ return s_pSesStore != NULL;
}
// this procedure returns the number of inputs of the library
// for example, somebody may try to map into 10-cuts while the library only contains 8-functions
int Abc_ExactInputNum()
{
- return 0;
+ assert( s_pSesStore );
+ return s_pSesStore->nNumVars;
}
// this procedure takes TT and input arrival times (pArrTimeProfile) and return the smallest output arrival time;
// it also returns the pin-to-pin delays (pPerm) between each cut leaf and the cut output and the cut area cost (Cost)
@@ -1145,7 +1288,9 @@ int Abc_ExactDelayCost( word * pTruth, int nVars, int * pArrTimeProfile, char *
for ( l = 0; l < nVars; ++l )
pPerm[l] = *p++;
- ABC_FREE( pSol );
+ /* store solution */
+ if ( !Ses_StoreAddEntry( s_pSesStore, pTruth, nVars, pArrTimeProfile, pSol ) )
+ ABC_FREE( pSol ); /* store entry already exists, so free solution */
}
pSes->timeTotal = Abc_Clock() - timeStart;