abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
giaKf.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [giaKf.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Scalable AIG package.]
8 
9  Synopsis [Cut computation.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: giaKf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "gia.h"
22 #include "misc/vec/vecSet.h"
23 
24 #ifdef ABC_USE_PTHREADS
25 
26 #ifdef _WIN32
27 #include "../lib/pthread.h"
28 #else
29 #include <pthread.h>
30 #include <unistd.h>
31 #endif
32 
33 #endif
34 
36 
37 ////////////////////////////////////////////////////////////////////////
38 /// DECLARATIONS ///
39 ////////////////////////////////////////////////////////////////////////
40 
41 #ifndef ABC_USE_PTHREADS
42 
43 void Kf_ManSetDefaultPars( Jf_Par_t * pPars ) {}
44 Gia_Man_t * Kf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) { return NULL; }
45 
46 #else // pthreads are used
47 
48 #define KF_LEAF_MAX 16
49 #define KF_CUT_MAX 32
50 #define KF_PROC_MAX 32
51 #define KF_WORD_MAX ((KF_LEAF_MAX > 6) ? 1 << (KF_LEAF_MAX-6) : 1)
52 #define KF_LOG_TABLE 8
53 
54 #define KF_ADD_ON1 2 // offset in cut storage for each node (cut count; best cut)
55 #define KF_ADD_ON2 4 // offset in cut storage for each cut (leaf count; function, cut delay; cut area)
56 
57 typedef struct Kf_Cut_t_ Kf_Cut_t;
58 typedef struct Kf_Set_t_ Kf_Set_t;
59 typedef struct Kf_Man_t_ Kf_Man_t;
60 
61 struct Kf_Cut_t_
62 {
63  word Sign; // signature
64  int Polar; // polarity
65  int Delay; // delay
66  float Area; // area
67  int iFunc; // function
68  int iNext; // next cut
69  int nLeaves; // number of leaves
70  int pLeaves[KF_LEAF_MAX];
71 };
72 struct Kf_Set_t_
73 {
74  Kf_Man_t * pMan; // manager
75  unsigned short nLutSize; // lut size
76  unsigned short nCutNum; // cut count
77  int nCuts0; // fanin0 cut count
78  int nCuts1; // fanin1 cut count
79  int nCuts; // resulting cut count
80  int nTEntries; // hash table entries
81  int TableMask; // hash table mask
82  int pTable[1 << KF_LOG_TABLE];
83  int pValue[1 << KF_LOG_TABLE];
84  int pPlace[KF_LEAF_MAX];
85  int pList [KF_LEAF_MAX+1];
86  Kf_Cut_t pCuts0[KF_CUT_MAX];
87  Kf_Cut_t pCuts1[KF_CUT_MAX];
88  Kf_Cut_t pCutsR[KF_CUT_MAX*KF_CUT_MAX];
89  Kf_Cut_t * ppCuts[KF_CUT_MAX];
90  Kf_Cut_t * pCutBest;
91  word CutCount[4]; // statistics
92 };
93 struct Kf_Man_t_
94 {
95  Gia_Man_t * pGia; // user's manager
96  Jf_Par_t * pPars; // user's parameters
97  Vec_Set_t pMem; // cut storage
98  Vec_Int_t vCuts; // node params
99  Vec_Int_t vTime; // node params
100  Vec_Flt_t vArea; // node params
101  Vec_Flt_t vRefs; // node params
102  Vec_Int_t * vTemp; // temporary
103  abctime clkStart; // starting time
104  Kf_Set_t pSett[KF_PROC_MAX];
105 };
106 
107 static inline int Kf_SetCutId( Kf_Set_t * p, Kf_Cut_t * pCut ) { return pCut - p->pCutsR; }
108 static inline Kf_Cut_t * Kf_SetCut( Kf_Set_t * p, int i ) { return i >= 0 ? p->pCutsR + i : NULL; }
109 
110 static inline int Kf_ObjTime( Kf_Man_t * p, int i ) { return Vec_IntEntry(&p->vTime, i); }
111 static inline float Kf_ObjArea( Kf_Man_t * p, int i ) { return Vec_FltEntry(&p->vArea, i); }
112 static inline float Kf_ObjRefs( Kf_Man_t * p, int i ) { return Vec_FltEntry(&p->vRefs, i); }
113 
114 static 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))); }
115 static inline int * Kf_ObjCuts( Kf_Man_t * p, int i ) { return (int *)Vec_SetEntry(&p->pMem, Vec_IntEntry(&p->vCuts, i)); }
116 static inline int * Kf_ObjCuts0( Kf_Man_t * p, int i ) { return Kf_ObjCuts(p, Gia_ObjFaninId0(Gia_ManObj(p->pGia, i), i)); }
117 static inline int * Kf_ObjCuts1( Kf_Man_t * p, int i ) { return Kf_ObjCuts(p, Gia_ObjFaninId1(Gia_ManObj(p->pGia, i), i)); }
118 static inline int * Kf_ObjCutBest( Kf_Man_t * p, int i ) { int * pCuts = Kf_ObjCuts(p, i); return pCuts + pCuts[1]; }
119 
120 #define Kf_ObjForEachCutInt( pList, pCut, i ) for ( i = 0, pCut = pList + KF_ADD_ON1; i < pList[0]; i++, pCut += pCut[0] + KF_ADD_ON2 )
121 #define Kf_ListForEachCut( p, iList, pCut ) for ( pCut = Kf_SetCut(p, p->pList[iList]); pCut; pCut = Kf_SetCut(p, pCut->iNext) )
122 #define Kf_ListForEachCutP( p, iList, pCut, pPlace ) for ( pPlace = p->pList+iList, pCut = Kf_SetCut(p, *pPlace); pCut; pCut = Kf_SetCut(p, *pPlace) )
123 
124 ////////////////////////////////////////////////////////////////////////
125 /// FUNCTION DEFINITIONS ///
126 ////////////////////////////////////////////////////////////////////////
127 
128 /**Function*************************************************************
129 
130  Synopsis []
131 
132  Description []
133 
134  SideEffects []
135 
136  SeeAlso []
137 
138 ***********************************************************************/
139 static inline int Kf_SetLoadCuts( Kf_Cut_t * pCuts, int * pIntCuts )
140 {
141  Kf_Cut_t * pCut;
142  int k, * pIntCut, nCuts = 0;
143  Kf_ObjForEachCutInt( pIntCuts, pIntCut, nCuts )
144  {
145  pCut = pCuts + nCuts;
146  pCut->Sign = 0;
147  pCut->Polar = 0;
148  pCut->iFunc = pIntCut[pIntCut[0] + 1];
149  pCut->Delay = pIntCut[pIntCut[0] + 2];
150  pCut->Area = Abc_Int2Float(pIntCut[pIntCut[0] + 3]);
151  pCut->nLeaves = pIntCut[0];
152  for ( k = 0; k < pIntCut[0]; k++ )
153  {
154  pCut->pLeaves[k] = Abc_Lit2Var(pIntCut[k+1]);
155  pCut->Sign |= ((word)1) << (pCut->pLeaves[k] & 0x3F);
156  if ( Abc_LitIsCompl(pIntCut[k+1]) )
157  pCut->Polar |= (1 << k);
158  }
159  }
160  return nCuts;
161 }
162 static inline void Kf_SetPrepare( Kf_Set_t * p, int * pCuts0, int * pCuts1 )
163 {
164  int i;
165  // prepare hash table
166 // for ( i = 0; i <= p->TableMask; i++ )
167 // assert( p->pTable[i] == 0 );
168  // prepare cut storage
169  for ( i = 0; i <= p->nLutSize; i++ )
170  p->pList[i] = -1;
171  // transfer cuts
172  p->nCuts0 = Kf_SetLoadCuts( p->pCuts0, pCuts0 );
173  p->nCuts1 = Kf_SetLoadCuts( p->pCuts1, pCuts1 );
174  p->nCuts = 0;
175 }
176 
177 /**Function*************************************************************
178 
179  Synopsis []
180 
181  Description []
182 
183  SideEffects []
184 
185  SeeAlso []
186 
187 ***********************************************************************/
188 static inline void Kf_ManStoreStart( Vec_Int_t * vTemp, int nCuts )
189 {
190  Vec_IntClear( vTemp );
191  Vec_IntPush( vTemp, nCuts ); // cut count
192  Vec_IntPush( vTemp, -1 ); // best offset
193 }
194 static inline void Kf_ManStoreAddUnit( Vec_Int_t * vTemp, int iObj, int Time, float Area )
195 {
196  Vec_IntAddToEntry( vTemp, 0, 1 );
197  Vec_IntPush( vTemp, 1 ); // cut size
198  Vec_IntPush( vTemp, Abc_Var2Lit(iObj, 0) ); // leaf
199  Vec_IntPush( vTemp, 2 ); // function
200  Vec_IntPush( vTemp, Time ); // delay
201  Vec_IntPush( vTemp, Abc_Float2Int(Area) ); // area
202 }
203 static inline void Kf_ManSaveResults( Kf_Cut_t ** ppCuts, int nCuts, Kf_Cut_t * pCutBest, Vec_Int_t * vTemp )
204 {
205  int i, k;
206  assert( nCuts > 0 && nCuts < KF_CUT_MAX );
207  Kf_ManStoreStart( vTemp, nCuts );
208  for ( i = 0; i < nCuts; i++ )
209  {
210  if ( ppCuts[i] == pCutBest )
211  Vec_IntWriteEntry( vTemp, 1, Vec_IntSize(vTemp) );
212  Vec_IntPush( vTemp, ppCuts[i]->nLeaves );
213 // Vec_IntPushArray( vTemp, ppCuts[i]->pLeaves, ppCuts[i]->nLeaves );
214  for ( k = 0; k < ppCuts[i]->nLeaves; k++ )
215  Vec_IntPush( vTemp, Abc_Var2Lit(ppCuts[i]->pLeaves[k], 0) );
216  Vec_IntPush( vTemp, ppCuts[i]->iFunc );
217  Vec_IntPush( vTemp, ppCuts[i]->Delay );
218  Vec_IntPush( vTemp, Abc_Float2Int(ppCuts[i]->Area) );
219  }
220  assert( Vec_IntEntry(vTemp, 1) > 0 );
221 }
222 static inline int Kf_SetCompareCuts( Kf_Cut_t * p1, Kf_Cut_t * p2 )
223 {
224  if ( p1 == NULL || p2 == NULL )
225  return (p1 != NULL) - (p2 != NULL);
226  if ( p1->nLeaves != p2->nLeaves )
227  return p1->nLeaves - p2->nLeaves;
228  return memcmp( p1->pLeaves, p2->pLeaves, sizeof(int)*p1->nLeaves );
229 }
230 static inline void Kf_SetAddToList( Kf_Set_t * p, Kf_Cut_t * pCut, int fSort )
231 {
232  if ( !fSort )
233  pCut->iNext = p->pList[pCut->nLeaves], p->pList[pCut->nLeaves] = Kf_SetCutId(p, pCut);
234  else
235  {
236  int Value, * pPlace;
237  Kf_Cut_t * pTemp;
238  Vec_IntSelectSort( pCut->pLeaves, pCut->nLeaves );
239  Kf_ListForEachCutP( p, pCut->nLeaves, pTemp, pPlace )
240  {
241  if ( (Value = Kf_SetCompareCuts(pTemp, pCut)) > 0 )
242  break;
243  assert( Value < 0 );
244  pPlace = &pTemp->iNext;
245  }
246  pCut->iNext = *pPlace, *pPlace = Kf_SetCutId(p, pCut);
247  }
248 }
249 static inline int Kf_CutCompare( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1, int fArea )
250 {
251  if ( fArea )
252  {
253  if ( pCut0->Area < pCut1->Area ) return -1;
254  if ( pCut0->Area > pCut1->Area ) return 1;
255  if ( pCut0->Delay < pCut1->Delay ) return -1;
256  if ( pCut0->Delay > pCut1->Delay ) return 1;
257  if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
258  if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
259  }
260  else
261  {
262  if ( pCut0->Delay < pCut1->Delay ) return -1;
263  if ( pCut0->Delay > pCut1->Delay ) return 1;
264  if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
265  if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
266  if ( pCut0->Area < pCut1->Area ) return -1;
267  if ( pCut0->Area > pCut1->Area ) return 1;
268  }
269  return 0;
270 }
271 static inline int Kf_SetStoreAddOne( Kf_Set_t * p, int nCuts, int nCutNum, Kf_Cut_t * pCut, int fArea )
272 {
273  int i;
274  p->ppCuts[nCuts] = pCut;
275  if ( nCuts == 0 )
276  return 1;
277  for ( i = nCuts; i > 0; i-- )
278  if ( Kf_CutCompare(p->ppCuts[i-1], p->ppCuts[i], fArea) > 0 )
279  ABC_SWAP( Kf_Cut_t *, p->ppCuts[i-1], p->ppCuts[i] )
280  else
281  break;
282  return Abc_MinInt( nCuts+1, nCutNum );
283 }
284 static inline void Kf_SetSelectBest( Kf_Set_t * p, int fArea, int fSort )
285 {
286 // int fArea = p->pMan->pPars->fArea;
287  Kf_Cut_t * pCut;
288  int i, nCuts = 0;
289  for ( i = 0; i <= p->nLutSize; i++ )
290  Kf_ListForEachCut( p, i, pCut )
291  nCuts = Kf_SetStoreAddOne( p, nCuts, p->nCutNum-1, pCut, fArea );
292  assert( nCuts > 0 && nCuts < p->nCutNum );
293  p->nCuts = nCuts;
294  p->pCutBest = p->ppCuts[0];
295  if ( !fSort )
296  return;
297  // sort by size in the reverse order
298  for ( i = 0; i <= p->nLutSize; i++ )
299  p->pList[i] = -1;
300  for ( i = 0; i < nCuts; i++ )
301  Kf_SetAddToList( p, p->ppCuts[i], 0 );
302  p->nCuts = 0;
303  for ( i = p->nLutSize; i >= 0; i-- )
304  Kf_ListForEachCut( p, i, pCut )
305  p->ppCuts[p->nCuts++] = pCut;
306  assert( p->nCuts == nCuts );
307 }
308 
309 /**Function*************************************************************
310 
311  Synopsis [Check correctness of cuts.]
312 
313  Description []
314 
315  SideEffects []
316 
317  SeeAlso []
318 
319 ***********************************************************************/
320 static inline int Kf_CheckCut( Kf_Cut_t * pBase, Kf_Cut_t * pCut ) // check if pCut is contained in pBase
321 {
322  int nSizeB = pBase->nLeaves;
323  int nSizeC = pCut->nLeaves;
324  int * pB = pBase->pLeaves;
325  int * pC = pCut->pLeaves;
326  int i, k;
327  for ( i = 0; i < nSizeC; i++ )
328  {
329  for ( k = 0; k < nSizeB; k++ )
330  if ( pC[i] == pB[k] )
331  break;
332  if ( k == nSizeB )
333  return 0;
334  }
335  return 1;
336 }
337 static inline int Kf_CheckCuts( Kf_Set_t * p )
338 {
339  Kf_Cut_t * pCut0, * pCut1;
340  int i, k, m, n, Value;
341  assert( p->nCuts > 0 );
342  for ( i = 0; i <= p->nLutSize; i++ )
343  Kf_ListForEachCut( p, i, pCut0 )
344  {
345  // check duplicates
346  for ( m = 0; m < pCut0->nLeaves; m++ )
347  for ( n = m+1; n < pCut0->nLeaves; n++ )
348  assert( pCut0->pLeaves[m] != pCut0->pLeaves[n] );
349  // check pairs
350  for ( k = 0; k <= p->nLutSize; k++ )
351  Kf_ListForEachCut( p, k, pCut1 )
352  {
353  if ( pCut0 == pCut1 )
354  continue;
355  // check containments
356  Value = Kf_CheckCut( pCut0, pCut1 );
357  assert( Value == 0 );
358  }
359  }
360  return 1;
361 }
362 
363 /**Function*************************************************************
364 
365  Synopsis [Hash table.]
366 
367  Description []
368 
369  SideEffects []
370 
371  SeeAlso []
372 
373 ***********************************************************************/
374 static inline int Kf_HashLookup( Kf_Set_t * p, int i )
375 {
376  int k;
377  assert( i > 0 );
378  for ( k = i & p->TableMask; p->pTable[k]; k = (k + 1) & p->TableMask )
379  if ( p->pTable[k] == i )
380  return -1;
381  return k;
382 }
383 static inline int Kf_HashFindOrAdd( Kf_Set_t * p, int i )
384 {
385  int k = Kf_HashLookup( p, i );
386  if ( k == -1 )
387  return 0;
388  if ( p->nTEntries == p->nLutSize )
389  return 1;
390  assert( p->pTable[k] == 0 );
391  p->pTable[k] = i;
392  p->pPlace[p->nTEntries] = k;
393  p->pValue[k] = p->nTEntries++;
394  return 0;
395 }
396 static inline void Kf_HashPopulate( Kf_Set_t * p, Kf_Cut_t * pCut )
397 {
398  int i;
399  assert( p->nTEntries == 0 );
400  for ( i = 0; i < pCut->nLeaves; i++ )
401  Kf_HashFindOrAdd( p, pCut->pLeaves[i] );
402  assert( p->nTEntries == pCut->nLeaves );
403 }
404 static inline void Kf_HashCleanup( Kf_Set_t * p, int iStart )
405 {
406  int i;
407  for ( i = iStart; i < p->nTEntries; i++ )
408  p->pTable[p->pPlace[i]] = 0;
409  p->nTEntries = iStart;
410 }
411 
412 /**Function*************************************************************
413 
414  Synopsis [Cut merging with arbitary order.]
415 
416  Description []
417 
418  SideEffects []
419 
420  SeeAlso []
421 
422 ***********************************************************************/
423 static inline int Kf_SetCountBits( word i )
424 {
425  i = i - ((i >> 1) & 0x5555555555555555);
426  i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
427  i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
428  return (i*(0x0101010101010101))>>56;
429 }
430 static inline word Kf_SetCutGetSign( Kf_Cut_t * p )
431 {
432  word Sign = 0; int i;
433  for ( i = 0; i < p->nLeaves; i++ )
434  Sign |= ((word)1) << (p->pLeaves[i] & 0x3F);
435  return Sign;
436 }
437 // returns 1 if the cut in hash table is dominated by the given one
438 static inline int Kf_SetCutDominatedByThis( Kf_Set_t * p, Kf_Cut_t * pCut )
439 {
440  int i;
441  for ( i = 0; i < pCut->nLeaves; i++ )
442  if ( Kf_HashLookup(p, pCut->pLeaves[i]) >= 0 )
443  return 0;
444  return 1;
445 }
446 static inline int Kf_SetRemoveDuplicates( Kf_Set_t * p, int nLeaves, word Sign )
447 {
448  Kf_Cut_t * pCut;
449  Kf_ListForEachCut( p, nLeaves, pCut )
450  if ( pCut->Sign == Sign && Kf_SetCutDominatedByThis(p, pCut) )
451  return 1;
452  return 0;
453 }
454 static inline void Kf_SetFilter( Kf_Set_t * p )
455 {
456  Kf_Cut_t * pCut0, * pCut1;
457  int i, k, * pPlace;
458  assert( p->nCuts > 0 );
459  for ( i = 0; i <= p->nLutSize; i++ )
460  Kf_ListForEachCutP( p, i, pCut0, pPlace )
461  {
462  Kf_HashPopulate( p, pCut0 );
463  for ( k = 0; k < pCut0->nLeaves; k++ )
464  Kf_ListForEachCut( p, k, pCut1 )
465  if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutDominatedByThis(p, pCut1) )
466  { k = pCut0->nLeaves; p->nCuts--; break; }
467  if ( k == pCut0->nLeaves + 1 ) // remove pCut0
468  *pPlace = pCut0->iNext;
469  else
470  pPlace = &pCut0->iNext;
471  Kf_HashCleanup( p, 0 );
472  }
473  assert( p->nCuts > 0 );
474 }
475 static inline void Kf_SetMergePairs( Kf_Set_t * p, Kf_Cut_t * pCut0, Kf_Cut_t * pCuts, int nCuts, int fArea )
476 {
477  Kf_Cut_t * pCut1, * pCutR; int i;
478  Kf_HashPopulate( p, pCut0 );
479  for ( pCut1 = pCuts; pCut1 < pCuts + nCuts; pCut1++ )
480  {
481  if ( pCut0->nLeaves + pCut1->nLeaves > p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) > p->nLutSize )
482  continue;
483  Kf_HashCleanup( p, pCut0->nLeaves );
484  for ( i = 0; i < pCut1->nLeaves; i++ )
485  if ( Kf_HashFindOrAdd(p, pCut1->pLeaves[i]) )
486  break;
487  if ( i < pCut1->nLeaves )
488  continue;
489  p->CutCount[1]++;
490  if ( Kf_SetRemoveDuplicates(p, p->nTEntries, pCut0->Sign | pCut1->Sign) )
491  continue;
492  // create new cut
493  pCutR = p->pCutsR + p->nCuts++;
494  pCutR->nLeaves = p->nTEntries;
495  for ( i = 0; i < p->nTEntries; i++ )
496  pCutR->pLeaves[i] = p->pTable[p->pPlace[i]];
497  pCutR->Sign = pCut0->Sign | pCut1->Sign;
498  pCutR->Delay = Abc_MaxInt(pCut0->Delay, pCut1->Delay);
499  pCutR->Area = pCut0->Area + pCut1->Area;
500  // add new cut
501  Kf_SetAddToList( p, pCutR, 0 );
502  }
503  Kf_HashCleanup( p, 0 );
504 }
505 static inline void Kf_SetMerge( Kf_Set_t * p, int * pCuts0, int * pCuts1, int fArea, int fCutMin )
506 {
507  int c0, c1;
508  Kf_SetPrepare( p, pCuts0, pCuts1 );
509  p->CutCount[0] += p->nCuts0 * p->nCuts1;
510 // for ( c0 = 1; c0 < p->nCuts0; c0++ )
511 // assert( p->pCuts0[c0-1].nLeaves >= p->pCuts0[c0].nLeaves );
512  for ( c0 = c1 = 0; c0 < p->nCuts0 && c1 < p->nCuts1; )
513  {
514  if ( p->pCuts0[c0].nLeaves >= p->pCuts1[c1].nLeaves )
515  Kf_SetMergePairs( p, p->pCuts0 + c0++, p->pCuts1 + c1, p->nCuts1 - c1, fArea );
516  else
517  Kf_SetMergePairs( p, p->pCuts1 + c1++, p->pCuts0 + c0, p->nCuts0 - c0, fArea );
518  }
519  p->CutCount[2] += p->nCuts;
520  Kf_SetFilter( p );
521 // Kf_CheckCuts( p );
522  p->CutCount[3] += Abc_MinInt( p->nCuts, p->nCutNum-1 );
523  Kf_SetSelectBest( p, fArea, 1 );
524 }
525 
526 /**Function*************************************************************
527 
528  Synopsis [Cut merging with fixed order.]
529 
530  Description []
531 
532  SideEffects []
533 
534  SeeAlso []
535 
536 ***********************************************************************/
537 static inline int Kf_SetCutIsContainedSimple( Kf_Cut_t * pBase, Kf_Cut_t * pCut ) // check if pCut is contained in pBase
538 {
539  int nSizeB = pBase->nLeaves;
540  int nSizeC = pCut->nLeaves;
541  int * pB = pBase->pLeaves;
542  int * pC = pCut->pLeaves;
543  int i, k;
544  assert( nSizeB >= nSizeC );
545  for ( i = 0; i < nSizeC; i++ )
546  {
547  for ( k = 0; k < nSizeB; k++ )
548  if ( pC[i] == pB[k] )
549  break;
550  if ( k == nSizeB )
551  return 0;
552  }
553  return 1;
554 }
555 static inline int Kf_SetMergeSimpleOne( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1, Kf_Cut_t * pCut, int nLutSize )
556 {
557  int nSize0 = pCut0->nLeaves;
558  int nSize1 = pCut1->nLeaves;
559  int * pC0 = pCut0->pLeaves;
560  int * pC1 = pCut1->pLeaves;
561  int * pC = pCut->pLeaves;
562  int i, k, c;
563  // compare two cuts with different numbers
564  c = nSize0;
565  for ( i = 0; i < nSize1; i++ )
566  {
567  for ( k = 0; k < nSize0; k++ )
568  if ( pC1[i] == pC0[k] )
569  break;
570  if ( k < nSize0 )
571  continue;
572  if ( c == nLutSize )
573  return 0;
574  pC[c++] = pC1[i];
575  }
576  for ( i = 0; i < nSize0; i++ )
577  pC[i] = pC0[i];
578  pCut->nLeaves = c;
579  return 1;
580 }
581 static inline int Kf_SetRemoveDuplicatesSimple( Kf_Set_t * p, Kf_Cut_t * pCutNew )
582 {
583  Kf_Cut_t * pCut;
584  Kf_ListForEachCut( p, pCutNew->nLeaves, pCut )
585  if ( pCut->Sign == pCutNew->Sign && Kf_SetCutIsContainedSimple(pCut, pCutNew) )
586  return 1;
587  return 0;
588 }
589 static inline void Kf_SetFilterSimple( Kf_Set_t * p )
590 {
591  Kf_Cut_t * pCut0, * pCut1;
592  int i, k, * pPlace;
593  assert( p->nCuts > 0 );
594  for ( i = 0; i <= p->nLutSize; i++ )
595  Kf_ListForEachCutP( p, i, pCut0, pPlace )
596  {
597  for ( k = 0; k < pCut0->nLeaves; k++ )
598  Kf_ListForEachCut( p, k, pCut1 )
599  if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutIsContainedSimple(pCut0, pCut1) )
600  { k = pCut0->nLeaves; p->nCuts--; break; }
601  if ( k == pCut0->nLeaves + 1 ) // remove pCut0
602  *pPlace = pCut0->iNext;
603  else
604  pPlace = &pCut0->iNext;
605  }
606  assert( p->nCuts > 0 );
607 }
608 static inline void Kf_SetMergeSimple( Kf_Set_t * p, int * pCuts0, int * pCuts1, int fArea, int fCutMin )
609 {
610  Kf_Cut_t * pCut0, * pCut1, * pCutR;
611  Kf_SetPrepare( p, pCuts0, pCuts1 );
612  p->CutCount[0] += p->nCuts0 * p->nCuts1;
613  for ( pCut0 = p->pCuts0; pCut0 < p->pCuts0 + p->nCuts0; pCut0++ )
614  for ( pCut1 = p->pCuts1; pCut1 < p->pCuts1 + p->nCuts1; pCut1++ )
615  {
616  if ( pCut0->nLeaves + pCut1->nLeaves > p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) > p->nLutSize )
617  continue;
618  p->CutCount[1]++;
619  pCutR = p->pCutsR + p->nCuts;
620  if ( !Kf_SetMergeSimpleOne(pCut0, pCut1, pCutR, p->nLutSize) )
621  continue;
622  p->CutCount[2]++;
623  pCutR->Sign = pCut0->Sign | pCut1->Sign;
624  if ( Kf_SetRemoveDuplicatesSimple(p, pCutR) )
625  continue;
626  p->nCuts++;
627  if ( fCutMin )
628  {
629  int nOldSupp = pCutR->nLeaves;
630 // pCutR->iFunc = Kf_SetComputeTruth( p, pCut0->iFunc, pCut1->iFunc, pCut0, pCut1, pCutR );
631  assert( pCutR->nLeaves <= nOldSupp );
632  if ( pCutR->nLeaves < nOldSupp )
633  pCutR->Sign = Kf_SetCutGetSign( pCutR );
634  // delay and area are inaccurate
635  }
636  assert( pCutR->nLeaves > 1 );
637  pCutR->Delay = Abc_MaxInt(pCut0->Delay, pCut1->Delay);
638  pCutR->Area = pCut0->Area + pCut1->Area;
639  // add new cut
640  Kf_SetAddToList( p, pCutR, 0 );
641  }
642  Kf_SetFilterSimple( p );
643 // Kf_CheckCuts( p );
644  p->CutCount[3] += Abc_MinInt( p->nCuts, p->nCutNum-1 );
645  Kf_SetSelectBest( p, fArea, 1 );
646 }
647 
648 /**Function*************************************************************
649 
650  Synopsis [Cut merging with fixed order.]
651 
652  Description []
653 
654  SideEffects []
655 
656  SeeAlso []
657 
658 ***********************************************************************/
659 static inline int Kf_SetCutIsContainedOrder( Kf_Cut_t * pBase, Kf_Cut_t * pCut ) // check if pCut is contained in pBase
660 {
661  int nSizeB = pBase->nLeaves;
662  int nSizeC = pCut->nLeaves;
663  int i, k;
664  if ( nSizeB == nSizeC )
665  {
666  for ( i = 0; i < nSizeB; i++ )
667  if ( pBase->pLeaves[i] != pCut->pLeaves[i] )
668  return 0;
669  return 1;
670  }
671  assert( nSizeB > nSizeC );
672  for ( i = k = 0; i < nSizeB; i++ )
673  {
674  if ( pBase->pLeaves[i] > pCut->pLeaves[k] )
675  return 0;
676  if ( pBase->pLeaves[i] == pCut->pLeaves[k] )
677  {
678  if ( ++k == nSizeC )
679  return 1;
680  }
681  }
682  return 0;
683 }
684 static inline int Kf_SetMergeOrderOne( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1, Kf_Cut_t * pCut, int nLutSize )
685 {
686  int nSize0 = pCut0->nLeaves;
687  int nSize1 = pCut1->nLeaves;
688  int * pC0 = pCut0->pLeaves;
689  int * pC1 = pCut1->pLeaves;
690  int * pC = pCut->pLeaves;
691  int i, k, c;
692  // the case of the largest cut sizes
693  if ( nSize0 == nLutSize && nSize1 == nLutSize )
694  {
695  for ( i = 0; i < nSize0; i++ )
696  {
697  if ( pC0[i] != pC1[i] ) return 0;
698  pC[i] = pC0[i];
699  }
700  pCut->nLeaves = nLutSize;
701  return 1;
702  }
703  // compare two cuts with different numbers
704  i = k = c = 0;
705  while ( 1 )
706  {
707  if ( c == nLutSize ) return 0;
708  if ( pC0[i] < pC1[k] )
709  {
710  pC[c++] = pC0[i++];
711  if ( i >= nSize0 ) goto FlushCut1;
712  }
713  else if ( pC0[i] > pC1[k] )
714  {
715  pC[c++] = pC1[k++];
716  if ( k >= nSize1 ) goto FlushCut0;
717  }
718  else
719  {
720  pC[c++] = pC0[i++]; k++;
721  if ( i >= nSize0 ) goto FlushCut1;
722  if ( k >= nSize1 ) goto FlushCut0;
723  }
724  }
725 
726 FlushCut0:
727  if ( c + nSize0 > nLutSize + i ) return 0;
728  while ( i < nSize0 )
729  pC[c++] = pC0[i++];
730  pCut->nLeaves = c;
731  return 1;
732 
733 FlushCut1:
734  if ( c + nSize1 > nLutSize + k ) return 0;
735  while ( k < nSize1 )
736  pC[c++] = pC1[k++];
737  pCut->nLeaves = c;
738  return 1;
739 }
740 static inline int Kf_SetRemoveDuplicatesOrder( Kf_Set_t * p, Kf_Cut_t * pCutNew )
741 {
742  Kf_Cut_t * pCut;
743  Kf_ListForEachCut( p, pCutNew->nLeaves, pCut )
744  if ( pCut->Sign == pCutNew->Sign && Kf_SetCutIsContainedOrder(pCut, pCutNew) )
745  return 1;
746  return 0;
747 }
748 static inline void Kf_SetFilterOrder( Kf_Set_t * p )
749 {
750  Kf_Cut_t * pCut0, * pCut1;
751  int i, k, * pPlace;
752  assert( p->nCuts > 0 );
753  for ( i = 0; i <= p->nLutSize; i++ )
754  Kf_ListForEachCutP( p, i, pCut0, pPlace )
755  {
756  for ( k = 0; k < pCut0->nLeaves; k++ )
757  Kf_ListForEachCut( p, k, pCut1 )
758  if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutIsContainedOrder(pCut0, pCut1) )
759  { k = pCut0->nLeaves; p->nCuts--; break; }
760  if ( k == pCut0->nLeaves + 1 ) // remove pCut0
761  *pPlace = pCut0->iNext;
762  else
763  pPlace = &pCut0->iNext;
764  }
765  assert( p->nCuts > 0 );
766 }
767 /*
768 int Kf_SetComputeTruth( Kf_Man_t * p, int iFuncLit0, int iFuncLit1, int * pCut0, int * pCut1, int * pCutOut )
769 {
770  word uTruth[JF_WORD_MAX], uTruth0[JF_WORD_MAX], uTruth1[JF_WORD_MAX];
771  int fCompl, truthId;
772  int LutSize = p->pPars->nLutSize;
773  int nWords = Abc_Truth6WordNum(p->pPars->nLutSize);
774  word * pTruth0 = Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(iFuncLit0));
775  word * pTruth1 = Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(iFuncLit1));
776  Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(iFuncLit0) );
777  Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(iFuncLit1) );
778  Abc_TtExpand( uTruth0, LutSize, pCut0 + 1, Kf_CutSize(pCut0), pCutOut + 1, Kf_CutSize(pCutOut) );
779  Abc_TtExpand( uTruth1, LutSize, pCut1 + 1, Kf_CutSize(pCut1), pCutOut + 1, Kf_CutSize(pCutOut) );
780  fCompl = (int)(uTruth0[0] & uTruth1[0] & 1);
781  Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, fCompl );
782  pCutOut[0] = Abc_TtMinBase( uTruth, pCutOut + 1, pCutOut[0], LutSize );
783  assert( (uTruth[0] & 1) == 0 );
784  truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
785  return Abc_Var2Lit( truthId, fCompl );
786 }
787 */
788 static inline void Kf_SetMergeOrder( Kf_Set_t * p, int * pCuts0, int * pCuts1, int fArea, int fCutMin )
789 {
790  Kf_Cut_t * pCut0, * pCut1, * pCutR;
791  Kf_SetPrepare( p, pCuts0, pCuts1 );
792  p->CutCount[0] += p->nCuts0 * p->nCuts1;
793  for ( pCut0 = p->pCuts0; pCut0 < p->pCuts0 + p->nCuts0; pCut0++ )
794  for ( pCut1 = p->pCuts1; pCut1 < p->pCuts1 + p->nCuts1; pCut1++ )
795  {
796  if ( pCut0->nLeaves + pCut1->nLeaves > p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) > p->nLutSize )
797  continue;
798  p->CutCount[1]++;
799  pCutR = p->pCutsR + p->nCuts;
800  if ( !Kf_SetMergeOrderOne(pCut0, pCut1, pCutR, p->nLutSize) )
801  continue;
802  p->CutCount[2]++;
803  pCutR->Sign = pCut0->Sign | pCut1->Sign;
804  if ( Kf_SetRemoveDuplicatesOrder(p, pCutR) )
805  continue;
806  p->nCuts++;
807  if ( fCutMin )
808  {
809  int nOldSupp = pCutR->nLeaves;
810 // pCutR->iFunc = Kf_SetComputeTruth( p, pCut0->iFunc, pCut1->iFunc, pCut0, pCut1, pCutR );
811  assert( pCutR->nLeaves <= nOldSupp );
812  if ( pCutR->nLeaves < nOldSupp )
813  pCutR->Sign = Kf_SetCutGetSign( pCutR );
814  // delay and area are inaccurate
815  }
816  assert( pCutR->nLeaves > 1 );
817  pCutR->Delay = Abc_MaxInt(pCut0->Delay, pCut1->Delay);
818  pCutR->Area = pCut0->Area + pCut1->Area;
819  // add new cut
820  Kf_SetAddToList( p, pCutR, 0 );
821  }
822  Kf_SetFilterOrder( p );
823 // Kf_CheckCuts( p );
824  p->CutCount[3] += Abc_MinInt( p->nCuts, p->nCutNum-1 );
825  Kf_SetSelectBest( p, fArea, 1 );
826 }
827 
828 
829 /**Function*************************************************************
830 
831  Synopsis [Cut operations.]
832 
833  Description []
834 
835  SideEffects []
836 
837  SeeAlso []
838 
839 ***********************************************************************/
840 static inline int Kf_CutSize( int * pCut ) { return pCut[0]; }
841 static inline int Kf_CutFunc( int * pCut ) { return pCut[pCut[0] + 1]; }
842 static inline int Kf_CutLeaf( int * pCut, int i ) { assert(i); return Abc_Lit2Var(pCut[i]); }
843 static inline int Kf_CutTime( Kf_Man_t * p, int * pCut )
844 {
845  int i, Time = 0;
846  for ( i = 1; i <= Kf_CutSize(pCut); i++ )
847  Time = Abc_MaxInt( Time, Kf_ObjTime(p, Kf_CutLeaf(pCut, i)) );
848  return Time + 1;
849 }
850 static inline void Kf_CutRef( Kf_Man_t * p, int * pCut )
851 {
852  int i;
853  for ( i = 1; i <= Kf_CutSize(pCut); i++ )
854  Gia_ObjRefIncId( p->pGia, Kf_CutLeaf(pCut, i) );
855 }
856 static inline void Kf_CutDeref( Kf_Man_t * p, int * pCut )
857 {
858  int i;
859  for ( i = 1; i <= Kf_CutSize(pCut); i++ )
860  Gia_ObjRefDecId( p->pGia, Kf_CutLeaf(pCut, i) );
861 }
862 static inline void Kf_CutPrint( int * pCut )
863 {
864  int i;
865  printf( "%d {", Kf_CutSize(pCut) );
866  for ( i = 1; i <= Kf_CutSize(pCut); i++ )
867  printf( " %d", Kf_CutLeaf(pCut, i) );
868  printf( " } Func = %d\n", Kf_CutFunc(pCut) );
869 }
870 static inline void Gia_CutSetPrint( int * pCuts )
871 {
872  int i, * pCut;
873  Kf_ObjForEachCutInt( pCuts, pCut, i )
874  Kf_CutPrint( pCut );
875  printf( "\n" );
876 }
877 
878 /**Function*************************************************************
879 
880  Synopsis [Computing delay/area.]
881 
882  Description []
883 
884  SideEffects []
885 
886  SeeAlso []
887 
888 ***********************************************************************/
889 int Kf_ManComputeDelay( Kf_Man_t * p, int fEval )
890 {
891  Gia_Obj_t * pObj;
892  int i, Delay = 0;
893  if ( fEval )
894  {
895  Gia_ManForEachAnd( p->pGia, pObj, i )
896  if ( Gia_ObjRefNum(p->pGia, pObj) > 0 )
897  Vec_IntWriteEntry( &p->vTime, i, Kf_CutTime(p, Kf_ObjCutBest(p, i)) );
898  }
899  Gia_ManForEachCoDriver( p->pGia, pObj, i )
900  {
901  assert( Gia_ObjRefNum(p->pGia, pObj) > 0 );
902  Delay = Abc_MaxInt( Delay, Kf_ObjTime(p, Gia_ObjId(p->pGia, pObj)) );
903  }
904  return Delay;
905 }
906 int Kf_ManComputeRefs( Kf_Man_t * p )
907 {
908  Gia_Obj_t * pObj;
909  float nRefsNew; int i, * pCut;
910  float * pRefs = Vec_FltArray(&p->vRefs);
911  float * pFlow = Vec_FltArray(&p->vArea);
912  assert( p->pGia->pRefs != NULL );
913  memset( p->pGia->pRefs, 0, sizeof(int) * Gia_ManObjNum(p->pGia) );
914  p->pPars->Area = p->pPars->Edge = 0;
915  Gia_ManForEachObjReverse( p->pGia, pObj, i )
916  {
917  if ( Gia_ObjIsCo(pObj) || Gia_ObjIsBuf(pObj) )
918  Gia_ObjRefInc( p->pGia, Gia_ObjFanin0(pObj) );
919  else if ( Gia_ObjIsAnd(pObj) && Gia_ObjRefNum(p->pGia, pObj) > 0 )
920  {
921  pCut = Kf_ObjCutBest(p, i);
922  Kf_CutRef( p, pCut );
923  p->pPars->Edge += Kf_CutSize(pCut);
924  p->pPars->Area++;
925  }
926  }
927  // blend references and normalize flow
928  for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ )
929  {
930  if ( p->pPars->fOptEdge )
931  nRefsNew = Abc_MaxFloat( 1, 0.8 * pRefs[i] + 0.2 * p->pGia->pRefs[i] );
932  else
933  nRefsNew = Abc_MaxFloat( 1, 0.2 * pRefs[i] + 0.8 * p->pGia->pRefs[i] );
934  pFlow[i] = pFlow[i] * pRefs[i] / nRefsNew;
935  pRefs[i] = nRefsNew;
936  assert( pFlow[i] >= 0 );
937  }
938  // compute delay
939  p->pPars->Delay = Kf_ManComputeDelay( p, 1 );
940  return p->pPars->Area;
941 }
942 
943 /**Function*************************************************************
944 
945  Synopsis []
946 
947  Description []
948 
949  SideEffects []
950 
951  SeeAlso []
952 
953 ***********************************************************************/
954 #define PAR_THR_MAX 100
955 typedef struct Kf_ThData_t_
956 {
957  Kf_Set_t * pSett;
958  int Id;
959  int Status;
960  abctime clkUsed;
961 } Kf_ThData_t;
962 void * Kf_WorkerThread( void * pArg )
963 {
964  Kf_ThData_t * pThData = (Kf_ThData_t *)pArg;
965  Kf_Man_t * pMan = pThData->pSett->pMan;
966  int fAreaOnly = pThData->pSett->pMan->pPars->fAreaOnly;
967  int fCutMin = pThData->pSett->pMan->pPars->fCutMin;
968  volatile int * pPlace = &pThData->Status;
969  abctime clk;
970  while ( 1 )
971  {
972  while ( *pPlace == 0 );
973  assert( pThData->Status == 1 );
974  if ( pThData->Id == -1 )
975  {
976  pthread_exit( NULL );
977  assert( 0 );
978  return NULL;
979  }
980  assert( pThData->Id >= 0 );
981  clk = Abc_Clock();
982  Kf_SetMergeOrder( pThData->pSett, Kf_ObjCuts0(pMan, pThData->Id), Kf_ObjCuts1(pMan, pThData->Id), fAreaOnly, fCutMin );
983  pThData->clkUsed += Abc_Clock() - clk;
984  pThData->Status = 0;
985 // printf( "Finished object %d\n", pThData->Id );
986  }
987  assert( 0 );
988  return NULL;
989 }
990 Vec_Int_t * Kf_ManCreateFaninCounts( Gia_Man_t * p )
991 {
992  Vec_Int_t * vCounts;
993  Gia_Obj_t * pObj; int i;
994  vCounts = Vec_IntAlloc( Gia_ManObjNum(p) );
995  Gia_ManForEachObj( p, pObj, i )
996  {
997  if ( Gia_ObjIsAnd(pObj) )
998  Vec_IntPush( vCounts, 2 - Gia_ObjIsCi(Gia_ObjFanin0(pObj)) - Gia_ObjIsCi(Gia_ObjFanin1(pObj)) );
999  else
1000  Vec_IntPush( vCounts, 0 );
1001  }
1002  assert( Vec_IntSize(vCounts) == Gia_ManObjNum(p) );
1003  return vCounts;
1004 }
1005 void Kf_ManComputeCuts( Kf_Man_t * p )
1006 {
1007  pthread_t WorkerThread[PAR_THR_MAX];
1008  Kf_ThData_t ThData[PAR_THR_MAX];
1009  Vec_Int_t * vStack, * vFanins;
1010  Gia_Obj_t * pObj;
1011  int nProcs = p->pPars->nProcNum;
1012  int i, k, iFan, status, nCountFanins, fRunning;
1013  abctime clk, clkUsed = 0;
1014  assert( nProcs <= PAR_THR_MAX );
1015  // start fanins
1016  vFanins = Kf_ManCreateFaninCounts( p->pGia );
1017  Gia_ManStaticFanoutStart( p->pGia );
1018  // start the stack
1019  vStack = Vec_IntAlloc( 1000 );
1020  Gia_ManForEachObjReverse( p->pGia, pObj, k )
1021  if ( Gia_ObjIsAnd(pObj) && Vec_IntEntry(vFanins, k) == 0 )
1022  Vec_IntPush( vStack, k );
1023  // start the threads
1024  for ( i = 0; i < nProcs; i++ )
1025  {
1026  ThData[i].pSett = p->pSett + i;
1027  ThData[i].Id = -1;
1028  ThData[i].Status = 0;
1029  ThData[i].clkUsed = 0;
1030  status = pthread_create( WorkerThread + i, NULL, Kf_WorkerThread, (void *)(ThData + i) ); assert( status == 0 );
1031  }
1032  nCountFanins = Vec_IntSum(vFanins);
1033  fRunning = 1;
1034  while ( nCountFanins > 0 || Vec_IntSize(vStack) > 0 || fRunning )
1035  {
1036  for ( i = 0; i < nProcs; i++ )
1037  {
1038  if ( ThData[i].Status )
1039  continue;
1040  assert( ThData[i].Status == 0 );
1041  if ( ThData[i].Id >= 0 )
1042  {
1043  int iObj = ThData[i].Id;
1044  Kf_Set_t * pSett = p->pSett + i;
1045  //printf( "Closing obj %d with Thread %d:\n", iObj, i );
1046  clk = Abc_Clock();
1047  // finalize the results
1048  Kf_ManSaveResults( pSett->ppCuts, pSett->nCuts, pSett->pCutBest, p->vTemp );
1049  Vec_IntWriteEntry( &p->vTime, iObj, pSett->pCutBest->Delay + 1 );
1050  Vec_FltWriteEntry( &p->vArea, iObj, (pSett->pCutBest->Area + 1)/Kf_ObjRefs(p, iObj) );
1051  if ( pSett->pCutBest->nLeaves > 1 )
1052  Kf_ManStoreAddUnit( p->vTemp, iObj, Kf_ObjTime(p, iObj), Kf_ObjArea(p, iObj) );
1053  Kf_ObjSetCuts( p, iObj, p->vTemp );
1054  //Gia_CutSetPrint( Kf_ObjCuts(p, iObj) );
1055  clkUsed += Abc_Clock() - clk;
1056  // schedule other nodes
1057  Gia_ObjForEachFanoutStaticId( p->pGia, iObj, iFan, k )
1058  {
1059  if ( !Gia_ObjIsAnd(Gia_ManObj(p->pGia, iFan)) )
1060  continue;
1061  assert( Vec_IntEntry(vFanins, iFan) > 0 );
1062  if ( Vec_IntAddToEntry(vFanins, iFan, -1) == 0 )
1063  Vec_IntPush( vStack, iFan );
1064  assert( nCountFanins > 0 );
1065  nCountFanins--;
1066  }
1067  ThData[i].Id = -1;
1068  }
1069  if ( Vec_IntSize(vStack) > 0 )
1070  {
1071  ThData[i].Id = Vec_IntPop( vStack );
1072  ThData[i].Status = 1;
1073  //printf( "Scheduling %d for Thread %d\n", ThData[i].Id, i );
1074  }
1075  }
1076  fRunning = 0;
1077  for ( i = 0; i < nProcs; i++ )
1078  if ( ThData[i].Status == 1 || (ThData[i].Status == 0 && ThData[i].Id >= 0) )
1079  fRunning = 1;
1080 // printf( "fRunning %d\n", fRunning );
1081  }
1082  Vec_IntForEachEntry( vFanins, iFan, k )
1083  if ( iFan != 0 )
1084  {
1085  printf( "%d -> %d ", k, iFan );
1086  Gia_ObjPrint( p->pGia, Gia_ManObj(p->pGia, k) );
1087  }
1088  assert( Vec_IntSum(vFanins) == 0 );
1089  // stop the threads
1090  for ( i = 0; i < nProcs; i++ )
1091  {
1092  assert( ThData[i].Status == 0 );
1093  ThData[i].Id = -1;
1094  ThData[i].Status = 1;
1095  }
1096  Gia_ManStaticFanoutStop( p->pGia );
1097  Vec_IntFree( vStack );
1098  Vec_IntFree( vFanins );
1099  if ( !p->pPars->fVerbose )
1100  return;
1101  // print runtime statistics
1102  printf( "Main : " );
1103  Abc_PrintTime( 1, "Time", clkUsed );
1104  for ( i = 0; i < nProcs; i++ )
1105  {
1106  printf( "Thread %d : ", i );
1107  Abc_PrintTime( 1, "Time", ThData[i].clkUsed );
1108  }
1109 
1110 }
1111 
1112 /**Function*************************************************************
1113 
1114  Synopsis []
1115 
1116  Description []
1117 
1118  SideEffects []
1119 
1120  SeeAlso []
1121 
1122 ***********************************************************************/
1123 void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle )
1124 {
1125  if ( !p->pPars->fVerbose )
1126  return;
1127  printf( "%s : ", pTitle );
1128  printf( "Level =%6lu ", p->pPars->Delay );
1129  printf( "Area =%9lu ", p->pPars->Area );
1130  printf( "Edge =%9lu ", p->pPars->Edge );
1131  Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
1132  fflush( stdout );
1133 }
1134 void Kf_ManComputeMapping( Kf_Man_t * p )
1135 {
1136  Gia_Obj_t * pObj; int i, iPi;
1137  if ( p->pPars->fVerbose )
1138  {
1139  printf( "Aig: CI = %d CO = %d AND = %d ", Gia_ManCiNum(p->pGia), Gia_ManCoNum(p->pGia), Gia_ManAndNum(p->pGia) );
1140  printf( "LutSize = %d CutMax = %d Threads = %d\n", p->pPars->nLutSize, p->pPars->nCutNum, p->pPars->nProcNum );
1141  printf( "Computing cuts...\r" );
1142  fflush( stdout );
1143  }
1144  Gia_ManForEachCi( p->pGia, pObj, iPi )
1145  {
1146  i = Gia_ObjId(p->pGia, pObj);
1147  Kf_ManStoreStart( p->vTemp, 0 );
1148  Kf_ManStoreAddUnit( p->vTemp, i, 0, 0 );
1149  assert( Vec_IntSize(p->vTemp) == 1 + KF_ADD_ON1 + KF_ADD_ON2 );
1150  Kf_ObjSetCuts( p, i, p->vTemp );
1151  }
1152  if ( p->pPars->nProcNum > 0 )
1153  Kf_ManComputeCuts( p );
1154  else
1155  {
1156  Gia_ManForEachAnd( p->pGia, pObj, i )
1157  {
1158  if ( p->pPars->fCutHashing )
1159  Kf_SetMerge( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
1160  else if ( p->pPars->fCutSimple )
1161  Kf_SetMergeSimple( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
1162  else
1163  Kf_SetMergeOrder( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
1164  Kf_ManSaveResults( p->pSett->ppCuts, p->pSett->nCuts, p->pSett->pCutBest, p->vTemp );
1165  Vec_IntWriteEntry( &p->vTime, i, p->pSett->pCutBest->Delay + 1 );
1166  Vec_FltWriteEntry( &p->vArea, i, (p->pSett->pCutBest->Area + 1)/Kf_ObjRefs(p, i) );
1167  if ( p->pSett->pCutBest->nLeaves > 1 )
1168  Kf_ManStoreAddUnit( p->vTemp, i, Kf_ObjTime(p, i), Kf_ObjArea(p, i) );
1169  Kf_ObjSetCuts( p, i, p->vTemp );
1170  //Gia_CutSetPrint( Kf_ObjCuts(p, i) );
1171  }
1172  }
1173  Kf_ManComputeRefs( p );
1174  if ( p->pPars->fVerbose )
1175  {
1176  printf( "CutPair = %lu ", p->pSett->CutCount[0] );
1177  printf( "Merge = %lu ", p->pSett->CutCount[1] );
1178  printf( "Eval = %lu ", p->pSett->CutCount[2] );
1179  printf( "Cut = %lu ", p->pSett->CutCount[3] );
1180  Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
1181  printf( "Memory: " );
1182  printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) );
1183  printf( "Man = %.2f MB ", 4.0 * sizeof(int) * Gia_ManObjNum(p->pGia) / (1<<20) );
1184  printf( "Cuts = %.2f MB ",Vec_ReportMemory(&p->pMem) / (1<<20) );
1185  printf( "Set = %.2f KB ", 1.0 * sizeof(Kf_Set_t) / (1<<10) );
1186  printf( "\n" );
1187  fflush( stdout );
1188  Kf_ManPrintStats( p, "Start" );
1189  }
1190 }
1191 
1192 /**Function*************************************************************
1193 
1194  Synopsis []
1195 
1196  Description []
1197 
1198  SideEffects []
1199 
1200  SeeAlso []
1201 
1202 ***********************************************************************/
1203 void Kf_ManSetInitRefs( Gia_Man_t * p, Vec_Flt_t * vRefs )
1204 {
1205  Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1; int i;
1206  Vec_FltFill( vRefs, Gia_ManObjNum(p), 0 );
1207  Gia_ManForEachAnd( p, pObj, i )
1208  {
1209  Vec_FltAddToEntry( vRefs, Gia_ObjFaninId0(pObj, i), 1 );
1210  Vec_FltAddToEntry( vRefs, Gia_ObjFaninId1(pObj, i), 1 );
1211  if ( !Gia_ObjIsMuxType(pObj) )
1212  continue;
1213  // discount XOR/MUX
1214  pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 );
1215  Vec_FltAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pCtrl)), -1 );
1216  if ( Gia_Regular(pData0) == Gia_Regular(pData1) )
1217  Vec_FltAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pData0)), -1 );
1218  }
1219  Gia_ManForEachCo( p, pObj, i )
1220  Vec_FltAddToEntry( vRefs, Gia_ObjFaninId0(pObj, Gia_ObjId(p, pObj)), 1 );
1221  for ( i = 0; i < Gia_ManObjNum(p); i++ )
1222  Vec_FltUpdateEntry( vRefs, i, 1 );
1223 }
1224 Kf_Man_t * Kf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
1225 {
1226  Kf_Man_t * p; int i;
1227  assert( pPars->nLutSize <= KF_LEAF_MAX );
1228  assert( pPars->nCutNum <= KF_CUT_MAX );
1229  assert( pPars->nProcNum <= KF_PROC_MAX );
1230  Vec_IntFreeP( &pGia->vMapping );
1231  p = ABC_CALLOC( Kf_Man_t, 1 );
1232  p->clkStart = Abc_Clock();
1233  p->pGia = pGia;
1234  p->pPars = pPars;
1235  Vec_SetAlloc_( &p->pMem, 20 );
1236  Vec_IntFill( &p->vCuts, Gia_ManObjNum(pGia), 0 );
1237  Vec_IntFill( &p->vTime, Gia_ManObjNum(pGia), 0 );
1238  Vec_FltFill( &p->vArea, Gia_ManObjNum(pGia), 0 );
1239  Kf_ManSetInitRefs( pGia, &p->vRefs );
1240  p->vTemp = Vec_IntAlloc( 1000 );
1241  pGia->pRefs = ABC_CALLOC( int, Gia_ManObjNum(pGia) );
1242  // prepare cut sets
1243  for ( i = 0; i < Abc_MaxInt(1, pPars->nProcNum); i++ )
1244  {
1245  (p->pSett + i)->pMan = p;
1246  (p->pSett + i)->nLutSize = (unsigned short)pPars->nLutSize;
1247  (p->pSett + i)->nCutNum = (unsigned short)pPars->nCutNum;
1248  (p->pSett + i)->TableMask = (1 << KF_LOG_TABLE) - 1;
1249  }
1250  return p;
1251 }
1252 void Kf_ManFree( Kf_Man_t * p )
1253 {
1254  ABC_FREE( p->pGia->pRefs );
1255  ABC_FREE( p->vCuts.pArray );
1256  ABC_FREE( p->vTime.pArray );
1257  ABC_FREE( p->vArea.pArray );
1258  ABC_FREE( p->vRefs.pArray );
1259  Vec_IntFreeP( &p->vTemp );
1260  Vec_SetFree_( &p->pMem );
1261  ABC_FREE( p );
1262 }
1263 Gia_Man_t * Kf_ManDerive( Kf_Man_t * p )
1264 {
1265  Vec_Int_t * vMapping;
1266  Gia_Obj_t * pObj;
1267  int i, k, * pCut;
1268  assert( !p->pPars->fCutMin );
1269  vMapping = Vec_IntAlloc( Gia_ManObjNum(p->pGia) + (int)p->pPars->Edge + (int)p->pPars->Area * 2 );
1270  Vec_IntFill( vMapping, Gia_ManObjNum(p->pGia), 0 );
1271  Gia_ManForEachAnd( p->pGia, pObj, i )
1272  {
1273  if ( Gia_ObjIsBuf(pObj) || Gia_ObjRefNum(p->pGia, pObj) == 0 )
1274  continue;
1275  pCut = Kf_ObjCutBest( p, i );
1276  Vec_IntWriteEntry( vMapping, i, Vec_IntSize(vMapping) );
1277  Vec_IntPush( vMapping, Kf_CutSize(pCut) );
1278  for ( k = 1; k <= Kf_CutSize(pCut); k++ )
1279  Vec_IntPush( vMapping, Kf_CutLeaf(pCut, k) );
1280  Vec_IntPush( vMapping, i );
1281  }
1282  assert( Vec_IntCap(vMapping) == 16 || Vec_IntSize(vMapping) == Vec_IntCap(vMapping) );
1283  p->pGia->vMapping = vMapping;
1284 // Gia_ManMappingVerify( p->pGia );
1285  return p->pGia;
1286 }
1287 
1288 /**Function*************************************************************
1289 
1290  Synopsis []
1291 
1292  Description []
1293 
1294  SideEffects []
1295 
1296  SeeAlso []
1297 
1298 ***********************************************************************/
1299 void Kf_ManSetDefaultPars( Jf_Par_t * pPars )
1300 {
1301  memset( pPars, 0, sizeof(Jf_Par_t) );
1302  pPars->nLutSize = 6;
1303  pPars->nCutNum = 8;
1304  pPars->nProcNum = 0;
1305  pPars->nRounds = 1;
1306  pPars->nVerbLimit = 5;
1307  pPars->DelayTarget = -1;
1308  pPars->fAreaOnly = 0;
1309  pPars->fOptEdge = 1;
1310  pPars->fCoarsen = 0;
1311  pPars->fCutMin = 0;
1312  pPars->fFuncDsd = 0;
1313  pPars->fGenCnf = 0;
1314  pPars->fPureAig = 0;
1315  pPars->fCutHashing = 0;
1316  pPars->fCutSimple = 0;
1317  pPars->fVerbose = 0;
1318  pPars->fVeryVerbose = 0;
1319  pPars->nLutSizeMax = KF_LEAF_MAX;
1320  pPars->nCutNumMax = KF_CUT_MAX;
1321  pPars->nProcNumMax = KF_PROC_MAX;
1322 }
1323 Gia_Man_t * Kf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
1324 {
1325  Kf_Man_t * p;
1326  Gia_Man_t * pNew;
1327  p = Kf_ManAlloc( pGia, pPars );
1328  Kf_ManComputeMapping( p );
1329  pNew = Kf_ManDerive( p );
1330  Kf_ManFree( p );
1331  return pNew;
1332 }
1333 
1334 ////////////////////////////////////////////////////////////////////////
1335 /// END OF FILE ///
1336 ////////////////////////////////////////////////////////////////////////
1337 
1338 #endif // pthreads are used
1339 
1341 
char * memset()
static int * Vec_IntArray(Vec_Int_t *p)
Definition: vecInt.h:328
int nCutNum
Definition: gia.h:268
int nLutSize
Definition: gia.h:267
static void Vec_FltWriteEntry(Vec_Flt_t *p, int i, float Entry)
Definition: vecFlt.h:364
#define Gia_ManForEachCo(p, pObj, i)
Definition: gia.h:1022
static Llb_Mgr_t * p
Definition: llb3Image.c:950
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
static Gia_Obj_t * Gia_Regular(Gia_Obj_t *p)
Definition: gia.h:377
static void Vec_SetAlloc_(Vec_Set_t *p, int nPageSize)
FUNCTION DEFINITIONS ///.
Definition: vecSet.h:115
int nProcNum
Definition: gia.h:269
int nCutNumMax
Definition: gia.h:294
static int Abc_Var2Lit(int Var, int fCompl)
Definition: abc_global.h:263
int fCutSimple
Definition: gia.h:290
static int Gia_ObjRefDecId(Gia_Man_t *p, int Id)
Definition: gia.h:520
static int Gia_ObjRefNum(Gia_Man_t *p, Gia_Obj_t *pObj)
Definition: gia.h:521
static int Gia_ObjIsBuf(Gia_Obj_t *pObj)
Definition: gia.h:427
static float * Vec_FltArray(Vec_Flt_t *p)
Definition: vecFlt.h:274
#define Gia_ManForEachObjReverse(p, pObj, i)
Definition: gia.h:994
int fAreaOnly
Definition: gia.h:277
int nVerbLimit
Definition: gia.h:275
static abctime Abc_Clock()
Definition: abc_global.h:279
static word * Vec_SetEntry(Vec_Set_t *p, int h)
Definition: vecSet.h:70
static int Abc_MaxInt(int a, int b)
Definition: abc_global.h:238
#define Gia_ManForEachCoDriver(p, pObj, i)
Definition: gia.h:1030
static int Vec_SetAppend(Vec_Set_t *p, int *pArray, int nSize)
Definition: vecSet.h:213
int fCutHashing
Definition: gia.h:289
static void Vec_FltFill(Vec_Flt_t *p, int nSize, float Entry)
Definition: vecFlt.h:450
static Gia_Obj_t * Gia_ManObj(Gia_Man_t *p, int v)
Definition: gia.h:402
static float Abc_MaxFloat(float a, float b)
Definition: abc_global.h:243
for(p=first;p->value< newval;p=p->next)
Definition: gia.h:75
#define ABC_SWAP(Type, a, b)
Definition: abc_global.h:218
int fVeryVerbose
Definition: gia.h:292
#define Gia_ManForEachCi(p, pObj, i)
Definition: gia.h:1016
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
int fOptEdge
Definition: gia.h:278
static void Vec_IntWriteEntry(Vec_Int_t *p, int i, int Entry)
Definition: bblif.c:285
static int Gia_ManAndNum(Gia_Man_t *p)
Definition: gia.h:389
static void Vec_IntSelectSort(int *pArray, int nSize)
Definition: vecInt.h:1740
static int Abc_MinInt(int a, int b)
Definition: abc_global.h:239
ABC_NAMESPACE_IMPL_START void Kf_ManSetDefaultPars(Jf_Par_t *pPars)
DECLARATIONS ///.
Definition: giaKf.c:43
static int Abc_LitIsCompl(int Lit)
Definition: abc_global.h:265
static int Abc_Float2Int(float Val)
Definition: abc_global.h:249
static Gia_Obj_t * Gia_ObjFanin0(Gia_Obj_t *pObj)
Definition: gia.h:454
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
static void Vec_FltUpdateEntry(Vec_Flt_t *p, int i, float Value)
Definition: vecFlt.h:398
Definition: gia.h:265
static void Vec_IntAddToEntry(Vec_Int_t *p, int i, int Addition)
Definition: bblif.c:302
Gia_Man_t * Kf_ManPerformMapping(Gia_Man_t *pGia, Jf_Par_t *pPars)
Definition: giaKf.c:44
void Gia_ManStaticFanoutStop(Gia_Man_t *p)
Definition: giaFanout.c:290
static int Vec_IntEntry(Vec_Int_t *p, int i)
Definition: bblif.c:268
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
static int Gia_ObjRefInc(Gia_Man_t *p, Gia_Obj_t *pObj)
Definition: gia.h:522
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static void Vec_IntFill(Vec_Int_t *p, int nSize, int Fill)
Definition: bblif.c:356
static void Vec_SetFree_(Vec_Set_t *p)
Definition: vecSet.h:168
if(last==0)
Definition: sparse_int.h:34
static int Vec_IntPop(Vec_Int_t *p)
void Gia_ManStaticFanoutStart(Gia_Man_t *p)
Definition: giaFanout.c:238
else
Definition: sparse_int.h:55
int memcmp()
#define Gia_ManForEachAnd(p, pObj, i)
Definition: gia.h:1002
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
static int Gia_ObjId(Gia_Man_t *p, Gia_Obj_t *pObj)
Definition: gia.h:410
#define Gia_ObjForEachFanoutStaticId(p, Id, FanId, i)
Definition: gia.h:948
void Gia_ObjPrint(Gia_Man_t *p, Gia_Obj_t *pObj)
Definition: giaUtil.c:1258
int nProcNumMax
Definition: gia.h:295
static void Vec_IntFreeP(Vec_Int_t **p)
Definition: vecInt.h:289
static int Vec_IntCap(Vec_Int_t *p)
Definition: vecInt.h:368
static int Gia_ObjIsCo(Gia_Obj_t *pObj)
Definition: gia.h:421
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int Gia_ObjIsMuxType(Gia_Obj_t *pNode)
Definition: giaUtil.c:885
static int Gia_ManCiNum(Gia_Man_t *p)
Definition: gia.h:383
int nRounds
Definition: gia.h:270
static void Vec_FltAddToEntry(Vec_Flt_t *p, int i, float Addition)
Definition: vecFlt.h:381
static int Vec_IntSize(Vec_Int_t *p)
Definition: bblif.c:252
static int Vec_IntSum(Vec_Int_t *p)
Definition: vecInt.h:1137
typedefABC_NAMESPACE_HEADER_START struct Vec_Set_t_ Vec_Set_t
INCLUDES ///.
Definition: vecSet.h:49
#define ABC_FREE(obj)
Definition: abc_global.h:232
Gia_Obj_t * Gia_ObjRecognizeMux(Gia_Obj_t *pNode, Gia_Obj_t **ppNodeT, Gia_Obj_t **ppNodeE)
Definition: giaUtil.c:959
Definition: gia.h:95
int fPureAig
Definition: gia.h:287
static int Gia_ObjIsAnd(Gia_Obj_t *pObj)
Definition: gia.h:422
#define Gia_ManForEachObj(p, pObj, i)
MACRO DEFINITIONS ///.
Definition: gia.h:984
int fCutMin
Definition: gia.h:282
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
static int Abc_Lit2Var(int Lit)
Definition: abc_global.h:264
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
Definition: vecFlt.h:42
static float Abc_Int2Float(int Num)
Definition: abc_global.h:250
static Gia_Obj_t * Gia_ObjFanin1(Gia_Obj_t *pObj)
Definition: gia.h:455
int fFuncDsd
Definition: gia.h:283
int fGenCnf
Definition: gia.h:284
#define assert(ex)
Definition: util_old.h:213
double Gia_ManMemory(Gia_Man_t *p)
Definition: giaMan.c:156
static float Vec_FltEntry(Vec_Flt_t *p, int i)
Definition: vecFlt.h:342
int nLutSizeMax
Definition: gia.h:293
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
static void Vec_IntClear(Vec_Int_t *p)
Definition: bblif.c:452
ABC_INT64_T abctime
Definition: abc_global.h:278
static int Gia_ObjIsCi(Gia_Obj_t *pObj)
Definition: gia.h:420
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition: vecInt.h:54
static int Gia_ObjFaninId1(Gia_Obj_t *pObj, int ObjId)
Definition: gia.h:461
static double Vec_ReportMemory(Vec_Set_t *p)
Definition: vecSet.h:194
int DelayTarget
Definition: gia.h:276
static int Gia_ManObjNum(Gia_Man_t *p)
Definition: gia.h:388
int fVerbose
Definition: gia.h:291
static int Gia_ObjRefIncId(Gia_Man_t *p, int Id)
Definition: gia.h:519
#define inline
Definition: kitPerm.c:28
static int Gia_ObjFaninId0(Gia_Obj_t *pObj, int ObjId)
Definition: gia.h:460
int fCoarsen
Definition: gia.h:281
static int Gia_ManCoNum(Gia_Man_t *p)
Definition: gia.h:384