ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
fraigTable.c
Go to the documentation of this file.
1
18
19#include "fraigInt.h"
20
22
23
27
28static void Fraig_TableResizeS( Fraig_HashTable_t * p );
29static void Fraig_TableResizeF( Fraig_HashTable_t * p, int fUseSimR );
30
34
47{
49 // allocate the table
51 memset( p, 0, sizeof(Fraig_HashTable_t) );
52 // allocate and clean the bins
53 p->nBins = Abc_PrimeCudd(nSize);
54 p->pBins = ABC_ALLOC( Fraig_Node_t *, p->nBins );
55 memset( p->pBins, 0, sizeof(Fraig_Node_t *) * p->nBins );
56 return p;
57}
58
71{
72 ABC_FREE( p->pBins );
73 ABC_FREE( p );
74}
75
91{
92 Fraig_HashTable_t * p = pMan->pTableS;
93 Fraig_Node_t * pEnt;
94 unsigned Key;
95
96 // order the arguments
97 if ( Fraig_Regular(p1)->Num > Fraig_Regular(p2)->Num )
98 pEnt = p1, p1 = p2, p2 = pEnt;
99
100 Key = Fraig_HashKey2( p1, p2, p->nBins );
101 Fraig_TableBinForEachEntryS( p->pBins[Key], pEnt )
102 if ( pEnt->p1 == p1 && pEnt->p2 == p2 )
103 {
104 *ppNodeRes = pEnt;
105 return 1;
106 }
107 // check if it is a good time for table resizing
108 if ( p->nEntries >= 2 * p->nBins )
109 {
110 Fraig_TableResizeS( p );
111 Key = Fraig_HashKey2( p1, p2, p->nBins );
112 }
113 // create the new node
114 pEnt = Fraig_NodeCreate( pMan, p1, p2 );
115 // add the node to the corresponding linked list in the table
116 pEnt->pNextS = p->pBins[Key];
117 p->pBins[Key] = pEnt;
118 *ppNodeRes = pEnt;
119 p->nEntries++;
120 return 0;
121}
122
123
137{
138 Fraig_HashTable_t * p = pMan->pTableF;
139 Fraig_Node_t * pEnt, * pEntD;
140 unsigned Key;
141
142 // go through the hash table entries
143 Key = pNode->uHashR % p->nBins;
144 Fraig_TableBinForEachEntryF( p->pBins[Key], pEnt )
145 {
146 // if their simulation info differs, skip
147 if ( !Fraig_CompareSimInfo( pNode, pEnt, pMan->nWordsRand, 1 ) )
148 continue;
149 // equivalent up to the complement
150 Fraig_TableBinForEachEntryD( pEnt, pEntD )
151 {
152 // if their simulation info differs, skip
153 if ( !Fraig_CompareSimInfo( pNode, pEntD, pMan->iWordStart, 0 ) )
154 continue;
155 // found a simulation-equivalent node
156 return pEntD;
157 }
158 // did not find a simulation equivalent node
159 // add the node to the corresponding linked list
160 pNode->pNextD = pEnt->pNextD;
161 pEnt->pNextD = pNode;
162 // return NULL, because there is no functional equivalence in this case
163 return NULL;
164 }
165
166 // check if it is a good time for table resizing
167 if ( p->nEntries >= 2 * p->nBins )
168 {
169 Fraig_TableResizeF( p, 1 );
170 Key = pNode->uHashR % p->nBins;
171 }
172
173 // add the node to the corresponding linked list in the table
174 pNode->pNextF = p->pBins[Key];
175 p->pBins[Key] = pNode;
176 p->nEntries++;
177 // return NULL, because there is no functional equivalence in this case
178 return NULL;
179}
180
194{
195 Fraig_HashTable_t * p = pMan->pTableF0;
196 Fraig_Node_t * pEnt;
197 unsigned Key;
198
199 // go through the hash table entries
200 Key = pNode->uHashD % p->nBins;
201 Fraig_TableBinForEachEntryF( p->pBins[Key], pEnt )
202 {
203 // if their simulation info differs, skip
204 if ( !Fraig_CompareSimInfo( pNode, pEnt, pMan->iWordStart, 0 ) )
205 continue;
206 // found a simulation-equivalent node
207 return pEnt;
208 }
209
210 // check if it is a good time for table resizing
211 if ( p->nEntries >= 2 * p->nBins )
212 {
213 Fraig_TableResizeF( p, 0 );
214 Key = pNode->uHashD % p->nBins;
215 }
216
217 // add the node to the corresponding linked list in the table
218 pNode->pNextF = p->pBins[Key];
219 p->pBins[Key] = pNode;
220 p->nEntries++;
221 // return NULL, because there is no functional equivalence in this case
222 return NULL;
223}
224
238{
239 Fraig_HashTable_t * p = pMan->pTableF0;
240 unsigned Key = pNode->uHashD % p->nBins;
241
242 pNode->pNextF = p->pBins[Key];
243 p->pBins[Key] = pNode;
244 p->nEntries++;
245}
246
247
259void Fraig_TableResizeS( Fraig_HashTable_t * p )
260{
261 Fraig_Node_t ** pBinsNew;
262 Fraig_Node_t * pEnt, * pEnt2;
263 int nBinsNew, Counter, i;
264 abctime clk;
265 unsigned Key;
266
267clk = Abc_Clock();
268 // get the new table size
269 nBinsNew = Abc_PrimeCudd(2 * p->nBins);
270 // allocate a new array
271 pBinsNew = ABC_ALLOC( Fraig_Node_t *, nBinsNew );
272 memset( pBinsNew, 0, sizeof(Fraig_Node_t *) * nBinsNew );
273 // rehash the entries from the old table
274 Counter = 0;
275 for ( i = 0; i < p->nBins; i++ )
276 Fraig_TableBinForEachEntrySafeS( p->pBins[i], pEnt, pEnt2 )
277 {
278 Key = Fraig_HashKey2( pEnt->p1, pEnt->p2, nBinsNew );
279 pEnt->pNextS = pBinsNew[Key];
280 pBinsNew[Key] = pEnt;
281 Counter++;
282 }
283 assert( Counter == p->nEntries );
284// printf( "Increasing the structural table size from %6d to %6d. ", p->nBins, nBinsNew );
285// ABC_PRT( "Time", Abc_Clock() - clk );
286 // replace the table and the parameters
287 ABC_FREE( p->pBins );
288 p->pBins = pBinsNew;
289 p->nBins = nBinsNew;
290}
291
303void Fraig_TableResizeF( Fraig_HashTable_t * p, int fUseSimR )
304{
305 Fraig_Node_t ** pBinsNew;
306 Fraig_Node_t * pEnt, * pEnt2;
307 int nBinsNew, Counter, i;
308 abctime clk;
309 unsigned Key;
310
311clk = Abc_Clock();
312 // get the new table size
313 nBinsNew = Abc_PrimeCudd(2 * p->nBins);
314 // allocate a new array
315 pBinsNew = ABC_ALLOC( Fraig_Node_t *, nBinsNew );
316 memset( pBinsNew, 0, sizeof(Fraig_Node_t *) * nBinsNew );
317 // rehash the entries from the old table
318 Counter = 0;
319 for ( i = 0; i < p->nBins; i++ )
320 Fraig_TableBinForEachEntrySafeF( p->pBins[i], pEnt, pEnt2 )
321 {
322 if ( fUseSimR )
323 Key = pEnt->uHashR % nBinsNew;
324 else
325 Key = pEnt->uHashD % nBinsNew;
326 pEnt->pNextF = pBinsNew[Key];
327 pBinsNew[Key] = pEnt;
328 Counter++;
329 }
330 assert( Counter == p->nEntries );
331// printf( "Increasing the functional table size from %6d to %6d. ", p->nBins, nBinsNew );
332// ABC_PRT( "Time", Abc_Clock() - clk );
333 // replace the table and the parameters
334 ABC_FREE( p->pBins );
335 p->pBins = pBinsNew;
336 p->nBins = nBinsNew;
337}
338
339
351int Fraig_CompareSimInfo( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand )
352{
353 int i;
354 assert( !Fraig_IsComplement(pNode1) );
355 assert( !Fraig_IsComplement(pNode2) );
356 if ( fUseRand )
357 {
358 // if their signatures differ, skip
359 if ( pNode1->uHashR != pNode2->uHashR )
360 return 0;
361 // check the simulation info
362 for ( i = 0; i < iWordLast; i++ )
363 if ( pNode1->puSimR[i] != pNode2->puSimR[i] )
364 return 0;
365 }
366 else
367 {
368 // if their signatures differ, skip
369 if ( pNode1->uHashD != pNode2->uHashD )
370 return 0;
371 // check the simulation info
372 for ( i = 0; i < iWordLast; i++ )
373 if ( pNode1->puSimD[i] != pNode2->puSimD[i] )
374 return 0;
375 }
376 return 1;
377}
378
390int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int fCompl, int iWordLast, int fUseRand )
391{
392 int i, v;
393 assert( !Fraig_IsComplement(pNode1) );
394 assert( !Fraig_IsComplement(pNode2) );
395 // take into account possible internal complementation
396 fCompl ^= pNode1->fInv;
397 fCompl ^= pNode2->fInv;
398 // find the pattern
399 if ( fCompl )
400 {
401 if ( fUseRand )
402 {
403 for ( i = 0; i < iWordLast; i++ )
404 if ( pNode1->puSimR[i] != ~pNode2->puSimR[i] )
405 for ( v = 0; v < 32; v++ )
406 if ( (pNode1->puSimR[i] ^ ~pNode2->puSimR[i]) & (1 << v) )
407 return i * 32 + v;
408 }
409 else
410 {
411 for ( i = 0; i < iWordLast; i++ )
412 if ( pNode1->puSimD[i] != ~pNode2->puSimD[i] )
413 for ( v = 0; v < 32; v++ )
414 if ( (pNode1->puSimD[i] ^ ~pNode2->puSimD[i]) & (1 << v) )
415 return i * 32 + v;
416 }
417 }
418 else
419 {
420 if ( fUseRand )
421 {
422 for ( i = 0; i < iWordLast; i++ )
423 if ( pNode1->puSimR[i] != pNode2->puSimR[i] )
424 for ( v = 0; v < 32; v++ )
425 if ( (pNode1->puSimR[i] ^ pNode2->puSimR[i]) & (1 << v) )
426 return i * 32 + v;
427 }
428 else
429 {
430 for ( i = 0; i < iWordLast; i++ )
431 if ( pNode1->puSimD[i] != pNode2->puSimD[i] )
432 for ( v = 0; v < 32; v++ )
433 if ( (pNode1->puSimD[i] ^ pNode2->puSimD[i]) & (1 << v) )
434 return i * 32 + v;
435 }
436 }
437 return -1;
438}
439
451int Fraig_CompareSimInfoUnderMask( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask )
452{
453 unsigned * pSims1, * pSims2;
454 int i;
455 assert( !Fraig_IsComplement(pNode1) );
456 assert( !Fraig_IsComplement(pNode2) );
457 // get hold of simulation info
458 pSims1 = fUseRand? pNode1->puSimR : pNode1->puSimD;
459 pSims2 = fUseRand? pNode2->puSimR : pNode2->puSimD;
460 // check the simulation info
461 for ( i = 0; i < iWordLast; i++ )
462 if ( (pSims1[i] & puMask[i]) != (pSims2[i] & puMask[i]) )
463 return 0;
464 return 1;
465}
466
478void Fraig_CollectXors( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask )
479{
480 unsigned * pSims1, * pSims2;
481 int i;
482 assert( !Fraig_IsComplement(pNode1) );
483 assert( !Fraig_IsComplement(pNode2) );
484 // get hold of simulation info
485 pSims1 = fUseRand? pNode1->puSimR : pNode1->puSimD;
486 pSims2 = fUseRand? pNode2->puSimR : pNode2->puSimD;
487 // check the simulation info
488 for ( i = 0; i < iWordLast; i++ )
489 puMask[i] = ( pSims1[i] ^ pSims2[i] );
490}
491
492
505{
506 Fraig_HashTable_t * pT = pMan->pTableS;
507 Fraig_Node_t * pNode;
508 int i, Counter;
509
510 printf( "Structural table. Table size = %d. Number of entries = %d.\n", pT->nBins, pT->nEntries );
511 for ( i = 0; i < pT->nBins; i++ )
512 {
513 Counter = 0;
514 Fraig_TableBinForEachEntryS( pT->pBins[i], pNode )
515 Counter++;
516 if ( Counter > 1 )
517 {
518 printf( "%d ", Counter );
519 if ( Counter > 50 )
520 printf( "{%d} ", i );
521 }
522 }
523 printf( "\n" );
524}
525
538{
539 Fraig_HashTable_t * pT = pMan->pTableF;
540 Fraig_Node_t * pNode;
541 int i, Counter;
542
543 printf( "Functional table. Table size = %d. Number of entries = %d.\n", pT->nBins, pT->nEntries );
544 for ( i = 0; i < pT->nBins; i++ )
545 {
546 Counter = 0;
547 Fraig_TableBinForEachEntryF( pT->pBins[i], pNode )
548 Counter++;
549 if ( Counter > 1 )
550 printf( "{%d} ", Counter );
551 }
552 printf( "\n" );
553}
554
567{
568 Fraig_HashTable_t * pT = pMan->pTableF0;
569 Fraig_Node_t * pNode;
570 int i, Counter;
571
572 printf( "Zero-node table. Table size = %d. Number of entries = %d.\n", pT->nBins, pT->nEntries );
573 for ( i = 0; i < pT->nBins; i++ )
574 {
575 Counter = 0;
576 Fraig_TableBinForEachEntryF( pT->pBins[i], pNode )
577 Counter++;
578 if ( Counter == 0 )
579 continue;
580/*
581 printf( "\nBin = %4d : Number of entries = %4d\n", i, Counter );
582 Fraig_TableBinForEachEntryF( pT->pBins[i], pNode )
583 printf( "Node %5d. Hash = %10d.\n", pNode->Num, pNode->uHashD );
584*/
585 }
586 printf( "\n" );
587}
588
604int Fraig_TableRehashF0( Fraig_Man_t * pMan, int fLinkEquiv )
605{
606 Fraig_HashTable_t * pT = pMan->pTableF0;
607 Fraig_Node_t ** pBinsNew;
608 Fraig_Node_t * pEntF, * pEntF2, * pEnt, * pEntD2, * pEntN;
609 int ReturnValue, Counter, i;
610 unsigned Key;
611
612 // allocate a new array of bins
613 pBinsNew = ABC_ALLOC( Fraig_Node_t *, pT->nBins );
614 memset( pBinsNew, 0, sizeof(Fraig_Node_t *) * pT->nBins );
615
616 // rehash the entries in the table
617 // go through all the nodes in the F-lists (and possible in D-lists, if used)
618 Counter = 0;
619 ReturnValue = 0;
620 for ( i = 0; i < pT->nBins; i++ )
621 Fraig_TableBinForEachEntrySafeF( pT->pBins[i], pEntF, pEntF2 )
622 Fraig_TableBinForEachEntrySafeD( pEntF, pEnt, pEntD2 )
623 {
624 // decide where to put entry pEnt
625 Key = pEnt->uHashD % pT->nBins;
626 if ( fLinkEquiv )
627 {
628 // go through the entries in the new bin
629 Fraig_TableBinForEachEntryF( pBinsNew[Key], pEntN )
630 {
631 // if they have different values skip
632 if ( pEnt->uHashD != pEntN->uHashD )
633 continue;
634 // they have the same hash value, add pEnt to the D-list pEnt3
635 pEnt->pNextD = pEntN->pNextD;
636 pEntN->pNextD = pEnt;
637 ReturnValue = 1;
638 Counter++;
639 break;
640 }
641 if ( pEntN != NULL ) // already linked
642 continue;
643 // we did not find equal entry
644 }
645 // link the new entry
646 pEnt->pNextF = pBinsNew[Key];
647 pBinsNew[Key] = pEnt;
648 pEnt->pNextD = NULL;
649 Counter++;
650 }
651 assert( Counter == pT->nEntries );
652 // replace the table and the parameters
653 ABC_FREE( pT->pBins );
654 pT->pBins = pBinsNew;
655 return ReturnValue;
656}
657
661
662
664
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
Cube * p
Definition exorList.c:222
#define Fraig_HashKey2(a, b, TSIZE)
Definition fraigInt.h:92
#define Fraig_TableBinForEachEntrySafeF(pBin, pEnt, pEnt2)
Definition fraigInt.h:316
#define Fraig_TableBinForEachEntryF(pBin, pEnt)
Definition fraigInt.h:312
#define Fraig_TableBinForEachEntryS(pBin, pEnt)
Definition fraigInt.h:301
#define Fraig_TableBinForEachEntrySafeD(pBin, pEnt, pEnt2)
Definition fraigInt.h:327
#define Fraig_TableBinForEachEntryD(pBin, pEnt)
Definition fraigInt.h:323
Fraig_Node_t * Fraig_NodeCreate(Fraig_Man_t *p, Fraig_Node_t *p1, Fraig_Node_t *p2)
Definition fraigNode.c:160
#define Fraig_TableBinForEachEntrySafeS(pBin, pEnt, pEnt2)
Definition fraigInt.h:305
void Fraig_HashTableFree(Fraig_HashTable_t *p)
Definition fraigTable.c:70
Fraig_Node_t * Fraig_HashTableLookupF(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition fraigTable.c:136
int Fraig_CompareSimInfo(Fraig_Node_t *pNode1, Fraig_Node_t *pNode2, int iWordLast, int fUseRand)
Definition fraigTable.c:351
void Fraig_TablePrintStatsF(Fraig_Man_t *pMan)
Definition fraigTable.c:537
int Fraig_TableRehashF0(Fraig_Man_t *pMan, int fLinkEquiv)
Definition fraigTable.c:604
void Fraig_CollectXors(Fraig_Node_t *pNode1, Fraig_Node_t *pNode2, int iWordLast, int fUseRand, unsigned *puMask)
Definition fraigTable.c:478
int Fraig_HashTableLookupS(Fraig_Man_t *pMan, Fraig_Node_t *p1, Fraig_Node_t *p2, Fraig_Node_t **ppNodeRes)
Definition fraigTable.c:90
int Fraig_CompareSimInfoUnderMask(Fraig_Node_t *pNode1, Fraig_Node_t *pNode2, int iWordLast, int fUseRand, unsigned *puMask)
Definition fraigTable.c:451
void Fraig_TablePrintStatsS(Fraig_Man_t *pMan)
Definition fraigTable.c:504
Fraig_Node_t * Fraig_HashTableLookupF0(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition fraigTable.c:193
int Fraig_FindFirstDiff(Fraig_Node_t *pNode1, Fraig_Node_t *pNode2, int fCompl, int iWordLast, int fUseRand)
Definition fraigTable.c:390
void Fraig_HashTableInsertF0(Fraig_Man_t *pMan, Fraig_Node_t *pNode)
Definition fraigTable.c:237
void Fraig_TablePrintStatsF0(Fraig_Man_t *pMan)
Definition fraigTable.c:566
Fraig_HashTable_t * Fraig_HashTableCreate(int nSize)
FUNCTION DEFINITIONS ///.
Definition fraigTable.c:46
#define Fraig_IsComplement(p)
GLOBAL VARIABLES ///.
Definition fraig.h:107
#define Fraig_Regular(p)
Definition fraig.h:108
typedefABC_NAMESPACE_HEADER_START struct Fraig_ManStruct_t_ Fraig_Man_t
INCLUDES ///.
Definition fraig.h:40
struct Fraig_NodeStruct_t_ Fraig_Node_t
Definition fraig.h:41
struct Fraig_HashTableStruct_t_ Fraig_HashTable_t
Definition fraig.h:43
Fraig_Node_t ** pBins
Definition fraigInt.h:273
Fraig_Node_t * pNextF
Definition fraigInt.h:239
Fraig_Node_t * p2
Definition fraigInt.h:233
Fraig_Node_t * pNextS
Definition fraigInt.h:238
unsigned * puSimR
Definition fraigInt.h:247
Fraig_Node_t * p1
Definition fraigInt.h:232
Fraig_Node_t * pNextD
Definition fraigInt.h:240
unsigned * puSimD
Definition fraigInt.h:248
#define assert(ex)
Definition util_old.h:213
char * memset()