30#ifdef ABC_USE_PTHREADS
33#include "../lib/pthread.h"
46#ifndef ABC_USE_PTHREADS
56#define KF_WORD_MAX ((KF_LEAF_MAX > 6) ? 1 << (KF_LEAF_MAX-6) : 1)
62typedef struct Kf_Cut_t_ Kf_Cut_t;
63typedef struct Kf_Set_t_ Kf_Set_t;
64typedef struct Kf_Man_t_ Kf_Man_t;
75 int pLeaves[KF_LEAF_MAX];
80 unsigned short nLutSize;
81 unsigned short nCutNum;
87 int pTable[1 << KF_LOG_TABLE];
88 int pValue[1 << KF_LOG_TABLE];
89 int pPlace[KF_LEAF_MAX];
90 int pList [KF_LEAF_MAX+1];
91 Kf_Cut_t pCuts0[KF_CUT_MAX];
92 Kf_Cut_t pCuts1[KF_CUT_MAX];
93 Kf_Cut_t pCutsR[KF_CUT_MAX*KF_CUT_MAX];
94 Kf_Cut_t * ppCuts[KF_CUT_MAX];
109 Kf_Set_t pSett[KF_PROC_MAX];
112static inline int Kf_SetCutId( Kf_Set_t *
p, Kf_Cut_t * pCut ) {
return pCut -
p->pCutsR; }
113static inline Kf_Cut_t * Kf_SetCut( Kf_Set_t *
p,
int i ) {
return i >= 0 ?
p->pCutsR + i : NULL; }
115static inline int Kf_ObjTime( Kf_Man_t *
p,
int i ) {
return Vec_IntEntry(&
p->vTime, i); }
116static inline float Kf_ObjArea( Kf_Man_t *
p,
int i ) {
return Vec_FltEntry(&
p->vArea, i); }
117static inline float Kf_ObjRefs( Kf_Man_t *
p,
int i ) {
return Vec_FltEntry(&
p->vRefs, i); }
119static inline void Kf_ObjSetCuts( Kf_Man_t *
p,
int i,
Vec_Int_t * vVec ) { Vec_IntWriteEntry(&
p->vCuts, i, Vec_SetAppend(&
p->pMem, Vec_IntArray(vVec), Vec_IntSize(vVec))); }
120static inline int * Kf_ObjCuts( Kf_Man_t *
p,
int i ) {
return (
int *)Vec_SetEntry(&
p->pMem, Vec_IntEntry(&
p->vCuts, i)); }
121static inline int * Kf_ObjCuts0( Kf_Man_t *
p,
int i ) {
return Kf_ObjCuts(
p, Gia_ObjFaninId0(Gia_ManObj(
p->pGia, i), i)); }
122static inline int * Kf_ObjCuts1( Kf_Man_t *
p,
int i ) {
return Kf_ObjCuts(
p, Gia_ObjFaninId1(Gia_ManObj(
p->pGia, i), i)); }
123static inline int * Kf_ObjCutBest( Kf_Man_t *
p,
int i ) {
int * pCuts = Kf_ObjCuts(
p, i);
return pCuts + pCuts[1]; }
125#define Kf_ObjForEachCutInt( pList, pCut, i ) for ( i = 0, pCut = pList + KF_ADD_ON1; i < pList[0]; i++, pCut += pCut[0] + KF_ADD_ON2 )
126#define Kf_ListForEachCut( p, iList, pCut ) for ( pCut = Kf_SetCut(p, p->pList[iList]); pCut; pCut = Kf_SetCut(p, pCut->iNext) )
127#define Kf_ListForEachCutP( p, iList, pCut, pPlace ) for ( pPlace = p->pList+iList, pCut = Kf_SetCut(p, *pPlace); pCut; pCut = Kf_SetCut(p, *pPlace) )
144static inline int Kf_SetLoadCuts( Kf_Cut_t * pCuts,
int * pIntCuts )
147 int k, * pIntCut, nCuts = 0;
148 Kf_ObjForEachCutInt( pIntCuts, pIntCut, nCuts )
150 pCut = pCuts + nCuts;
153 pCut->iFunc = pIntCut[pIntCut[0] + 1];
154 pCut->Delay = pIntCut[pIntCut[0] + 2];
155 pCut->Area = Abc_Int2Float(pIntCut[pIntCut[0] + 3]);
156 pCut->nLeaves = pIntCut[0];
157 for ( k = 0; k < pIntCut[0]; k++ )
159 pCut->pLeaves[k] = Abc_Lit2Var(pIntCut[k+1]);
160 pCut->Sign |= ((
word)1) << (pCut->pLeaves[k] & 0x3F);
161 if ( Abc_LitIsCompl(pIntCut[k+1]) )
162 pCut->Polar |= (1 << k);
167static inline void Kf_SetPrepare( Kf_Set_t *
p,
int * pCuts0,
int * pCuts1 )
174 for ( i = 0; i <=
p->nLutSize; i++ )
177 p->nCuts0 = Kf_SetLoadCuts(
p->pCuts0, pCuts0 );
178 p->nCuts1 = Kf_SetLoadCuts(
p->pCuts1, pCuts1 );
193static inline void Kf_ManStoreStart(
Vec_Int_t * vTemp,
int nCuts )
195 Vec_IntClear( vTemp );
196 Vec_IntPush( vTemp, nCuts );
197 Vec_IntPush( vTemp, -1 );
199static inline void Kf_ManStoreAddUnit(
Vec_Int_t * vTemp,
int iObj,
int Time,
float Area )
201 Vec_IntAddToEntry( vTemp, 0, 1 );
202 Vec_IntPush( vTemp, 1 );
203 Vec_IntPush( vTemp, Abc_Var2Lit(iObj, 0) );
204 Vec_IntPush( vTemp, 2 );
205 Vec_IntPush( vTemp, Time );
206 Vec_IntPush( vTemp, Abc_Float2Int(Area) );
208static inline void Kf_ManSaveResults( Kf_Cut_t ** ppCuts,
int nCuts, Kf_Cut_t * pCutBest,
Vec_Int_t * vTemp )
211 assert( nCuts > 0 && nCuts < KF_CUT_MAX );
212 Kf_ManStoreStart( vTemp, nCuts );
213 for ( i = 0; i < nCuts; i++ )
215 if ( ppCuts[i] == pCutBest )
216 Vec_IntWriteEntry( vTemp, 1, Vec_IntSize(vTemp) );
217 Vec_IntPush( vTemp, ppCuts[i]->nLeaves );
219 for ( k = 0; k < ppCuts[i]->nLeaves; k++ )
220 Vec_IntPush( vTemp, Abc_Var2Lit(ppCuts[i]->pLeaves[k], 0) );
221 Vec_IntPush( vTemp, ppCuts[i]->iFunc );
222 Vec_IntPush( vTemp, ppCuts[i]->Delay );
223 Vec_IntPush( vTemp, Abc_Float2Int(ppCuts[i]->Area) );
225 assert( Vec_IntEntry(vTemp, 1) > 0 );
227static inline int Kf_SetCompareCuts( Kf_Cut_t * p1, Kf_Cut_t * p2 )
229 if ( p1 == NULL || p2 == NULL )
230 return (p1 != NULL) - (p2 != NULL);
231 if ( p1->nLeaves != p2->nLeaves )
232 return p1->nLeaves - p2->nLeaves;
233 return memcmp( p1->pLeaves, p2->pLeaves,
sizeof(
int)*p1->nLeaves );
235static inline void Kf_SetAddToList( Kf_Set_t *
p, Kf_Cut_t * pCut,
int fSort )
238 pCut->iNext =
p->pList[pCut->nLeaves],
p->pList[pCut->nLeaves] = Kf_SetCutId(
p, pCut);
243 Vec_IntSelectSort( pCut->pLeaves, pCut->nLeaves );
244 Kf_ListForEachCutP(
p, pCut->nLeaves, pTemp, pPlace )
246 if ( (Value = Kf_SetCompareCuts(pTemp, pCut)) > 0 )
249 pPlace = &pTemp->iNext;
251 pCut->iNext = *pPlace, *pPlace = Kf_SetCutId(
p, pCut);
254static inline int Kf_CutCompare( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1,
int fArea )
258 if ( pCut0->Area < pCut1->Area )
return -1;
259 if ( pCut0->Area > pCut1->Area )
return 1;
260 if ( pCut0->Delay < pCut1->Delay )
return -1;
261 if ( pCut0->Delay > pCut1->Delay )
return 1;
262 if ( pCut0->nLeaves < pCut1->nLeaves )
return -1;
263 if ( pCut0->nLeaves > pCut1->nLeaves )
return 1;
267 if ( pCut0->Delay < pCut1->Delay )
return -1;
268 if ( pCut0->Delay > pCut1->Delay )
return 1;
269 if ( pCut0->nLeaves < pCut1->nLeaves )
return -1;
270 if ( pCut0->nLeaves > pCut1->nLeaves )
return 1;
271 if ( pCut0->Area < pCut1->Area )
return -1;
272 if ( pCut0->Area > pCut1->Area )
return 1;
276static inline int Kf_SetStoreAddOne( Kf_Set_t *
p,
int nCuts,
int nCutNum, Kf_Cut_t * pCut,
int fArea )
279 p->ppCuts[nCuts] = pCut;
282 for ( i = nCuts; i > 0; i-- )
283 if ( Kf_CutCompare(
p->ppCuts[i-1],
p->ppCuts[i], fArea) > 0 )
284 ABC_SWAP( Kf_Cut_t *,
p->ppCuts[i-1],
p->ppCuts[i] )
287 return Abc_MinInt( nCuts+1, nCutNum );
289static inline void Kf_SetSelectBest( Kf_Set_t *
p,
int fArea,
int fSort )
294 for ( i = 0; i <=
p->nLutSize; i++ )
295 Kf_ListForEachCut(
p, i, pCut )
296 nCuts = Kf_SetStoreAddOne(
p, nCuts,
p->nCutNum-1, pCut, fArea );
297 assert( nCuts > 0 && nCuts < p->nCutNum );
299 p->pCutBest =
p->ppCuts[0];
303 for ( i = 0; i <=
p->nLutSize; i++ )
305 for ( i = 0; i < nCuts; i++ )
306 Kf_SetAddToList(
p,
p->ppCuts[i], 0 );
308 for ( i =
p->nLutSize; i >= 0; i-- )
309 Kf_ListForEachCut(
p, i, pCut )
310 p->ppCuts[
p->nCuts++] = pCut;
325static inline int Kf_CheckCut( Kf_Cut_t * pBase, Kf_Cut_t * pCut )
327 int nSizeB = pBase->nLeaves;
328 int nSizeC = pCut->nLeaves;
329 int * pB = pBase->pLeaves;
330 int * pC = pCut->pLeaves;
332 for ( i = 0; i < nSizeC; i++ )
334 for ( k = 0; k < nSizeB; k++ )
335 if ( pC[i] == pB[k] )
342static inline int Kf_CheckCuts( Kf_Set_t *
p )
344 Kf_Cut_t * pCut0, * pCut1;
345 int i, k, m, n, Value;
347 for ( i = 0; i <=
p->nLutSize; i++ )
348 Kf_ListForEachCut(
p, i, pCut0 )
351 for ( m = 0; m < pCut0->nLeaves; m++ )
352 for ( n = m+1; n < pCut0->nLeaves; n++ )
353 assert( pCut0->pLeaves[m] != pCut0->pLeaves[n] );
355 for ( k = 0; k <=
p->nLutSize; k++ )
356 Kf_ListForEachCut(
p, k, pCut1 )
358 if ( pCut0 == pCut1 )
361 Value = Kf_CheckCut( pCut0, pCut1 );
379static inline int Kf_HashLookup( Kf_Set_t *
p,
int i )
383 for ( k = i &
p->TableMask;
p->pTable[k]; k = (k + 1) &
p->TableMask )
384 if (
p->pTable[k] == i )
388static inline int Kf_HashFindOrAdd( Kf_Set_t *
p,
int i )
390 int k = Kf_HashLookup(
p, i );
393 if (
p->nTEntries ==
p->nLutSize )
397 p->pPlace[
p->nTEntries] = k;
398 p->pValue[k] =
p->nTEntries++;
401static inline void Kf_HashPopulate( Kf_Set_t *
p, Kf_Cut_t * pCut )
405 for ( i = 0; i < pCut->nLeaves; i++ )
406 Kf_HashFindOrAdd(
p, pCut->pLeaves[i] );
407 assert(
p->nTEntries == pCut->nLeaves );
409static inline void Kf_HashCleanup( Kf_Set_t *
p,
int iStart )
412 for ( i = iStart; i <
p->nTEntries; i++ )
413 p->pTable[
p->pPlace[i]] = 0;
414 p->nTEntries = iStart;
428static inline int Kf_SetCountBits(
word i )
430 i = i - ((i >> 1) & 0x5555555555555555);
431 i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
432 i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
433 return (i*(0x0101010101010101))>>56;
435static inline word Kf_SetCutGetSign( Kf_Cut_t *
p )
437 word Sign = 0;
int i;
438 for ( i = 0; i <
p->nLeaves; i++ )
439 Sign |= ((
word)1) << (
p->pLeaves[i] & 0x3F);
443static inline int Kf_SetCutDominatedByThis( Kf_Set_t *
p, Kf_Cut_t * pCut )
446 for ( i = 0; i < pCut->nLeaves; i++ )
447 if ( Kf_HashLookup(
p, pCut->pLeaves[i]) >= 0 )
451static inline int Kf_SetRemoveDuplicates( Kf_Set_t *
p,
int nLeaves,
word Sign )
454 Kf_ListForEachCut(
p, nLeaves, pCut )
455 if ( pCut->Sign == Sign && Kf_SetCutDominatedByThis(
p, pCut) )
459static inline void Kf_SetFilter( Kf_Set_t *
p )
461 Kf_Cut_t * pCut0, * pCut1;
464 for ( i = 0; i <=
p->nLutSize; i++ )
465 Kf_ListForEachCutP(
p, i, pCut0, pPlace )
467 Kf_HashPopulate(
p, pCut0 );
468 for ( k = 0; k < pCut0->nLeaves; k++ )
469 Kf_ListForEachCut(
p, k, pCut1 )
470 if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutDominatedByThis(
p, pCut1) )
471 { k = pCut0->nLeaves;
p->nCuts--;
break; }
472 if ( k == pCut0->nLeaves + 1 )
473 *pPlace = pCut0->iNext;
475 pPlace = &pCut0->iNext;
476 Kf_HashCleanup(
p, 0 );
480static inline void Kf_SetMergePairs( Kf_Set_t *
p, Kf_Cut_t * pCut0, Kf_Cut_t * pCuts,
int nCuts,
int fArea )
482 Kf_Cut_t * pCut1, * pCutR;
int i;
483 Kf_HashPopulate(
p, pCut0 );
484 for ( pCut1 = pCuts; pCut1 < pCuts + nCuts; pCut1++ )
486 if ( pCut0->nLeaves + pCut1->nLeaves >
p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) >
p->nLutSize )
488 Kf_HashCleanup(
p, pCut0->nLeaves );
489 for ( i = 0; i < pCut1->nLeaves; i++ )
490 if ( Kf_HashFindOrAdd(
p, pCut1->pLeaves[i]) )
492 if ( i < pCut1->nLeaves )
495 if ( Kf_SetRemoveDuplicates(
p,
p->nTEntries, pCut0->Sign | pCut1->Sign) )
498 pCutR =
p->pCutsR +
p->nCuts++;
499 pCutR->nLeaves =
p->nTEntries;
500 for ( i = 0; i <
p->nTEntries; i++ )
501 pCutR->pLeaves[i] =
p->pTable[
p->pPlace[i]];
502 pCutR->Sign = pCut0->Sign | pCut1->Sign;
503 pCutR->Delay = Abc_MaxInt(pCut0->Delay, pCut1->Delay);
504 pCutR->Area = pCut0->Area + pCut1->Area;
506 Kf_SetAddToList(
p, pCutR, 0 );
508 Kf_HashCleanup(
p, 0 );
510static inline void Kf_SetMerge( Kf_Set_t *
p,
int * pCuts0,
int * pCuts1,
int fArea,
int fCutMin )
513 Kf_SetPrepare(
p, pCuts0, pCuts1 );
514 p->CutCount[0] +=
p->nCuts0 *
p->nCuts1;
517 for ( c0 = c1 = 0; c0 <
p->nCuts0 && c1 <
p->nCuts1; )
519 if (
p->pCuts0[c0].nLeaves >=
p->pCuts1[c1].nLeaves )
520 Kf_SetMergePairs(
p,
p->pCuts0 + c0++,
p->pCuts1 + c1,
p->nCuts1 - c1, fArea );
522 Kf_SetMergePairs(
p,
p->pCuts1 + c1++,
p->pCuts0 + c0,
p->nCuts0 - c0, fArea );
524 p->CutCount[2] +=
p->nCuts;
527 p->CutCount[3] += Abc_MinInt(
p->nCuts,
p->nCutNum-1 );
528 Kf_SetSelectBest(
p, fArea, 1 );
542static inline int Kf_SetCutIsContainedSimple( Kf_Cut_t * pBase, Kf_Cut_t * pCut )
544 int nSizeB = pBase->nLeaves;
545 int nSizeC = pCut->nLeaves;
546 int * pB = pBase->pLeaves;
547 int * pC = pCut->pLeaves;
549 assert( nSizeB >= nSizeC );
550 for ( i = 0; i < nSizeC; i++ )
552 for ( k = 0; k < nSizeB; k++ )
553 if ( pC[i] == pB[k] )
560static inline int Kf_SetMergeSimpleOne( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1, Kf_Cut_t * pCut,
int nLutSize )
562 int nSize0 = pCut0->nLeaves;
563 int nSize1 = pCut1->nLeaves;
564 int * pC0 = pCut0->pLeaves;
565 int * pC1 = pCut1->pLeaves;
566 int * pC = pCut->pLeaves;
570 for ( i = 0; i < nSize1; i++ )
572 for ( k = 0; k < nSize0; k++ )
573 if ( pC1[i] == pC0[k] )
581 for ( i = 0; i < nSize0; i++ )
586static inline int Kf_SetRemoveDuplicatesSimple( Kf_Set_t *
p, Kf_Cut_t * pCutNew )
589 Kf_ListForEachCut(
p, pCutNew->nLeaves, pCut )
590 if ( pCut->Sign == pCutNew->Sign && Kf_SetCutIsContainedSimple(pCut, pCutNew) )
594static inline void Kf_SetFilterSimple( Kf_Set_t *
p )
596 Kf_Cut_t * pCut0, * pCut1;
599 for ( i = 0; i <=
p->nLutSize; i++ )
600 Kf_ListForEachCutP(
p, i, pCut0, pPlace )
602 for ( k = 0; k < pCut0->nLeaves; k++ )
603 Kf_ListForEachCut(
p, k, pCut1 )
604 if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutIsContainedSimple(pCut0, pCut1) )
605 { k = pCut0->nLeaves;
p->nCuts--;
break; }
606 if ( k == pCut0->nLeaves + 1 )
607 *pPlace = pCut0->iNext;
609 pPlace = &pCut0->iNext;
613static inline void Kf_SetMergeSimple( Kf_Set_t *
p,
int * pCuts0,
int * pCuts1,
int fArea,
int fCutMin )
615 Kf_Cut_t * pCut0, * pCut1, * pCutR;
616 Kf_SetPrepare(
p, pCuts0, pCuts1 );
617 p->CutCount[0] +=
p->nCuts0 *
p->nCuts1;
618 for ( pCut0 =
p->pCuts0; pCut0 < p->pCuts0 +
p->nCuts0; pCut0++ )
619 for ( pCut1 =
p->pCuts1; pCut1 < p->pCuts1 +
p->nCuts1; pCut1++ )
621 if ( pCut0->nLeaves + pCut1->nLeaves >
p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) >
p->nLutSize )
624 pCutR =
p->pCutsR +
p->nCuts;
625 if ( !Kf_SetMergeSimpleOne(pCut0, pCut1, pCutR,
p->nLutSize) )
628 pCutR->Sign = pCut0->Sign | pCut1->Sign;
629 if ( Kf_SetRemoveDuplicatesSimple(
p, pCutR) )
634 int nOldSupp = pCutR->nLeaves;
636 assert( pCutR->nLeaves <= nOldSupp );
637 if ( pCutR->nLeaves < nOldSupp )
638 pCutR->Sign = Kf_SetCutGetSign( pCutR );
641 assert( pCutR->nLeaves > 1 );
642 pCutR->Delay = Abc_MaxInt(pCut0->Delay, pCut1->Delay);
643 pCutR->Area = pCut0->Area + pCut1->Area;
645 Kf_SetAddToList(
p, pCutR, 0 );
647 Kf_SetFilterSimple(
p );
649 p->CutCount[3] += Abc_MinInt(
p->nCuts,
p->nCutNum-1 );
650 Kf_SetSelectBest(
p, fArea, 1 );
664static inline int Kf_SetCutIsContainedOrder( Kf_Cut_t * pBase, Kf_Cut_t * pCut )
666 int nSizeB = pBase->nLeaves;
667 int nSizeC = pCut->nLeaves;
669 if ( nSizeB == nSizeC )
671 for ( i = 0; i < nSizeB; i++ )
672 if ( pBase->pLeaves[i] != pCut->pLeaves[i] )
676 assert( nSizeB > nSizeC );
677 for ( i = k = 0; i < nSizeB; i++ )
679 if ( pBase->pLeaves[i] > pCut->pLeaves[k] )
681 if ( pBase->pLeaves[i] == pCut->pLeaves[k] )
689static inline int Kf_SetMergeOrderOne( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1, Kf_Cut_t * pCut,
int nLutSize )
691 int nSize0 = pCut0->nLeaves;
692 int nSize1 = pCut1->nLeaves;
693 int * pC0 = pCut0->pLeaves;
694 int * pC1 = pCut1->pLeaves;
695 int * pC = pCut->pLeaves;
698 if ( nSize0 == nLutSize && nSize1 == nLutSize )
700 for ( i = 0; i < nSize0; i++ )
702 if ( pC0[i] != pC1[i] )
return 0;
705 pCut->nLeaves = nLutSize;
712 if ( c == nLutSize )
return 0;
713 if ( pC0[i] < pC1[k] )
716 if ( i >= nSize0 )
goto FlushCut1;
718 else if ( pC0[i] > pC1[k] )
721 if ( k >= nSize1 )
goto FlushCut0;
725 pC[c++] = pC0[i++]; k++;
726 if ( i >= nSize0 )
goto FlushCut1;
727 if ( k >= nSize1 )
goto FlushCut0;
732 if ( c + nSize0 > nLutSize + i )
return 0;
739 if ( c + nSize1 > nLutSize + k )
return 0;
745static inline int Kf_SetRemoveDuplicatesOrder( Kf_Set_t *
p, Kf_Cut_t * pCutNew )
748 Kf_ListForEachCut(
p, pCutNew->nLeaves, pCut )
749 if ( pCut->Sign == pCutNew->Sign && Kf_SetCutIsContainedOrder(pCut, pCutNew) )
753static inline void Kf_SetFilterOrder( Kf_Set_t *
p )
755 Kf_Cut_t * pCut0, * pCut1;
758 for ( i = 0; i <=
p->nLutSize; i++ )
759 Kf_ListForEachCutP(
p, i, pCut0, pPlace )
761 for ( k = 0; k < pCut0->nLeaves; k++ )
762 Kf_ListForEachCut(
p, k, pCut1 )
763 if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutIsContainedOrder(pCut0, pCut1) )
764 { k = pCut0->nLeaves;
p->nCuts--;
break; }
765 if ( k == pCut0->nLeaves + 1 )
766 *pPlace = pCut0->iNext;
768 pPlace = &pCut0->iNext;
793static inline void Kf_SetMergeOrder( Kf_Set_t *
p,
int * pCuts0,
int * pCuts1,
int fArea,
int fCutMin )
795 Kf_Cut_t * pCut0, * pCut1, * pCutR;
796 Kf_SetPrepare(
p, pCuts0, pCuts1 );
797 p->CutCount[0] +=
p->nCuts0 *
p->nCuts1;
798 for ( pCut0 =
p->pCuts0; pCut0 < p->pCuts0 +
p->nCuts0; pCut0++ )
799 for ( pCut1 =
p->pCuts1; pCut1 < p->pCuts1 +
p->nCuts1; pCut1++ )
801 if ( pCut0->nLeaves + pCut1->nLeaves >
p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) >
p->nLutSize )
804 pCutR =
p->pCutsR +
p->nCuts;
805 if ( !Kf_SetMergeOrderOne(pCut0, pCut1, pCutR,
p->nLutSize) )
808 pCutR->Sign = pCut0->Sign | pCut1->Sign;
809 if ( Kf_SetRemoveDuplicatesOrder(
p, pCutR) )
814 int nOldSupp = pCutR->nLeaves;
816 assert( pCutR->nLeaves <= nOldSupp );
817 if ( pCutR->nLeaves < nOldSupp )
818 pCutR->Sign = Kf_SetCutGetSign( pCutR );
821 assert( pCutR->nLeaves > 1 );
822 pCutR->Delay = Abc_MaxInt(pCut0->Delay, pCut1->Delay);
823 pCutR->Area = pCut0->Area + pCut1->Area;
825 Kf_SetAddToList(
p, pCutR, 0 );
827 Kf_SetFilterOrder(
p );
829 p->CutCount[3] += Abc_MinInt(
p->nCuts,
p->nCutNum-1 );
830 Kf_SetSelectBest(
p, fArea, 1 );
845static inline int Kf_CutSize(
int * pCut ) {
return pCut[0]; }
846static inline int Kf_CutFunc(
int * pCut ) {
return pCut[pCut[0] + 1]; }
847static inline int Kf_CutLeaf(
int * pCut,
int i ) {
assert(i);
return Abc_Lit2Var(pCut[i]); }
848static inline int Kf_CutTime( Kf_Man_t *
p,
int * pCut )
851 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
852 Time = Abc_MaxInt( Time, Kf_ObjTime(
p, Kf_CutLeaf(pCut, i)) );
855static inline void Kf_CutRef( Kf_Man_t *
p,
int * pCut )
858 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
859 Gia_ObjRefIncId(
p->pGia, Kf_CutLeaf(pCut, i) );
861static inline void Kf_CutDeref( Kf_Man_t *
p,
int * pCut )
864 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
865 Gia_ObjRefDecId(
p->pGia, Kf_CutLeaf(pCut, i) );
867static inline void Kf_CutPrint(
int * pCut )
870 printf(
"%d {", Kf_CutSize(pCut) );
871 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
872 printf(
" %d", Kf_CutLeaf(pCut, i) );
873 printf(
" } Func = %d\n", Kf_CutFunc(pCut) );
875static inline void Gia_CutSetPrint(
int * pCuts )
878 Kf_ObjForEachCutInt( pCuts, pCut, i )
894int Kf_ManComputeDelay( Kf_Man_t *
p,
int fEval )
901 if ( Gia_ObjRefNum(
p->pGia, pObj) > 0 )
902 Vec_IntWriteEntry( &
p->vTime, i, Kf_CutTime(
p, Kf_ObjCutBest(
p, i)) );
906 assert( Gia_ObjRefNum(
p->pGia, pObj) > 0 );
907 Delay = Abc_MaxInt( Delay, Kf_ObjTime(
p, Gia_ObjId(
p->pGia, pObj)) );
911int Kf_ManComputeRefs( Kf_Man_t *
p )
914 float nRefsNew;
int i, * pCut;
915 float * pRefs = Vec_FltArray(&
p->vRefs);
916 float * pFlow = Vec_FltArray(&
p->vArea);
917 assert(
p->pGia->pRefs != NULL );
918 memset(
p->pGia->pRefs, 0,
sizeof(
int) * Gia_ManObjNum(
p->pGia) );
919 p->pPars->Area =
p->pPars->Edge = 0;
922 if ( Gia_ObjIsCo(pObj) || Gia_ObjIsBuf(pObj) )
923 Gia_ObjRefInc(
p->pGia, Gia_ObjFanin0(pObj) );
924 else if ( Gia_ObjIsAnd(pObj) && Gia_ObjRefNum(
p->pGia, pObj) > 0 )
926 pCut = Kf_ObjCutBest(
p, i);
927 Kf_CutRef(
p, pCut );
928 p->pPars->Edge += Kf_CutSize(pCut);
933 for ( i = 0; i < Gia_ManObjNum(
p->pGia); i++ )
935 if (
p->pPars->fOptEdge )
936 nRefsNew = Abc_MaxFloat( 1, 0.8 * pRefs[i] + 0.2 *
p->pGia->pRefs[i] );
938 nRefsNew = Abc_MaxFloat( 1, 0.2 * pRefs[i] + 0.8 *
p->pGia->pRefs[i] );
939 pFlow[i] = pFlow[i] * pRefs[i] / nRefsNew;
944 p->pPars->Delay = Kf_ManComputeDelay(
p, 1 );
945 return p->pPars->Area;
959#define PAR_THR_MAX 100
960typedef struct Kf_ThData_t_
967void * Kf_WorkerThread(
void * pArg )
969 Kf_ThData_t * pThData = (Kf_ThData_t *)pArg;
970 Kf_Man_t * pMan = pThData->pSett->pMan;
971 int fAreaOnly = pThData->pSett->pMan->pPars->fAreaOnly;
972 int fCutMin = pThData->pSett->pMan->pPars->fCutMin;
973 volatile int * pPlace = &pThData->Status;
977 while ( *pPlace == 0 );
978 assert( pThData->Status == 1 );
979 if ( pThData->Id == -1 )
981 pthread_exit( NULL );
985 assert( pThData->Id >= 0 );
987 Kf_SetMergeOrder( pThData->pSett, Kf_ObjCuts0(pMan, pThData->Id), Kf_ObjCuts1(pMan, pThData->Id), fAreaOnly, fCutMin );
988 pThData->clkUsed += Abc_Clock() - clk;
999 vCounts = Vec_IntAlloc( Gia_ManObjNum(
p) );
1002 if ( Gia_ObjIsAnd(pObj) )
1003 Vec_IntPush( vCounts, 2 - Gia_ObjIsCi(Gia_ObjFanin0(pObj)) - Gia_ObjIsCi(Gia_ObjFanin1(pObj)) );
1005 Vec_IntPush( vCounts, 0 );
1007 assert( Vec_IntSize(vCounts) == Gia_ManObjNum(
p) );
1010void Kf_ManComputeCuts( Kf_Man_t *
p )
1016 int nProcs =
p->pPars->nProcNum;
1017 int i, k, iFan, status, nCountFanins, fRunning;
1021 vFanins = Kf_ManCreateFaninCounts(
p->pGia );
1024 vStack = Vec_IntAlloc( 1000 );
1026 if ( Gia_ObjIsAnd(pObj) && Vec_IntEntry(vFanins, k) == 0 )
1027 Vec_IntPush( vStack, k );
1029 for ( i = 0; i < nProcs; i++ )
1031 ThData[i].pSett =
p->pSett + i;
1033 ThData[i].Status = 0;
1034 ThData[i].clkUsed = 0;
1035 status = pthread_create( WorkerThread + i, NULL, Kf_WorkerThread, (
void *)(ThData + i) );
assert( status == 0 );
1037 nCountFanins = Vec_IntSum(vFanins);
1039 while ( nCountFanins > 0 || Vec_IntSize(vStack) > 0 || fRunning )
1041 for ( i = 0; i < nProcs; i++ )
1043 if ( ThData[i].Status )
1045 assert( ThData[i].Status == 0 );
1046 if ( ThData[i].Id >= 0 )
1048 int iObj = ThData[i].Id;
1049 Kf_Set_t * pSett =
p->pSett + i;
1053 Kf_ManSaveResults( pSett->ppCuts, pSett->nCuts, pSett->pCutBest,
p->vTemp );
1054 Vec_IntWriteEntry( &
p->vTime, iObj, pSett->pCutBest->Delay + 1 );
1055 Vec_FltWriteEntry( &
p->vArea, iObj, (pSett->pCutBest->Area + 1)/Kf_ObjRefs(
p, iObj) );
1056 if ( pSett->pCutBest->nLeaves > 1 )
1057 Kf_ManStoreAddUnit(
p->vTemp, iObj, Kf_ObjTime(
p, iObj), Kf_ObjArea(
p, iObj) );
1058 Kf_ObjSetCuts(
p, iObj,
p->vTemp );
1060 clkUsed += Abc_Clock() - clk;
1064 if ( !Gia_ObjIsAnd(Gia_ManObj(
p->pGia, iFan)) )
1066 assert( Vec_IntEntry(vFanins, iFan) > 0 );
1067 if ( Vec_IntAddToEntry(vFanins, iFan, -1) == 0 )
1068 Vec_IntPush( vStack, iFan );
1069 assert( nCountFanins > 0 );
1074 if ( Vec_IntSize(vStack) > 0 )
1076 ThData[i].Id = Vec_IntPop( vStack );
1077 ThData[i].Status = 1;
1082 for ( i = 0; i < nProcs; i++ )
1083 if ( ThData[i].Status == 1 || (ThData[i].Status == 0 && ThData[i].Id >= 0) )
1090 printf(
"%d -> %d ", k, iFan );
1093 assert( Vec_IntSum(vFanins) == 0 );
1095 for ( i = 0; i < nProcs; i++ )
1097 assert( ThData[i].Status == 0 );
1099 ThData[i].Status = 1;
1102 Vec_IntFree( vStack );
1103 Vec_IntFree( vFanins );
1104 if ( !
p->pPars->fVerbose )
1107 printf(
"Main : " );
1108 Abc_PrintTime( 1,
"Time", clkUsed );
1109 for ( i = 0; i < nProcs; i++ )
1111 printf(
"Thread %d : ", i );
1112 Abc_PrintTime( 1,
"Time", ThData[i].clkUsed );
1128void Kf_ManPrintStats( Kf_Man_t *
p,
char * pTitle )
1130 if ( !
p->pPars->fVerbose )
1132 printf(
"%s : ", pTitle );
1133 printf(
"Level =%6lu ", (
long)
p->pPars->Delay );
1134 printf(
"Area =%9lu ", (
long)
p->pPars->Area );
1135 printf(
"Edge =%9lu ", (
long)
p->pPars->Edge );
1136 Abc_PrintTime( 1,
"Time", Abc_Clock() -
p->clkStart );
1139void Kf_ManComputeMapping( Kf_Man_t *
p )
1142 if (
p->pPars->fVerbose )
1144 printf(
"Aig: CI = %d CO = %d AND = %d ", Gia_ManCiNum(
p->pGia), Gia_ManCoNum(
p->pGia), Gia_ManAndNum(
p->pGia) );
1145 printf(
"LutSize = %d CutMax = %d Threads = %d\n",
p->pPars->nLutSize,
p->pPars->nCutNum,
p->pPars->nProcNum );
1146 printf(
"Computing cuts...\r" );
1151 i = Gia_ObjId(
p->pGia, pObj);
1152 Kf_ManStoreStart(
p->vTemp, 0 );
1153 Kf_ManStoreAddUnit(
p->vTemp, i, 0, 0 );
1154 assert( Vec_IntSize(
p->vTemp) == 1 + KF_ADD_ON1 + KF_ADD_ON2 );
1155 Kf_ObjSetCuts(
p, i,
p->vTemp );
1157 if (
p->pPars->nProcNum > 0 )
1158 Kf_ManComputeCuts(
p );
1163 if (
p->pPars->fCutHashing )
1164 Kf_SetMerge(
p->pSett, Kf_ObjCuts0(
p, i), Kf_ObjCuts1(
p, i),
p->pPars->fAreaOnly,
p->pPars->fCutMin );
1165 else if (
p->pPars->fCutSimple )
1166 Kf_SetMergeSimple(
p->pSett, Kf_ObjCuts0(
p, i), Kf_ObjCuts1(
p, i),
p->pPars->fAreaOnly,
p->pPars->fCutMin );
1168 Kf_SetMergeOrder(
p->pSett, Kf_ObjCuts0(
p, i), Kf_ObjCuts1(
p, i),
p->pPars->fAreaOnly,
p->pPars->fCutMin );
1169 Kf_ManSaveResults(
p->pSett->ppCuts,
p->pSett->nCuts,
p->pSett->pCutBest,
p->vTemp );
1170 Vec_IntWriteEntry( &
p->vTime, i,
p->pSett->pCutBest->Delay + 1 );
1171 Vec_FltWriteEntry( &
p->vArea, i, (
p->pSett->pCutBest->Area + 1)/Kf_ObjRefs(
p, i) );
1172 if (
p->pSett->pCutBest->nLeaves > 1 )
1173 Kf_ManStoreAddUnit(
p->vTemp, i, Kf_ObjTime(
p, i), Kf_ObjArea(
p, i) );
1174 Kf_ObjSetCuts(
p, i,
p->vTemp );
1178 Kf_ManComputeRefs(
p );
1179 if (
p->pPars->fVerbose )
1181 printf(
"CutPair = %lu ", (
long)
p->pSett->CutCount[0] );
1182 printf(
"Merge = %lu ", (
long)
p->pSett->CutCount[1] );
1183 printf(
"Eval = %lu ", (
long)
p->pSett->CutCount[2] );
1184 printf(
"Cut = %lu ", (
long)
p->pSett->CutCount[3] );
1185 Abc_PrintTime( 1,
"Time", Abc_Clock() -
p->clkStart );
1186 printf(
"Memory: " );
1188 printf(
"Man = %.2f MB ", 4.0 *
sizeof(
int) * Gia_ManObjNum(
p->pGia) / (1<<20) );
1189 printf(
"Cuts = %.2f MB ",Vec_ReportMemory(&
p->pMem) / (1<<20) );
1190 printf(
"Set = %.2f KB ", 1.0 *
sizeof(Kf_Set_t) / (1<<10) );
1193 Kf_ManPrintStats(
p,
"Start" );
1210 Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
int i;
1211 Vec_FltFill( vRefs, Gia_ManObjNum(
p), 0 );
1214 Vec_FltAddToEntry( vRefs, Gia_ObjFaninId0(pObj, i), 1 );
1215 Vec_FltAddToEntry( vRefs, Gia_ObjFaninId1(pObj, i), 1 );
1220 Vec_FltAddToEntry( vRefs, Gia_ObjId(
p, Gia_Regular(pCtrl)), -1 );
1221 if ( Gia_Regular(pData0) == Gia_Regular(pData1) )
1222 Vec_FltAddToEntry( vRefs, Gia_ObjId(
p, Gia_Regular(pData0)), -1 );
1225 Vec_FltAddToEntry( vRefs, Gia_ObjFaninId0(pObj, Gia_ObjId(
p, pObj)), 1 );
1226 for ( i = 0; i < Gia_ManObjNum(
p); i++ )
1227 Vec_FltUpdateEntry( vRefs, i, 1 );
1231 Kf_Man_t *
p;
int i;
1237 p->clkStart = Abc_Clock();
1240 Vec_SetAlloc_( &
p->pMem, 20 );
1241 Vec_IntFill( &
p->vCuts, Gia_ManObjNum(pGia), 0 );
1242 Vec_IntFill( &
p->vTime, Gia_ManObjNum(pGia), 0 );
1243 Vec_FltFill( &
p->vArea, Gia_ManObjNum(pGia), 0 );
1244 Kf_ManSetInitRefs( pGia, &
p->vRefs );
1245 p->vTemp = Vec_IntAlloc( 1000 );
1248 for ( i = 0; i < Abc_MaxInt(1, pPars->
nProcNum); i++ )
1250 (
p->pSett + i)->pMan =
p;
1251 (
p->pSett + i)->nLutSize = (
unsigned short)pPars->
nLutSize;
1252 (
p->pSett + i)->nCutNum = (
unsigned short)pPars->
nCutNum;
1253 (
p->pSett + i)->TableMask = (1 << KF_LOG_TABLE) - 1;
1257void Kf_ManFree( Kf_Man_t *
p )
1264 Vec_IntFreeP( &
p->vTemp );
1265 Vec_SetFree_( &
p->pMem );
1274 vMapping = Vec_IntAlloc( Gia_ManObjNum(
p->pGia) + (
int)
p->pPars->Edge + (
int)
p->pPars->Area * 2 );
1275 Vec_IntFill( vMapping, Gia_ManObjNum(
p->pGia), 0 );
1278 if ( Gia_ObjIsBuf(pObj) || Gia_ObjRefNum(
p->pGia, pObj) == 0 )
1280 pCut = Kf_ObjCutBest(
p, i );
1281 Vec_IntWriteEntry( vMapping, i, Vec_IntSize(vMapping) );
1282 Vec_IntPush( vMapping, Kf_CutSize(pCut) );
1283 for ( k = 1; k <= Kf_CutSize(pCut); k++ )
1284 Vec_IntPush( vMapping, Kf_CutLeaf(pCut, k) );
1285 Vec_IntPush( vMapping, i );
1287 assert( Vec_IntCap(vMapping) == 16 || Vec_IntSize(vMapping) == Vec_IntCap(vMapping) );
1288 p->pGia->vMapping = vMapping;
1332 p = Kf_ManAlloc( pGia, pPars );
1333 Kf_ManComputeMapping(
p );
1334 pNew = Kf_ManDerive(
p );
#define ABC_SWAP(Type, a, b)
#define ABC_CALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
#define PAR_THR_MAX
DECLARATIONS ///.
ABC_NAMESPACE_IMPL_START void Kf_ManSetDefaultPars(Jf_Par_t *pPars)
DECLARATIONS ///.
Gia_Man_t * Kf_ManPerformMapping(Gia_Man_t *pGia, Jf_Par_t *pPars)
void Gia_ManStaticFanoutStart(Gia_Man_t *p)
void Gia_ManStaticFanoutStop(Gia_Man_t *p)
double Gia_ManMemory(Gia_Man_t *p)
Gia_Obj_t * Gia_ObjRecognizeMux(Gia_Obj_t *pNode, Gia_Obj_t **ppNodeT, Gia_Obj_t **ppNodeE)
#define Gia_ManForEachAnd(p, pObj, i)
#define Gia_ManForEachObjReverse(p, pObj, i)
struct Gia_Obj_t_ Gia_Obj_t
int Gia_ObjIsMuxType(Gia_Obj_t *pNode)
void Gia_ObjPrint(Gia_Man_t *p, Gia_Obj_t *pObj)
struct Gia_Man_t_ Gia_Man_t
struct Jf_Par_t_ Jf_Par_t
#define Gia_ObjForEachFanoutStaticId(p, Id, FanId, i)
#define Gia_ManForEachObj(p, pObj, i)
MACRO DEFINITIONS ///.
#define Gia_ManForEachCo(p, pObj, i)
#define Gia_ManForEachCi(p, pObj, i)
#define Gia_ManForEachCoDriver(p, pObj, i)
unsigned __int64 word
DECLARATIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Set_t_ Vec_Set_t
INCLUDES ///.