ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
aigPart.c
Go to the documentation of this file.
1
20
21#include "aig.h"
22#include "misc/tim/tim.h"
23#include "proof/fra/fra.h"
24
26
27
31
32typedef struct Part_Man_t_ Part_Man_t;
34{
35 int nChunkSize; // the size of one chunk of memory (~1 MB)
36 int nStepSize; // the step size in saving memory (~64 bytes)
37 char * pFreeBuf; // the pointer to free memory
38 int nFreeSize; // the size of remaining free memory
39 Vec_Ptr_t * vMemory; // the memory allocated
40 Vec_Ptr_t * vFree; // the vector of free pieces of memory
41};
42
43typedef struct Part_One_t_ Part_One_t;
45{
46 int nRefs; // the number of references
47 int nOuts; // the number of outputs
48 int nOutsAlloc; // the array size
49 int pOuts[0]; // the array of outputs
50};
51
52static inline int Part_SizeType( int nSize, int nStepSize ) { return nSize / nStepSize + ((nSize % nStepSize) > 0); }
53static inline char * Part_OneNext( char * pPart ) { return *((char **)pPart); }
54static inline void Part_OneSetNext( char * pPart, char * pNext ) { *((char **)pPart) = pNext; }
55
59
71Part_Man_t * Part_ManStart( int nChunkSize, int nStepSize )
72{
73 Part_Man_t * p;
74 p = ABC_ALLOC( Part_Man_t, 1 );
75 memset( p, 0, sizeof(Part_Man_t) );
76 p->nChunkSize = nChunkSize;
77 p->nStepSize = nStepSize;
78 p->vMemory = Vec_PtrAlloc( 1000 );
79 p->vFree = Vec_PtrAlloc( 1000 );
80 return p;
81}
82
95{
96 void * pMemory;
97 int i;
98 Vec_PtrForEachEntry( void *, p->vMemory, pMemory, i )
99 ABC_FREE( pMemory );
100 Vec_PtrFree( p->vMemory );
101 Vec_PtrFree( p->vFree );
102 ABC_FREE( p );
103}
104
116char * Part_ManFetch( Part_Man_t * p, int nSize )
117{
118 int Type, nSizeReal;
119 char * pMemory;
120 assert( nSize > 0 );
121 Type = Part_SizeType( nSize, p->nStepSize );
122 Vec_PtrFillExtra( p->vFree, Type + 1, NULL );
123 if ( (pMemory = (char *)Vec_PtrEntry( p->vFree, Type )) )
124 {
125 Vec_PtrWriteEntry( p->vFree, Type, Part_OneNext(pMemory) );
126 return pMemory;
127 }
128 nSizeReal = p->nStepSize * Type;
129 if ( p->nFreeSize < nSizeReal )
130 {
131 p->pFreeBuf = ABC_ALLOC( char, p->nChunkSize );
132 p->nFreeSize = p->nChunkSize;
133 Vec_PtrPush( p->vMemory, p->pFreeBuf );
134 }
135 assert( p->nFreeSize >= nSizeReal );
136 pMemory = p->pFreeBuf;
137 p->pFreeBuf += nSizeReal;
138 p->nFreeSize -= nSizeReal;
139 return pMemory;
140}
141
153void Part_ManRecycle( Part_Man_t * p, char * pMemory, int nSize )
154{
155 int Type;
156 Type = Part_SizeType( nSize, p->nStepSize );
157 Vec_PtrFillExtra( p->vFree, Type + 1, NULL );
158 Part_OneSetNext( pMemory, (char *)Vec_PtrEntry(p->vFree, Type) );
159 Vec_PtrWriteEntry( p->vFree, Type, pMemory );
160}
161
173static inline Part_One_t * Part_ManFetchEntry( Part_Man_t * p, int nWords, int nRefs )
174{
175 Part_One_t * pPart;
176 pPart = (Part_One_t *)Part_ManFetch( p, sizeof(Part_One_t) + sizeof(int) * nWords );
177 pPart->nRefs = nRefs;
178 pPart->nOuts = 0;
179 pPart->nOutsAlloc = nWords;
180 return pPart;
181}
182
194static inline void Part_ManRecycleEntry( Part_Man_t * p, Part_One_t * pEntry )
195{
196 assert( pEntry->nOuts <= pEntry->nOutsAlloc );
197 assert( pEntry->nOuts >= pEntry->nOutsAlloc/2 );
198 Part_ManRecycle( p, (char *)pEntry, sizeof(Part_One_t) + sizeof(int) * pEntry->nOutsAlloc );
199}
200
213{
214 Part_One_t * p = Part_ManFetchEntry( pMan, p1->nOuts + p2->nOuts, nRefs );
215 int * pBeg1 = p1->pOuts;
216 int * pBeg2 = p2->pOuts;
217 int * pBeg = p->pOuts;
218 int * pEnd1 = p1->pOuts + p1->nOuts;
219 int * pEnd2 = p2->pOuts + p2->nOuts;
220 while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
221 {
222 if ( *pBeg1 == *pBeg2 )
223 *pBeg++ = *pBeg1++, pBeg2++;
224 else if ( *pBeg1 < *pBeg2 )
225 *pBeg++ = *pBeg1++;
226 else
227 *pBeg++ = *pBeg2++;
228 }
229 while ( pBeg1 < pEnd1 )
230 *pBeg++ = *pBeg1++;
231 while ( pBeg2 < pEnd2 )
232 *pBeg++ = *pBeg2++;
233 p->nOuts = pBeg - p->pOuts;
234 assert( p->nOuts <= p->nOutsAlloc );
235 assert( p->nOuts >= p1->nOuts );
236 assert( p->nOuts >= p2->nOuts );
237 return p;
238}
239
252{
253 Vec_Int_t * vSupp;
254 int i;
255 vSupp = Vec_IntAlloc( p->nOuts );
256 for ( i = 0; i < p->nOuts; i++ )
257 Vec_IntPush( vSupp, p->pOuts[i] );
258 return vSupp;
259}
260
274{
275 Vec_Ptr_t * vSupports;
276 Vec_Int_t * vSupp;
277 Part_Man_t * p;
278 Part_One_t * pPart0, * pPart1;
279 Aig_Obj_t * pObj;
280 int i, Counter = 0;
281 // set the number of PIs/POs
282 Aig_ManForEachCi( pMan, pObj, i )
283 pObj->pNext = (Aig_Obj_t *)(long)i;
284 Aig_ManForEachCo( pMan, pObj, i )
285 pObj->pNext = (Aig_Obj_t *)(long)i;
286 // start the support computation manager
287 p = Part_ManStart( 1 << 20, 1 << 6 );
288 // consider objects in the topological order
289 vSupports = Vec_PtrAlloc( Aig_ManCoNum(pMan) );
290 Aig_ManCleanData(pMan);
291 Aig_ManForEachObj( pMan, pObj, i )
292 {
293 if ( Aig_ObjIsNode(pObj) )
294 {
295 pPart0 = (Part_One_t *)Aig_ObjFanin0(pObj)->pData;
296 pPart1 = (Part_One_t *)Aig_ObjFanin1(pObj)->pData;
297 pObj->pData = Part_ManMergeEntry( p, pPart0, pPart1, pObj->nRefs );
298 assert( pPart0->nRefs > 0 );
299 if ( --pPart0->nRefs == 0 )
300 Part_ManRecycleEntry( p, pPart0 );
301 assert( pPart1->nRefs > 0 );
302 if ( --pPart1->nRefs == 0 )
303 Part_ManRecycleEntry( p, pPart1 );
304 if ( ((Part_One_t *)pObj->pData)->nOuts <= 16 )
305 Counter++;
306 continue;
307 }
308 if ( Aig_ObjIsCo(pObj) )
309 {
310 pPart0 = (Part_One_t *)Aig_ObjFanin0(pObj)->pData;
311 vSupp = Part_ManTransferEntry(pPart0);
312 Vec_IntPush( vSupp, (int)(long)pObj->pNext );
313 Vec_PtrPush( vSupports, vSupp );
314 assert( pPart0->nRefs > 0 );
315 if ( --pPart0->nRefs == 0 )
316 Part_ManRecycleEntry( p, pPart0 );
317 continue;
318 }
319 if ( Aig_ObjIsCi(pObj) )
320 {
321 if ( pObj->nRefs )
322 {
323 pPart0 = Part_ManFetchEntry( p, 1, pObj->nRefs );
324 pPart0->pOuts[ pPart0->nOuts++ ] = (int)(long)pObj->pNext;
325 pObj->pData = pPart0;
326 }
327 continue;
328 }
329 if ( Aig_ObjIsConst1(pObj) )
330 {
331 if ( pObj->nRefs )
332 pObj->pData = Part_ManFetchEntry( p, 0, pObj->nRefs );
333 continue;
334 }
335 assert( 0 );
336 }
337//printf( "Memory usage = %d MB.\n", Vec_PtrSize(p->vMemory) * p->nChunkSize / (1<<20) );
338 Part_ManStop( p );
339 // sort supports by size
340 Vec_VecSort( (Vec_Vec_t *)vSupports, 1 );
341 // clear the number of PIs/POs
342 Aig_ManForEachCi( pMan, pObj, i )
343 pObj->pNext = NULL;
344 Aig_ManForEachCo( pMan, pObj, i )
345 pObj->pNext = NULL;
346/*
347 Aig_ManForEachCo( pMan, pObj, i )
348 printf( "%d ", Vec_IntSize( Vec_VecEntryInt(vSupports, i) ) );
349 printf( "\n" );
350*/
351// printf( "%d \n", Counter );
352 return vSupports;
353}
354
367{
368 Vec_Ptr_t * vSupps;
369 vSupps = Aig_ManSupports( pMan );
370 Vec_VecFree( (Vec_Vec_t *)vSupps );
371}
372
386{
387 Vec_Ptr_t * vSupps, * vSuppsInv;
388 Vec_Int_t * vSupp;
389 int i, k, iIn, iOut;
390 // get structural supports for each output
391 vSupps = Aig_ManSupports( p );
392 // start the inverse supports
393 vSuppsInv = Vec_PtrAlloc( Aig_ManCiNum(p) );
394 for ( i = 0; i < Aig_ManCiNum(p); i++ )
395 Vec_PtrPush( vSuppsInv, Vec_IntAlloc(8) );
396 // transforms the supports into the inverse supports
397 Vec_PtrForEachEntry( Vec_Int_t *, vSupps, vSupp, i )
398 {
399 iOut = Vec_IntPop( vSupp );
400 Vec_IntForEachEntry( vSupp, iIn, k )
401 Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vSuppsInv, iIn), iOut );
402 }
403 Vec_VecFree( (Vec_Vec_t *)vSupps );
404 return vSuppsInv;
405}
406
419{
420 Vec_Ptr_t * vSupports, * vMatrix;
421 Vec_Int_t * vSupp;
422 int iOut, iIn, k, m, i;
423 // get structural supports for each output
424 vSupports = Aig_ManSupports( p );
425 // transforms the supports into the latch dependency matrix
426 vMatrix = Vec_PtrStart( Aig_ManRegNum(p) );
427 Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vSupp, i )
428 {
429 // skip true POs
430 iOut = Vec_IntPop( vSupp );
431 iOut -= Aig_ManCoNum(p) - Aig_ManRegNum(p);
432 if ( iOut < 0 )
433 {
434 Vec_IntFree( vSupp );
435 continue;
436 }
437 // remove PIs
438 m = 0;
439 Vec_IntForEachEntry( vSupp, iIn, k )
440 {
441 iIn -= Aig_ManCiNum(p) - Aig_ManRegNum(p);
442 if ( iIn < 0 )
443 continue;
444 assert( iIn < Aig_ManRegNum(p) );
445 Vec_IntWriteEntry( vSupp, m++, iIn );
446 }
447 Vec_IntShrink( vSupp, m );
448 // store support in the matrix
449 assert( iOut < Aig_ManRegNum(p) );
450 Vec_PtrWriteEntry( vMatrix, iOut, vSupp );
451 }
452 Vec_PtrFree( vSupports );
453 // check that all supports are used
454 Vec_PtrForEachEntry( Vec_Int_t *, vMatrix, vSupp, i )
455 assert( vSupp != NULL );
456 return vMatrix;
457}
458
470unsigned * Aig_ManSuppCharStart( Vec_Int_t * vOne, int nPis )
471{
472 unsigned * pBuffer;
473 int i, Entry;
474 int nWords = Abc_BitWordNum(nPis);
475 pBuffer = ABC_ALLOC( unsigned, nWords );
476 memset( pBuffer, 0, sizeof(unsigned) * nWords );
477 Vec_IntForEachEntry( vOne, Entry, i )
478 {
479 assert( Entry < nPis );
480 Abc_InfoSetBit( pBuffer, Entry );
481 }
482 return pBuffer;
483}
484
496void Aig_ManSuppCharAdd( unsigned * pBuffer, Vec_Int_t * vOne, int nPis )
497{
498 int i, Entry;
499 Vec_IntForEachEntry( vOne, Entry, i )
500 {
501 assert( Entry < nPis );
502 Abc_InfoSetBit( pBuffer, Entry );
503 }
504}
505
517int Aig_ManSuppCharCommon( unsigned * pBuffer, Vec_Int_t * vOne )
518{
519 int i, Entry, nCommon = 0;
520 Vec_IntForEachEntry( vOne, Entry, i )
521 nCommon += Abc_InfoHasBit(pBuffer, Entry);
522 return nCommon;
523}
524
536int Aig_ManPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsBit, int nSuppSizeLimit, Vec_Int_t * vOne )
537{
538 Vec_Int_t * vPartSupp;//, * vPart;
539 int Attract, Repulse, Value, ValueBest;
540 int i, nCommon, iBest;
541 iBest = -1;
542 ValueBest = 0;
543 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vPartSupp, i )
544 {
545// vPart = Vec_PtrEntry( vPartsAll, i );
546// if ( nSuppSizeLimit > 0 && Vec_IntSize(vPart) >= nSuppSizeLimit )
547// continue;
548// nCommon = Vec_IntTwoCountCommon( vPartSupp, vOne );
549 nCommon = Aig_ManSuppCharCommon( (unsigned *)Vec_PtrEntry(vPartSuppsBit, i), vOne );
550 if ( nCommon == 0 )
551 continue;
552 if ( nCommon == Vec_IntSize(vOne) )
553 return i;
554 // skip partitions whose size exceeds the limit
555 if ( nSuppSizeLimit > 0 && Vec_IntSize(vPartSupp) >= 2 * nSuppSizeLimit )
556 continue;
557 Attract = 1000 * nCommon / Vec_IntSize(vOne);
558 if ( Vec_IntSize(vPartSupp) < 100 )
559 Repulse = 1;
560 else
561 Repulse = 1+Abc_Base2Log(Vec_IntSize(vPartSupp)-100);
562 Value = Attract/Repulse;
563 if ( ValueBest < Value )
564 {
565 ValueBest = Value;
566 iBest = i;
567 }
568 }
569 if ( ValueBest < 75 )
570 return -1;
571 return iBest;
572}
573
585void Aig_ManPartitionPrint( Aig_Man_t * p, Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll )
586{
587 Vec_Int_t * vOne;
588 int i, nOutputs, Counter;
589
590 Counter = 0;
591 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i )
592 {
593 nOutputs = Vec_IntSize((Vec_Int_t *)Vec_PtrEntry(vPartsAll, i));
594 printf( "%d=(%d,%d) ", i, Vec_IntSize(vOne), nOutputs );
595 Counter += nOutputs;
596 if ( i == Vec_PtrSize(vPartsAll) - 1 )
597 break;
598 }
599 assert( Counter == Aig_ManCoNum(p) );
600// printf( "\nTotal = %d. Outputs = %d.\n", Counter, Aig_ManCoNum(p) );
601}
602
614void Aig_ManPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll, int nSuppSizeLimit )
615{
616 Vec_Int_t * vOne, * vPart, * vPartSupp, * vTemp;
617 int i, iPart;
618
619 if ( nSuppSizeLimit == 0 )
620 nSuppSizeLimit = 200;
621
622 // pack smaller partitions into larger blocks
623 iPart = 0;
624 vPart = vPartSupp = NULL;
625 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i )
626 {
627 if ( Vec_IntSize(vOne) < nSuppSizeLimit )
628 {
629 if ( vPartSupp == NULL )
630 {
631 assert( vPart == NULL );
632 vPartSupp = Vec_IntDup(vOne);
633 vPart = (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i);
634 }
635 else
636 {
637 vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne );
638 Vec_IntFree( vTemp );
639 vPart = Vec_IntTwoMerge( vTemp = vPart, (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i) );
640 Vec_IntFree( vTemp );
641 Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i) );
642 }
643 if ( Vec_IntSize(vPartSupp) < nSuppSizeLimit )
644 continue;
645 }
646 else
647 vPart = (Vec_Int_t *)Vec_PtrEntry(vPartsAll, i);
648 // add the partition
649 Vec_PtrWriteEntry( vPartsAll, iPart, vPart );
650 vPart = NULL;
651 if ( vPartSupp )
652 {
653 Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vPartSuppsAll, iPart) );
654 Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp );
655 vPartSupp = NULL;
656 }
657 iPart++;
658 }
659 // add the last one
660 if ( vPart )
661 {
662 Vec_PtrWriteEntry( vPartsAll, iPart, vPart );
663 vPart = NULL;
664
665 assert( vPartSupp != NULL );
666 Vec_IntFree( (Vec_Int_t *)Vec_PtrEntry(vPartSuppsAll, iPart) );
667 Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp );
668 vPartSupp = NULL;
669 iPart++;
670 }
671 Vec_PtrShrink( vPartsAll, iPart );
672 Vec_PtrShrink( vPartsAll, iPart );
673}
674
686Vec_Ptr_t * Aig_ManPartitionSmart( Aig_Man_t * p, int nSuppSizeLimit, int fVerbose, Vec_Ptr_t ** pvPartSupps )
687{
688 Vec_Ptr_t * vPartSuppsBit;
689 Vec_Ptr_t * vSupports, * vPartsAll, * vPartsAll2, * vPartSuppsAll;//, * vPartPtr;
690 Vec_Int_t * vOne, * vPart, * vPartSupp, * vTemp;
691 int i, iPart, iOut;
692 abctime clk;
693
694 // compute the supports for all outputs
695clk = Abc_Clock();
696 vSupports = Aig_ManSupports( p );
697if ( fVerbose )
698{
699ABC_PRT( "Supps", Abc_Clock() - clk );
700}
701 // start char-based support representation
702 vPartSuppsBit = Vec_PtrAlloc( 1000 );
703
704 // create partitions
705clk = Abc_Clock();
706 vPartsAll = Vec_PtrAlloc( 256 );
707 vPartSuppsAll = Vec_PtrAlloc( 256 );
708 Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vOne, i )
709 {
710 // get the output number
711 iOut = Vec_IntPop(vOne);
712 // find closely matching part
713 iPart = Aig_ManPartitionSmartFindPart( vPartSuppsAll, vPartsAll, vPartSuppsBit, nSuppSizeLimit, vOne );
714 if ( iPart == -1 )
715 {
716 // create new partition
717 vPart = Vec_IntAlloc( 32 );
718 Vec_IntPush( vPart, iOut );
719 // create new partition support
720 vPartSupp = Vec_IntDup( vOne );
721 // add this partition and its support
722 Vec_PtrPush( vPartsAll, vPart );
723 Vec_PtrPush( vPartSuppsAll, vPartSupp );
724
725 Vec_PtrPush( vPartSuppsBit, Aig_ManSuppCharStart(vOne, Aig_ManCiNum(p)) );
726 }
727 else
728 {
729 // add output to this partition
730 vPart = (Vec_Int_t *)Vec_PtrEntry( vPartsAll, iPart );
731 Vec_IntPush( vPart, iOut );
732 // merge supports
733 vPartSupp = (Vec_Int_t *)Vec_PtrEntry( vPartSuppsAll, iPart );
734 vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne );
735 Vec_IntFree( vTemp );
736 // reinsert new support
737 Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp );
738
739 Aig_ManSuppCharAdd( (unsigned *)Vec_PtrEntry(vPartSuppsBit, iPart), vOne, Aig_ManCiNum(p) );
740 }
741 }
742
743 // stop char-based support representation
744 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsBit, vTemp, i )
745 ABC_FREE( vTemp );
746 Vec_PtrFree( vPartSuppsBit );
747
748//printf( "\n" );
749if ( fVerbose )
750{
751ABC_PRT( "Parts", Abc_Clock() - clk );
752}
753
754clk = Abc_Clock();
755 // reorder partitions in the decreasing order of support sizes
756 // remember partition number in each partition support
757 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i )
758 Vec_IntPush( vOne, i );
759 // sort the supports in the decreasing order
760 Vec_VecSort( (Vec_Vec_t *)vPartSuppsAll, 1 );
761 // reproduce partitions
762 vPartsAll2 = Vec_PtrAlloc( 256 );
763 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i )
764 Vec_PtrPush( vPartsAll2, Vec_PtrEntry(vPartsAll, Vec_IntPop(vOne)) );
765 Vec_PtrFree( vPartsAll );
766 vPartsAll = vPartsAll2;
767
768 // compact small partitions
769// Aig_ManPartitionPrint( p, vPartsAll, vPartSuppsAll );
770 Aig_ManPartitionCompact( vPartsAll, vPartSuppsAll, nSuppSizeLimit );
771 if ( fVerbose )
772// Aig_ManPartitionPrint( p, vPartsAll, vPartSuppsAll );
773 printf( "Created %d partitions.\n", Vec_PtrSize(vPartsAll) );
774
775if ( fVerbose )
776{
777//ABC_PRT( "Comps", Abc_Clock() - clk );
778}
779
780 // cleanup
781 Vec_VecFree( (Vec_Vec_t *)vSupports );
782 if ( pvPartSupps == NULL )
783 Vec_VecFree( (Vec_Vec_t *)vPartSuppsAll );
784 else
785 *pvPartSupps = vPartSuppsAll;
786/*
787 // converts from intergers to nodes
788 Vec_PtrForEachEntry( Vec_Int_t *, vPartsAll, vPart, iPart )
789 {
790 vPartPtr = Vec_PtrAlloc( Vec_IntSize(vPart) );
791 Vec_IntForEachEntry( vPart, iOut, i )
792 Vec_PtrPush( vPartPtr, Aig_ManCo(p, iOut) );
793 Vec_IntFree( vPart );
794 Vec_PtrWriteEntry( vPartsAll, iPart, vPartPtr );
795 }
796*/
797 return vPartsAll;
798}
799
811Vec_Ptr_t * Aig_ManPartitionSmartRegisters( Aig_Man_t * pAig, int nSuppSizeLimit, int fVerbose )
812{
813 Vec_Ptr_t * vPartSuppsBit;
814 Vec_Ptr_t * vSupports, * vPartsAll, * vPartsAll2, * vPartSuppsAll;
815 Vec_Int_t * vOne, * vPart, * vPartSupp, * vTemp;
816 int i, iPart, iOut;
817 abctime clk;
818
819 // add output number to each
820clk = Abc_Clock();
821 vSupports = Aig_ManSupportsRegisters( pAig );
822 assert( Vec_PtrSize(vSupports) == Aig_ManRegNum(pAig) );
823 Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vOne, i )
824 Vec_IntPush( vOne, i );
825if ( fVerbose )
826{
827ABC_PRT( "Supps", Abc_Clock() - clk );
828}
829
830 // start char-based support representation
831 vPartSuppsBit = Vec_PtrAlloc( 1000 );
832
833 // create partitions
834clk = Abc_Clock();
835 vPartsAll = Vec_PtrAlloc( 256 );
836 vPartSuppsAll = Vec_PtrAlloc( 256 );
837 Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vOne, i )
838 {
839 // get the output number
840 iOut = Vec_IntPop(vOne);
841 // find closely matching part
842 iPart = Aig_ManPartitionSmartFindPart( vPartSuppsAll, vPartsAll, vPartSuppsBit, nSuppSizeLimit, vOne );
843 if ( iPart == -1 )
844 {
845 // create new partition
846 vPart = Vec_IntAlloc( 32 );
847 Vec_IntPush( vPart, iOut );
848 // create new partition support
849 vPartSupp = Vec_IntDup( vOne );
850 // add this partition and its support
851 Vec_PtrPush( vPartsAll, vPart );
852 Vec_PtrPush( vPartSuppsAll, vPartSupp );
853
854 Vec_PtrPush( vPartSuppsBit, Aig_ManSuppCharStart(vOne, Vec_PtrSize(vSupports)) );
855 }
856 else
857 {
858 // add output to this partition
859 vPart = (Vec_Int_t *)Vec_PtrEntry( vPartsAll, iPart );
860 Vec_IntPush( vPart, iOut );
861 // merge supports
862 vPartSupp = (Vec_Int_t *)Vec_PtrEntry( vPartSuppsAll, iPart );
863 vPartSupp = Vec_IntTwoMerge( vTemp = vPartSupp, vOne );
864 Vec_IntFree( vTemp );
865 // reinsert new support
866 Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp );
867
868 Aig_ManSuppCharAdd( (unsigned *)Vec_PtrEntry(vPartSuppsBit, iPart), vOne, Vec_PtrSize(vSupports) );
869 }
870 }
871
872 // stop char-based support representation
873 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsBit, vTemp, i )
874 ABC_FREE( vTemp );
875 Vec_PtrFree( vPartSuppsBit );
876
877//printf( "\n" );
878if ( fVerbose )
879{
880ABC_PRT( "Parts", Abc_Clock() - clk );
881}
882
883clk = Abc_Clock();
884 // reorder partitions in the decreasing order of support sizes
885 // remember partition number in each partition support
886 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i )
887 Vec_IntPush( vOne, i );
888 // sort the supports in the decreasing order
889 Vec_VecSort( (Vec_Vec_t *)vPartSuppsAll, 1 );
890 // reproduce partitions
891 vPartsAll2 = Vec_PtrAlloc( 256 );
892 Vec_PtrForEachEntry( Vec_Int_t *, vPartSuppsAll, vOne, i )
893 Vec_PtrPush( vPartsAll2, Vec_PtrEntry(vPartsAll, Vec_IntPop(vOne)) );
894 Vec_PtrFree( vPartsAll );
895 vPartsAll = vPartsAll2;
896
897 // compact small partitions
898// Aig_ManPartitionPrint( p, vPartsAll, vPartSuppsAll );
899 Aig_ManPartitionCompact( vPartsAll, vPartSuppsAll, nSuppSizeLimit );
900 if ( fVerbose )
901// Aig_ManPartitionPrint( p, vPartsAll, vPartSuppsAll );
902 printf( "Created %d partitions.\n", Vec_PtrSize(vPartsAll) );
903
904if ( fVerbose )
905{
906//ABC_PRT( "Comps", Abc_Clock() - clk );
907}
908
909 // cleanup
910 Vec_VecFree( (Vec_Vec_t *)vSupports );
911// if ( pvPartSupps == NULL )
912 Vec_VecFree( (Vec_Vec_t *)vPartSuppsAll );
913// else
914// *pvPartSupps = vPartSuppsAll;
915
916/*
917 // converts from intergers to nodes
918 Vec_PtrForEachEntry( Vec_Int_t *, vPartsAll, vPart, iPart )
919 {
920 vPartPtr = Vec_PtrAlloc( Vec_IntSize(vPart) );
921 Vec_IntForEachEntry( vPart, iOut, i )
922 Vec_PtrPush( vPartPtr, Aig_ManCo(p, iOut) );
923 Vec_IntFree( vPart );
924 Vec_PtrWriteEntry( vPartsAll, iPart, vPartPtr );
925 }
926*/
927 return vPartsAll;
928}
929
942{
943 Vec_Ptr_t * vParts;
944 Aig_Obj_t * pObj;
945 int nParts, i;
946 nParts = (Aig_ManCoNum(p) / nPartSize) + ((Aig_ManCoNum(p) % nPartSize) > 0);
947 vParts = (Vec_Ptr_t *)Vec_VecStart( nParts );
948 Aig_ManForEachCo( p, pObj, i )
949 Vec_IntPush( (Vec_Int_t *)Vec_PtrEntry(vParts, i / nPartSize), i );
950 return vParts;
951}
952
953
954
966Aig_Obj_t * Aig_ManDupPart_rec( Aig_Man_t * pNew, Aig_Man_t * pOld, Aig_Obj_t * pObj, Vec_Int_t * vSuppMap )
967{
968 assert( !Aig_IsComplement(pObj) );
969 if ( Aig_ObjIsTravIdCurrent(pOld, pObj) )
970 return (Aig_Obj_t *)pObj->pData;
971 Aig_ObjSetTravIdCurrent(pOld, pObj);
972 if ( Aig_ObjIsCi(pObj) )
973 {
974 assert( Vec_IntSize(vSuppMap) == Aig_ManCiNum(pNew) );
975 Vec_IntPush( vSuppMap, (int)(long)pObj->pNext );
976 return (Aig_Obj_t *)(pObj->pData = Aig_ObjCreateCi(pNew));
977 }
978 assert( Aig_ObjIsNode(pObj) );
979 Aig_ManDupPart_rec( pNew, pOld, Aig_ObjFanin0(pObj), vSuppMap );
980 Aig_ManDupPart_rec( pNew, pOld, Aig_ObjFanin1(pObj), vSuppMap );
981 return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ));
982}
983
995Vec_Ptr_t * Aig_ManDupPart( Aig_Man_t * pNew, Aig_Man_t * pOld, Vec_Int_t * vPart, Vec_Int_t * vSuppMap, int fInverse )
996{
997 Vec_Ptr_t * vOutsTotal;
998 Aig_Obj_t * pObj;
999 int Entry, i;
1000 // create the PIs
1001 Aig_ManIncrementTravId( pOld );
1002 Aig_ManConst1(pOld)->pData = Aig_ManConst1(pNew);
1003 Aig_ObjSetTravIdCurrent( pOld, Aig_ManConst1(pOld) );
1004 if ( !fInverse )
1005 {
1006 Vec_IntForEachEntry( vSuppMap, Entry, i )
1007 {
1008 pObj = Aig_ManCi( pOld, Entry );
1009 pObj->pData = Aig_ManCi( pNew, i );
1010 Aig_ObjSetTravIdCurrent( pOld, pObj );
1011 }
1012 }
1013 else
1014 {
1015 Vec_IntForEachEntry( vSuppMap, Entry, i )
1016 {
1017 pObj = Aig_ManCi( pOld, i );
1018 pObj->pData = Aig_ManCi( pNew, Entry );
1019 Aig_ObjSetTravIdCurrent( pOld, pObj );
1020 }
1021 vSuppMap = NULL; // should not be useful
1022 }
1023 // create the internal nodes
1024 vOutsTotal = Vec_PtrAlloc( Vec_IntSize(vPart) );
1025 if ( !fInverse )
1026 {
1027 Vec_IntForEachEntry( vPart, Entry, i )
1028 {
1029 pObj = Aig_ManCo( pOld, Entry );
1030 Aig_ManDupPart_rec( pNew, pOld, Aig_ObjFanin0(pObj), vSuppMap );
1031 Vec_PtrPush( vOutsTotal, Aig_ObjChild0Copy(pObj) );
1032 }
1033 }
1034 else
1035 {
1036 Aig_ManForEachObj( pOld, pObj, i )
1037 {
1038 if ( Aig_ObjIsCo(pObj) )
1039 {
1040 Aig_ManDupPart_rec( pNew, pOld, Aig_ObjFanin0(pObj), vSuppMap );
1041 Vec_PtrPush( vOutsTotal, Aig_ObjChild0Copy(pObj) );
1042 }
1043 else if ( Aig_ObjIsNode(pObj) && pObj->nRefs == 0 )
1044 Aig_ManDupPart_rec( pNew, pOld, pObj, vSuppMap );
1045
1046 }
1047 }
1048 return vOutsTotal;
1049}
1050
1063{
1064 Aig_Obj_t * pObjNew;
1065 assert( !Aig_IsComplement(pObj) );
1066 if ( Aig_ObjIsTravIdCurrent(pOld, pObj) )
1067 return;
1068 Aig_ObjSetTravIdCurrent(pOld, pObj);
1069 if ( Aig_ObjIsCi(pObj) )
1070 pObjNew = Aig_ObjCreateCi(pNew);
1071 else if ( Aig_ObjIsCo(pObj) )
1072 {
1073 Aig_ManDupPartAll_rec( pNew, pOld, Aig_ObjFanin0(pObj) );
1074 pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
1075 }
1076 else
1077 {
1078 assert( Aig_ObjIsNode(pObj) );
1079 Aig_ManDupPartAll_rec( pNew, pOld, Aig_ObjFanin0(pObj) );
1080 Aig_ManDupPartAll_rec( pNew, pOld, Aig_ObjFanin1(pObj) );
1081 pObjNew = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1082 }
1083 pObj->pData = pObjNew;
1084 pObjNew->pData = pObj;
1085}
1086
1099{
1100 Aig_Man_t * pNew;
1101 Aig_Obj_t * pObj, * pObjNew;
1102 int i, Entry;
1103 Aig_ManIncrementTravId( pOld );
1104 pNew = Aig_ManStart( 5000 );
1105 // map constant nodes
1106 pObj = Aig_ManConst1(pOld);
1107 pObjNew = Aig_ManConst1(pNew);
1108 pObj->pData = pObjNew;
1109 pObjNew->pData = pObj;
1110 Aig_ObjSetTravIdCurrent(pOld, pObj);
1111 // map all other nodes
1112 Vec_IntForEachEntry( vPart, Entry, i )
1113 {
1114 pObj = Aig_ManCo( pOld, Entry );
1115 Aig_ManDupPartAll_rec( pNew, pOld, pObj );
1116 }
1117 return pNew;
1118}
1119
1132{
1133 if ( Aig_ObjIsTravIdCurrent(p, pObj) )
1134 return;
1135 Aig_ObjSetTravIdCurrent(p, pObj);
1136 if ( Aig_ObjIsCi(pObj) )
1137 {
1138 Vec_IntPush( vSupport, Aig_ObjCioId(pObj) );
1139 return;
1140 }
1141 Aig_ManSupportNodes_rec( p, Aig_ObjFanin0(pObj), vSupport );
1142 Aig_ManSupportNodes_rec( p, Aig_ObjFanin1(pObj), vSupport );
1143}
1144
1157{
1158 Vec_Ptr_t * vPartSupps;
1159 Vec_Int_t * vPart, * vSupport;
1160 int i, k, iOut;
1162 vPartSupps = Vec_PtrAlloc( Vec_PtrSize(vParts) );
1163 Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i )
1164 {
1165 vSupport = Vec_IntAlloc( 100 );
1167 Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
1168 Vec_IntForEachEntry( vPart, iOut, k )
1169 Aig_ManSupportNodes_rec( p, Aig_ObjFanin0(Aig_ManCo(p, iOut)), vSupport );
1170// Vec_IntSort( vSupport, 0 );
1171 Vec_PtrPush( vPartSupps, vSupport );
1172 }
1174 return vPartSupps;
1175}
1176
1189Vec_Ptr_t * Aig_ManMiterPartitioned( Aig_Man_t * p1, Aig_Man_t * p2, int nPartSize, int fSmart )
1190{
1191 Aig_Man_t * pNew;
1192 Aig_Obj_t * pMiter;
1193 Vec_Ptr_t * vMiters, * vNodes1, * vNodes2;
1194 Vec_Ptr_t * vParts, * vPartSupps;
1195 Vec_Int_t * vPart, * vPartSupp;
1196 int i, k;
1197 // partition the first manager
1198 if ( fSmart )
1199 vParts = Aig_ManPartitionSmart( p1, nPartSize, 0, &vPartSupps );
1200 else
1201 {
1202 vParts = Aig_ManPartitionNaive( p1, nPartSize );
1203 vPartSupps = Aig_ManSupportNodes( p1, vParts );
1204 }
1205 // derive miters
1206 vMiters = Vec_PtrAlloc( Vec_PtrSize(vParts) );
1207 for ( i = 0; i < Vec_PtrSize(vParts); i++ )
1208 {
1209 // get partition and its support
1210 vPart = (Vec_Int_t *)Vec_PtrEntry( vParts, i );
1211 vPartSupp = (Vec_Int_t *)Vec_PtrEntry( vPartSupps, i );
1212 // create the new miter
1213 pNew = Aig_ManStart( 1000 );
1214 // create the PIs
1215 for ( k = 0; k < Vec_IntSize(vPartSupp); k++ )
1216 Aig_ObjCreateCi( pNew );
1217 // copy the components
1218 vNodes1 = Aig_ManDupPart( pNew, p1, vPart, vPartSupp, 0 );
1219 vNodes2 = Aig_ManDupPart( pNew, p2, vPart, vPartSupp, 0 );
1220 // create the miter
1221 pMiter = Aig_MiterTwo( pNew, vNodes1, vNodes2 );
1222 Vec_PtrFree( vNodes1 );
1223 Vec_PtrFree( vNodes2 );
1224 // create the output
1225 Aig_ObjCreateCo( pNew, pMiter );
1226 // clean up
1227 Aig_ManCleanup( pNew );
1228 Vec_PtrPush( vMiters, pNew );
1229 }
1230 Vec_VecFree( (Vec_Vec_t *)vParts );
1231 Vec_VecFree( (Vec_Vec_t *)vPartSupps );
1232 return vMiters;
1233}
1234
1247Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize, int nConfMax, int nLevelMax, int fVerbose )
1248{
1249// extern int Cmd_CommandExecute( void * pAbc, char * sCommand );
1250// extern void * Abc_FrameGetGlobalFrame();
1251// extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig, int nConfMax, int nLevelMax );
1252
1253 Vec_Ptr_t * vPios;
1254 Vec_Ptr_t * vOutsTotal, * vOuts;
1255 Aig_Man_t * pAigTotal, * pAigPart, * pAig, * pTemp;
1256 Vec_Int_t * vPart, * vPartSupp;
1257 Vec_Ptr_t * vParts;
1258 Aig_Obj_t * pObj;
1259 void ** ppData;
1260 int i, k, m, nIdMax;
1261 assert( Vec_PtrSize(vAigs) > 1 );
1262
1263 // compute the total number of IDs
1264 nIdMax = 0;
1265 Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i )
1266 nIdMax += Aig_ManObjNumMax(pAig);
1267
1268 // partition the first AIG in the array
1269 pAig = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 );
1270 vParts = Aig_ManPartitionSmart( pAig, nPartSize, 0, NULL );
1271
1272 // start the total fraiged AIG
1273 pAigTotal = Aig_ManStartFrom( pAig );
1274 Aig_ManReprStart( pAigTotal, nIdMax );
1275 vOutsTotal = Vec_PtrStart( Aig_ManCoNum(pAig) );
1276
1277 // set the PI numbers
1278 Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i )
1279 Aig_ManForEachCi( pAig, pObj, k )
1280 pObj->pNext = (Aig_Obj_t *)(long)k;
1281
1282// Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "unset progressbar" );
1283
1284 // create the total fraiged AIG
1285 vPartSupp = Vec_IntAlloc( 100 ); // maps part PI num into total PI num
1286 Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i )
1287 {
1288 // derive the partition AIG
1289 pAigPart = Aig_ManStart( 5000 );
1290// pAigPart->pName = Extra_UtilStrsav( pAigPart->pName );
1291 Vec_IntClear( vPartSupp );
1292 Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, k )
1293 {
1294 vOuts = Aig_ManDupPart( pAigPart, pAig, vPart, vPartSupp, 0 );
1295 if ( k == 0 )
1296 {
1297 Vec_PtrForEachEntry( Aig_Obj_t *, vOuts, pObj, m )
1298 Aig_ObjCreateCo( pAigPart, pObj );
1299 }
1300 Vec_PtrFree( vOuts );
1301 }
1302 // derive the total AIG from the partitioned AIG
1303 vOuts = Aig_ManDupPart( pAigTotal, pAigPart, vPart, vPartSupp, 1 );
1304 // add to the outputs
1305 Vec_PtrForEachEntry( Aig_Obj_t *, vOuts, pObj, k )
1306 {
1307 assert( Vec_PtrEntry( vOutsTotal, Vec_IntEntry(vPart,k) ) == NULL );
1308 Vec_PtrWriteEntry( vOutsTotal, Vec_IntEntry(vPart,k), pObj );
1309 }
1310 Vec_PtrFree( vOuts );
1311 // store contents of pData pointers
1312 ppData = ABC_ALLOC( void *, Aig_ManObjNumMax(pAigPart) );
1313 Aig_ManForEachObj( pAigPart, pObj, k )
1314 ppData[k] = pObj->pData;
1315 // report the process
1316 if ( fVerbose )
1317 printf( "Part %4d (out of %4d) PI = %5d. PO = %5d. And = %6d. Lev = %4d.\r",
1318 i+1, Vec_PtrSize(vParts), Aig_ManCiNum(pAigPart), Aig_ManCoNum(pAigPart),
1319 Aig_ManNodeNum(pAigPart), Aig_ManLevelNum(pAigPart) );
1320 // compute equivalence classes (to be stored in pNew->pReprs)
1321 pAig = Fra_FraigChoice( pAigPart, nConfMax, nLevelMax );
1322 Aig_ManStop( pAig );
1323 // reset the pData pointers
1324 Aig_ManForEachObj( pAigPart, pObj, k )
1325 pObj->pData = ppData[k];
1326 ABC_FREE( ppData );
1327 // transfer representatives to the total AIG
1328 if ( pAigPart->pReprs )
1329 Aig_ManTransferRepr( pAigTotal, pAigPart );
1330 Aig_ManStop( pAigPart );
1331 }
1332 if ( fVerbose )
1333 printf( " \r" );
1334 Vec_VecFree( (Vec_Vec_t *)vParts );
1335 Vec_IntFree( vPartSupp );
1336
1337// Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "set progressbar" );
1338
1339 // clear the PI numbers
1340 Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pAig, i )
1341 Aig_ManForEachCi( pAig, pObj, k )
1342 pObj->pNext = NULL;
1343
1344 // add the outputs in the same order
1345 Vec_PtrForEachEntry( Aig_Obj_t *, vOutsTotal, pObj, i )
1346 Aig_ObjCreateCo( pAigTotal, pObj );
1347 Vec_PtrFree( vOutsTotal );
1348
1349 // derive the result of choicing
1350 pAig = Aig_ManRehash( pAigTotal );
1351 // create the equivalent nodes lists
1353 // reconstruct the network
1354 vPios = Aig_ManOrderPios( pAig, (Aig_Man_t *)Vec_PtrEntry(vAigs,0) );
1355 pAig = Aig_ManDupDfsGuided( pTemp = pAig, vPios );
1356 Aig_ManStop( pTemp );
1357 Vec_PtrFree( vPios );
1358 // duplicate the timing manager
1359 pTemp = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 );
1360 if ( pTemp->pManTime )
1361 pAig->pManTime = Tim_ManDup( (Tim_Man_t *)pTemp->pManTime, 0 );
1362 // reset levels
1363 Aig_ManChoiceLevel( pAig );
1364 return pAig;
1365}
1366
1379Aig_Man_t * Aig_ManFraigPartitioned( Aig_Man_t * pAig, int nPartSize, int nConfMax, int nLevelMax, int fVerbose )
1380{
1381// extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig, int nConfMax, int nLevelMax );
1382
1383 Aig_Man_t * pAigPart, * pAigTemp;
1384 Vec_Int_t * vPart;
1385 Vec_Ptr_t * vParts;
1386 Aig_Obj_t * pObj;
1387 void ** ppData;
1388 int i, k;
1389
1390 // partition the outputs of the AIG
1391 vParts = Aig_ManPartitionNaive( pAig, nPartSize );
1392
1393 // start the equivalence classes
1394 Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
1395
1396 // set the PI numbers
1397 Aig_ManSetCioIds( pAig );
1398
1399 // create the total fraiged AIG
1400 Vec_PtrForEachEntry( Vec_Int_t *, vParts, vPart, i )
1401 {
1402 // derive the partition AIG
1403 pAigPart = Aig_ManDupPartAll( pAig, vPart );
1404 // store contents of pData pointers
1405 ppData = ABC_ALLOC( void *, Aig_ManObjNumMax(pAigPart) );
1406 Aig_ManForEachObj( pAigPart, pObj, k )
1407 ppData[k] = pObj->pData;
1408 // report the process
1409 if ( fVerbose )
1410 printf( "Part %4d (out of %4d) PI = %5d. PO = %5d. And = %6d. Lev = %4d.\r",
1411 i+1, Vec_PtrSize(vParts), Aig_ManCiNum(pAigPart), Aig_ManCoNum(pAigPart),
1412 Aig_ManNodeNum(pAigPart), Aig_ManLevelNum(pAigPart) );
1413 // compute equivalence classes (to be stored in pNew->pReprs)
1414 pAigTemp = Fra_FraigChoice( pAigPart, nConfMax, nLevelMax );
1415 Aig_ManStop( pAigTemp );
1416 // reset the pData pointers
1417 Aig_ManForEachObj( pAigPart, pObj, k )
1418 pObj->pData = ppData[k];
1419 ABC_FREE( ppData );
1420 // transfer representatives to the total AIG
1421 if ( pAigPart->pReprs )
1422 Aig_ManTransferRepr( pAig, pAigPart );
1423 Aig_ManStop( pAigPart );
1424 }
1425 if ( fVerbose )
1426 printf( " \r" );
1427 Vec_VecFree( (Vec_Vec_t *)vParts );
1428
1429 // clear the PI numbers
1430 Aig_ManCleanCioIds( pAig );
1431
1432 // derive the result of choicing
1433 return Aig_ManDupRepr( pAig, 0 );
1434}
1435
1436
1437
1438
1450static inline void Aig_ObjSetRepr_( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 )
1451{
1452 assert( p->pReprs != NULL );
1453 assert( !Aig_IsComplement(pNode1) );
1454 assert( !Aig_IsComplement(pNode2) );
1455 assert( pNode1->Id < p->nReprsAlloc );
1456 assert( pNode2->Id < p->nReprsAlloc );
1457 if ( pNode1 == pNode2 )
1458 return;
1459 if ( pNode1->Id < pNode2->Id )
1460 p->pReprs[pNode2->Id] = pNode1;
1461 else
1462 p->pReprs[pNode1->Id] = pNode2;
1463}
1464
1479{
1480 Aig_Obj_t * pObj, * pObjNew;
1481 int i;
1482 assert( Aig_ManCiNum(pNew) == Aig_ManCiNum(pPrev) );
1483 assert( Aig_ManCiNum(pNew) == Aig_ManCiNum(pThis) );
1484 assert( Aig_ManCoNum(pNew) == Aig_ManCoNum(pPrev) );
1485 assert( Aig_ManCoNum(pNew) == Aig_ManCoNum(pThis) );
1486 // make sure the nodes of pPrev point to pNew
1487 Aig_ManForEachObj( pNew, pObj, i )
1488 pObj->fMarkB = 1;
1489 Aig_ManForEachObj( pPrev, pObj, i )
1490 assert( Aig_Regular((Aig_Obj_t *)pObj->pData)->fMarkB );
1491 Aig_ManForEachObj( pNew, pObj, i )
1492 pObj->fMarkB = 0;
1493 // make sure the nodes of pThis point to pPrev
1494 Aig_ManForEachObj( pPrev, pObj, i )
1495 pObj->fMarkB = 1;
1496 Aig_ManForEachObj( pPrev, pObj, i )
1497 pObj->fMarkB = 0;
1498 // remap nodes of pThis on top of pNew using pPrev
1499 pObj = Aig_ManConst1(pThis);
1500 pObj->pData = Aig_ManConst1(pNew);
1501 Aig_ManForEachCi( pThis, pObj, i )
1502 pObj->pData = Aig_ManCi(pNew, i);
1503 Aig_ManForEachCo( pThis, pObj, i )
1504 pObj->pData = Aig_ManCo(pNew, i);
1505 // go through the nodes in the topological order
1506 Aig_ManForEachNode( pThis, pObj, i )
1507 pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1508 // set the inputs of POs as equivalent
1509 Aig_ManForEachCo( pThis, pObj, i )
1510 {
1511 pObjNew = Aig_ObjFanin0( Aig_ManCo(pNew,i) );
1512 // pObjNew and Aig_ObjFanin0(pObj)->pData are equivalent
1513 Aig_ObjSetRepr_( pNew, pObjNew, Aig_Regular((Aig_Obj_t *)Aig_ObjFanin0(pObj)->pData) );
1514 }
1515}
1516
1529{
1530 Vec_Ptr_t * vSupp;
1531 Aig_Obj_t * pNode, * pTemp;
1532 int i, Counter;
1533
1534 vSupp = Vec_PtrAlloc( 100 );
1535 Aig_ManForEachNode( p, pNode, i )
1536 {
1537 if ( !Aig_ObjIsChoice(p, pNode) )
1538 continue;
1539 Counter = 0;
1540 for ( pTemp = pNode; pTemp; pTemp = Aig_ObjEquiv(p, pTemp) )
1541 Counter++;
1542 printf( "Choice node = %5d. Level = %2d. Choices = %d. { ", pNode->Id, pNode->Level, Counter );
1543 for ( pTemp = pNode; pTemp; pTemp = Aig_ObjEquiv(p, pTemp) )
1544 {
1545 Counter = Aig_NodeMffcSupp( p, pTemp, 0, vSupp );
1546 printf( "S=%d N=%d L=%d ", Vec_PtrSize(vSupp), Counter, pTemp->Level );
1547 }
1548 printf( "}\n" );
1549 }
1550 Vec_PtrFree( vSupp );
1551}
1552
1565{
1566 Vec_Ptr_t * vPios;
1567 Aig_Man_t * pNew, * pThis, * pPrev, * pTemp;
1568 int i;
1569 // start AIG with choices
1570 pPrev = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 );
1571 pNew = Aig_ManDupOrdered( pPrev );
1572 // create room for equivalent nodes and representatives
1573 assert( pNew->pReprs == NULL );
1574 pNew->nReprsAlloc = Vec_PtrSize(vAigs) * Aig_ManObjNumMax(pNew);
1575 pNew->pReprs = ABC_ALLOC( Aig_Obj_t *, pNew->nReprsAlloc );
1576 memset( pNew->pReprs, 0, sizeof(Aig_Obj_t *) * pNew->nReprsAlloc );
1577 // add other AIGs one by one
1578 Vec_PtrForEachEntryStart( Aig_Man_t *, vAigs, pThis, i, 1 )
1579 {
1580 Aig_ManChoiceConstructiveOne( pNew, pPrev, pThis );
1581 pPrev = pThis;
1582 }
1583 // derive the result of choicing
1584 pNew = Aig_ManRehash( pNew );
1585 // create the equivalent nodes lists
1587 // reconstruct the network
1588 vPios = Aig_ManOrderPios( pNew, (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 ) );
1589 pNew = Aig_ManDupDfsGuided( pTemp = pNew, vPios );
1590 Aig_ManStop( pTemp );
1591 Vec_PtrFree( vPios );
1592 // duplicate the timing manager
1593 pTemp = (Aig_Man_t *)Vec_PtrEntry( vAigs, 0 );
1594 if ( pTemp->pManTime )
1595 pNew->pManTime = Tim_ManDup( (Tim_Man_t *)pTemp->pManTime, 0 );
1596 // reset levels
1597 Aig_ManChoiceLevel( pNew );
1598 return pNew;
1599}
1600
1601/*
1602 Vec_Ptr_t * vPios;
1603 vPios = Aig_ManOrderPios( pMan, pAig );
1604 Vec_PtrFree( vPios );
1605*/
1606
1610
1611
1613
int nWords
Definition abcNpn.c:127
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#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
void Part_ManStop(Part_Man_t *p)
Definition aigPart.c:94
struct Part_One_t_ Part_One_t
Definition aigPart.c:43
Aig_Man_t * Aig_ManDupPartAll(Aig_Man_t *pOld, Vec_Int_t *vPart)
Definition aigPart.c:1098
Part_Man_t * Part_ManStart(int nChunkSize, int nStepSize)
FUNCTION DEFINITIONS ///.
Definition aigPart.c:71
Vec_Ptr_t * Aig_ManPartitionNaive(Aig_Man_t *p, int nPartSize)
Definition aigPart.c:941
Vec_Ptr_t * Aig_ManSupportsRegisters(Aig_Man_t *p)
Definition aigPart.c:418
void Aig_ManSupportsTest(Aig_Man_t *pMan)
Definition aigPart.c:366
Aig_Man_t * Aig_ManChoiceConstructive(Vec_Ptr_t *vAigs, int fVerbose)
Definition aigPart.c:1564
int Aig_ManPartitionSmartFindPart(Vec_Ptr_t *vPartSuppsAll, Vec_Ptr_t *vPartsAll, Vec_Ptr_t *vPartSuppsBit, int nSuppSizeLimit, Vec_Int_t *vOne)
Definition aigPart.c:536
Vec_Ptr_t * Aig_ManSupportNodes(Aig_Man_t *p, Vec_Ptr_t *vParts)
Definition aigPart.c:1156
Aig_Man_t * Aig_ManFraigPartitioned(Aig_Man_t *pAig, int nPartSize, int nConfMax, int nLevelMax, int fVerbose)
Definition aigPart.c:1379
unsigned * Aig_ManSuppCharStart(Vec_Int_t *vOne, int nPis)
Definition aigPart.c:470
typedefABC_NAMESPACE_IMPL_START struct Part_Man_t_ Part_Man_t
DECLARATIONS ///.
Definition aigPart.c:32
int Aig_ManSuppCharCommon(unsigned *pBuffer, Vec_Int_t *vOne)
Definition aigPart.c:517
char * Part_ManFetch(Part_Man_t *p, int nSize)
Definition aigPart.c:116
Aig_Man_t * Aig_ManChoicePartitioned(Vec_Ptr_t *vAigs, int nPartSize, int nConfMax, int nLevelMax, int fVerbose)
Definition aigPart.c:1247
void Part_ManRecycle(Part_Man_t *p, char *pMemory, int nSize)
Definition aigPart.c:153
Vec_Ptr_t * Aig_ManPartitionSmartRegisters(Aig_Man_t *pAig, int nSuppSizeLimit, int fVerbose)
Definition aigPart.c:811
Vec_Ptr_t * Aig_ManSupportsInverse(Aig_Man_t *p)
Definition aigPart.c:385
Part_One_t * Part_ManMergeEntry(Part_Man_t *pMan, Part_One_t *p1, Part_One_t *p2, int nRefs)
Definition aigPart.c:212
Vec_Ptr_t * Aig_ManSupports(Aig_Man_t *pMan)
Definition aigPart.c:273
void Aig_ManPartitionCompact(Vec_Ptr_t *vPartsAll, Vec_Ptr_t *vPartSuppsAll, int nSuppSizeLimit)
Definition aigPart.c:614
void Aig_ManSupportNodes_rec(Aig_Man_t *p, Aig_Obj_t *pObj, Vec_Int_t *vSupport)
Definition aigPart.c:1131
Vec_Int_t * Part_ManTransferEntry(Part_One_t *p)
Definition aigPart.c:251
void Aig_ManChoiceEval(Aig_Man_t *p)
Definition aigPart.c:1528
void Aig_ManChoiceConstructiveOne(Aig_Man_t *pNew, Aig_Man_t *pPrev, Aig_Man_t *pThis)
Definition aigPart.c:1478
void Aig_ManDupPartAll_rec(Aig_Man_t *pNew, Aig_Man_t *pOld, Aig_Obj_t *pObj)
Definition aigPart.c:1062
Vec_Ptr_t * Aig_ManMiterPartitioned(Aig_Man_t *p1, Aig_Man_t *p2, int nPartSize, int fSmart)
Definition aigPart.c:1189
Vec_Ptr_t * Aig_ManDupPart(Aig_Man_t *pNew, Aig_Man_t *pOld, Vec_Int_t *vPart, Vec_Int_t *vSuppMap, int fInverse)
Definition aigPart.c:995
Vec_Ptr_t * Aig_ManPartitionSmart(Aig_Man_t *p, int nSuppSizeLimit, int fVerbose, Vec_Ptr_t **pvPartSupps)
Definition aigPart.c:686
void Aig_ManPartitionPrint(Aig_Man_t *p, Vec_Ptr_t *vPartsAll, Vec_Ptr_t *vPartSuppsAll)
Definition aigPart.c:585
void Aig_ManSuppCharAdd(unsigned *pBuffer, Vec_Int_t *vOne, int nPis)
Definition aigPart.c:496
Aig_Obj_t * Aig_ManDupPart_rec(Aig_Man_t *pNew, Aig_Man_t *pOld, Aig_Obj_t *pObj, Vec_Int_t *vSuppMap)
Definition aigPart.c:966
Aig_Man_t * Aig_ManDupRepr(Aig_Man_t *p, int fOrdered)
Definition aigRepr.c:267
Vec_Ptr_t * Aig_ManOrderPios(Aig_Man_t *p, Aig_Man_t *pOrder)
Definition aigDup.c:626
Aig_Man_t * Aig_ManDupOrdered(Aig_Man_t *p)
Definition aigDup.c:277
Aig_Man_t * Aig_ManRehash(Aig_Man_t *p)
Definition aigRepr.c:454
void Aig_ManSetCioIds(Aig_Man_t *p)
Definition aigUtil.c:978
int Aig_ManLevelNum(Aig_Man_t *p)
Definition aigDfs.c:500
void Aig_ManReprStart(Aig_Man_t *p, int nIdMax)
DECLARATIONS ///.
Definition aigRepr.c:45
#define Aig_ManForEachObj(p, pObj, i)
Definition aig.h:403
void Aig_ManStop(Aig_Man_t *p)
Definition aigMan.c:187
void Aig_ManIncrementTravId(Aig_Man_t *p)
DECLARATIONS ///.
Definition aigUtil.c:44
#define Aig_ManForEachCi(p, pObj, i)
ITERATORS ///.
Definition aig.h:393
Aig_Obj_t * Aig_And(Aig_Man_t *p, Aig_Obj_t *p0, Aig_Obj_t *p1)
Definition aigOper.c:104
Aig_Obj_t * Aig_ObjCreateCo(Aig_Man_t *p, Aig_Obj_t *pDriver)
Definition aigObj.c:66
Aig_Man_t * Aig_ManStartFrom(Aig_Man_t *p)
Definition aigMan.c:92
void Aig_ManCleanCioIds(Aig_Man_t *p)
Definition aigUtil.c:999
struct Aig_Obj_t_ Aig_Obj_t
Definition aig.h:51
void Aig_ManMarkValidChoices(Aig_Man_t *p)
Definition aigRepr.c:481
Aig_Man_t * Aig_ManDupDfsGuided(Aig_Man_t *p, Vec_Ptr_t *vPios)
Definition aigDup.c:694
Aig_Man_t * Aig_ManStart(int nNodesMax)
DECLARATIONS ///.
Definition aigMan.c:47
#define Aig_ManForEachNode(p, pObj, i)
Definition aig.h:413
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition aig.h:50
int Aig_ManCleanup(Aig_Man_t *p)
Definition aigMan.c:265
#define Aig_ManForEachCo(p, pObj, i)
Definition aig.h:398
int Aig_NodeMffcSupp(Aig_Man_t *p, Aig_Obj_t *pNode, int LevelMin, Vec_Ptr_t *vSupp)
Definition aigMffc.c:179
Aig_Obj_t * Aig_ObjCreateCi(Aig_Man_t *p)
DECLARATIONS ///.
Definition aigObj.c:45
void Aig_ManCleanData(Aig_Man_t *p)
Definition aigUtil.c:205
void Aig_ManTransferRepr(Aig_Man_t *pNew, Aig_Man_t *p)
Definition aigRepr.c:211
int Aig_ManChoiceLevel(Aig_Man_t *p)
Definition aigDfs.c:595
Aig_Obj_t * Aig_MiterTwo(Aig_Man_t *p, Vec_Ptr_t *vNodes1, Vec_Ptr_t *vNodes2)
Definition aigOper.c:453
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Cube * p
Definition exorList.c:222
Aig_Man_t * Fra_FraigChoice(Aig_Man_t *pManAig, int nConfMax, int nLevelMax)
Definition fraCore.c:442
int Id
Definition aig.h:85
unsigned int nRefs
Definition aig.h:81
unsigned int fMarkB
Definition aig.h:80
Aig_Obj_t * pNext
Definition aig.h:72
void * pData
Definition aig.h:87
unsigned Level
Definition aig.h:82
int nFreeSize
Definition aigPart.c:38
int nChunkSize
Definition aigPart.c:35
int nStepSize
Definition aigPart.c:36
char * pFreeBuf
Definition aigPart.c:37
Vec_Ptr_t * vFree
Definition aigPart.c:40
Vec_Ptr_t * vMemory
Definition aigPart.c:39
int nRefs
Definition aigPart.c:46
int pOuts[0]
Definition aigPart.c:49
int nOutsAlloc
Definition aigPart.c:48
int nOuts
Definition aigPart.c:47
typedefABC_NAMESPACE_HEADER_START struct Tim_Man_t_ Tim_Man_t
INCLUDES ///.
Definition tim.h:92
Tim_Man_t * Tim_ManDup(Tim_Man_t *p, int fUnitDelay)
Definition timMan.c:86
#define assert(ex)
Definition util_old.h:213
char * memset()
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_PtrForEachEntryStart(Type, vVec, pEntry, i, Start)
Definition vecPtr.h:57
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42