abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
reoCore.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [reoCore.c]
4 
5  PackageName [REO: A specialized DD reordering engine.]
6 
7  Synopsis [Implementation of the core reordering procedure.]
8 
9  Author [Alan Mishchenko]
10 
11  Affiliation [UC Berkeley]
12 
13  Date [Ver. 1.0. Started - October 15, 2002.]
14 
15  Revision [$Id: reoCore.c,v 1.0 2002/15/10 03:00:00 alanmi Exp $]
16 
17 ***********************************************************************/
18 
19 #include "reo.h"
20 
22 
23 
24 ////////////////////////////////////////////////////////////////////////
25 /// DECLARATIONS ///
26 ////////////////////////////////////////////////////////////////////////
27 
28 static int reoRecursiveDeref( reo_unit * pUnit );
29 static int reoCheckZeroRefs( reo_plane * pPlane );
30 static int reoCheckLevels( reo_man * p );
31 
32 double s_AplBefore;
33 double s_AplAfter;
34 
35 ////////////////////////////////////////////////////////////////////////
36 /// FUNCTION DEFINITIONS ///
37 ////////////////////////////////////////////////////////////////////////
38 
39 /**Function*************************************************************
40 
41  Synopsis []
42 
43  Description []
44 
45  SideEffects []
46 
47  SeeAlso []
48 
49 ***********************************************************************/
50 void reoReorderArray( reo_man * p, DdManager * dd, DdNode * Funcs[], DdNode * FuncsRes[], int nFuncs, int * pOrder )
51 {
52  int Counter, i;
53 
54  // set the initial parameters
55  p->dd = dd;
56  p->pOrder = pOrder;
57  p->nTops = nFuncs;
58  // get the initial number of nodes
59  p->nNodesBeg = Cudd_SharingSize( Funcs, nFuncs );
60  // resize the internal data structures of the manager if necessary
61  reoResizeStructures( p, ddMax(dd->size,dd->sizeZ), p->nNodesBeg, nFuncs );
62  // compute the support
63  p->pSupp = Extra_VectorSupportArray( dd, Funcs, nFuncs, p->pSupp );
64  // get the number of support variables
65  p->nSupp = 0;
66  for ( i = 0; i < dd->size; i++ )
67  p->nSupp += p->pSupp[i];
68 
69  // if it is the constant function, no need to reorder
70  if ( p->nSupp == 0 )
71  {
72  for ( i = 0; i < nFuncs; i++ )
73  {
74  FuncsRes[i] = Funcs[i]; Cudd_Ref( FuncsRes[i] );
75  }
76  return;
77  }
78 
79  // create the internal variable maps
80  // go through variable levels in the manager
81  Counter = 0;
82  for ( i = 0; i < dd->size; i++ )
83  if ( p->pSupp[ dd->invperm[i] ] )
84  {
85  p->pMapToPlanes[ dd->invperm[i] ] = Counter;
86  p->pMapToDdVarsOrig[Counter] = dd->invperm[i];
87  if ( !p->fRemapUp )
88  p->pMapToDdVarsFinal[Counter] = dd->invperm[i];
89  else
92  Counter++;
93  }
94 
95  // set the initial parameters
96  p->nUnitsUsed = 0;
97  p->nNodesCur = 0;
98  p->fThisIsAdd = 0;
99  p->Signature++;
100  // transfer the function from the CUDD package into REO"s internal data structure
101  for ( i = 0; i < nFuncs; i++ )
102  p->pTops[i] = reoTransferNodesToUnits_rec( p, Funcs[i] );
103  assert( p->nNodesBeg == p->nNodesCur );
104 
105  if ( !p->fThisIsAdd && p->fMinWidth )
106  {
107  printf( "An important message from the REO reordering engine:\n" );
108  printf( "The BDD given to the engine for reordering contains complemented edges.\n" );
109  printf( "Currently, such BDDs cannot be reordered for the minimum width.\n" );
110  printf( "Therefore, minimization for the number of BDD nodes is performed.\n" );
111  fflush( stdout );
112  p->fMinApl = 0;
113  p->fMinWidth = 0;
114  }
115 
116  if ( p->fMinWidth )
118  else if ( p->fMinApl )
120  else
122 
123  if ( p->fVerbose )
124  {
125  printf( "INITIAL:\n" );
126  if ( p->fMinWidth )
128  else if ( p->fMinApl )
130  else
132  }
133 
134  ///////////////////////////////////////////////////////////////////
135  // performs the reordering
136  p->nSwaps = 0;
137  p->nNISwaps = 0;
138  for ( i = 0; i < p->nIters; i++ )
139  {
140  reoReorderSift( p );
141  // print statistics after each iteration
142  if ( p->fVerbose )
143  {
144  printf( "ITER #%d:\n", i+1 );
145  if ( p->fMinWidth )
147  else if ( p->fMinApl )
149  else
151  }
152  // if the cost function did not change, stop iterating
153  if ( p->fMinWidth )
154  {
155  p->nWidthEnd = p->nWidthCur;
156  assert( p->nWidthEnd <= p->nWidthBeg );
157  if ( p->nWidthEnd == p->nWidthBeg )
158  break;
159  }
160  else if ( p->fMinApl )
161  {
162  p->nAplEnd = p->nAplCur;
163  assert( p->nAplEnd <= p->nAplBeg );
164  if ( p->nAplEnd == p->nAplBeg )
165  break;
166  }
167  else
168  {
169  p->nNodesEnd = p->nNodesCur;
170  assert( p->nNodesEnd <= p->nNodesBeg );
171  if ( p->nNodesEnd == p->nNodesBeg )
172  break;
173  }
174  }
175  assert( reoCheckLevels( p ) );
176  ///////////////////////////////////////////////////////////////////
177 
178 s_AplBefore = p->nAplBeg;
179 s_AplAfter = p->nAplEnd;
180 
181  // set the initial parameters
182  p->nRefNodes = 0;
183  p->nNodesCur = 0;
184  p->Signature++;
185  // transfer the BDDs from REO's internal data structure to CUDD
186  for ( i = 0; i < nFuncs; i++ )
187  {
188  FuncsRes[i] = reoTransferUnitsToNodes_rec( p, p->pTops[i] ); Cudd_Ref( FuncsRes[i] );
189  }
190  // undo the DDs referenced for storing in the cache
191  for ( i = 0; i < p->nRefNodes; i++ )
192  Cudd_RecursiveDeref( dd, p->pRefNodes[i] );
193  // verify zero refs of the terminal nodes
194  for ( i = 0; i < nFuncs; i++ )
195  {
196  assert( reoRecursiveDeref( p->pTops[i] ) );
197  }
198  assert( reoCheckZeroRefs( &(p->pPlanes[p->nSupp]) ) );
199 
200  // prepare the variable map to return to the user
201  if ( p->pOrder )
202  {
203  // i is the current level in the planes data structure
204  // p->pOrderInt[i] is the original level in the planes data structure
205  // p->pMapToDdVarsOrig[i] is the variable, into which we remap when we construct the BDD from planes
206  // p->pMapToDdVarsOrig[ p->pOrderInt[i] ] is the original BDD variable corresponding to this level
207  // Therefore, p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ]
208  // creates the permutation, which remaps the resulting BDD variable into the original BDD variable
209  for ( i = 0; i < p->nSupp; i++ )
210  p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ];
211  }
212 
213  if ( p->fVerify )
214  {
215  int fVerification;
216  DdNode * FuncRemapped;
217  int * pOrder;
218 
219  if ( p->pOrder == NULL )
220  {
221  pOrder = ABC_ALLOC( int, p->nSupp );
222  for ( i = 0; i < p->nSupp; i++ )
223  pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ];
224  }
225  else
226  pOrder = p->pOrder;
227 
228  fVerification = 1;
229  for ( i = 0; i < nFuncs; i++ )
230  {
231  // verify the result
232  if ( p->fThisIsAdd )
233  FuncRemapped = Cudd_addPermute( dd, FuncsRes[i], pOrder );
234  else
235  FuncRemapped = Cudd_bddPermute( dd, FuncsRes[i], pOrder );
236  Cudd_Ref( FuncRemapped );
237 
238  if ( FuncRemapped != Funcs[i] )
239  {
240  fVerification = 0;
241  printf( "REO: Internal verification has failed!\n" );
242  fflush( stdout );
243  }
244  Cudd_RecursiveDeref( dd, FuncRemapped );
245  }
246  if ( fVerification )
247  printf( "REO: Internal verification is okay!\n" );
248 
249  if ( p->pOrder == NULL )
250  ABC_FREE( pOrder );
251  }
252 
253  // recycle the data structure
254  for ( i = 0; i <= p->nSupp; i++ )
255  reoUnitsRecycleUnitList( p, p->pPlanes + i );
256 }
257 
258 /**Function*************************************************************
259 
260  Synopsis [Resizes the internal manager data structures.]
261 
262  Description []
263 
264  SideEffects []
265 
266  SeeAlso []
267 
268 ***********************************************************************/
269 void reoResizeStructures( reo_man * p, int nDdVarsMax, int nNodesMax, int nFuncs )
270 {
271  // resize data structures depending on the number of variables in the DD manager
272  if ( p->nSuppAlloc == 0 )
273  {
274  p->pSupp = ABC_ALLOC( int, nDdVarsMax + 1 );
275  p->pOrderInt = ABC_ALLOC( int, nDdVarsMax + 1 );
276  p->pMapToPlanes = ABC_ALLOC( int, nDdVarsMax + 1 );
277  p->pMapToDdVarsOrig = ABC_ALLOC( int, nDdVarsMax + 1 );
278  p->pMapToDdVarsFinal = ABC_ALLOC( int, nDdVarsMax + 1 );
279  p->pPlanes = ABC_CALLOC( reo_plane, nDdVarsMax + 1 );
280  p->pVarCosts = ABC_ALLOC( double, nDdVarsMax + 1 );
281  p->pLevelOrder = ABC_ALLOC( int, nDdVarsMax + 1 );
282  p->nSuppAlloc = nDdVarsMax + 1;
283  }
284  else if ( p->nSuppAlloc < nDdVarsMax )
285  {
286  ABC_FREE( p->pSupp );
287  ABC_FREE( p->pOrderInt );
288  ABC_FREE( p->pMapToPlanes );
291  ABC_FREE( p->pPlanes );
292  ABC_FREE( p->pVarCosts );
293  ABC_FREE( p->pLevelOrder );
294 
295  p->pSupp = ABC_ALLOC( int, nDdVarsMax + 1 );
296  p->pOrderInt = ABC_ALLOC( int, nDdVarsMax + 1 );
297  p->pMapToPlanes = ABC_ALLOC( int, nDdVarsMax + 1 );
298  p->pMapToDdVarsOrig = ABC_ALLOC( int, nDdVarsMax + 1 );
299  p->pMapToDdVarsFinal = ABC_ALLOC( int, nDdVarsMax + 1 );
300  p->pPlanes = ABC_CALLOC( reo_plane, nDdVarsMax + 1 );
301  p->pVarCosts = ABC_ALLOC( double, nDdVarsMax + 1 );
302  p->pLevelOrder = ABC_ALLOC( int, nDdVarsMax + 1 );
303  p->nSuppAlloc = nDdVarsMax + 1;
304  }
305 
306  // resize the data structures depending on the number of nodes
307  if ( p->nRefNodesAlloc == 0 )
308  {
309  p->nNodesMaxAlloc = nNodesMax;
310  p->nTableSize = 3*nNodesMax + 1;
311  p->nRefNodesAlloc = 3*nNodesMax + 1;
312  p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1;
313 
314  p->HTable = ABC_CALLOC( reo_hash, p->nTableSize );
318  }
319  else if ( p->nNodesMaxAlloc < nNodesMax )
320  {
321  reo_unit ** pTemp;
322  int nMemChunksAllocPrev = p->nMemChunksAlloc;
323 
324  p->nNodesMaxAlloc = nNodesMax;
325  p->nTableSize = 3*nNodesMax + 1;
326  p->nRefNodesAlloc = 3*nNodesMax + 1;
327  p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1;
328 
329  ABC_FREE( p->HTable );
330  ABC_FREE( p->pRefNodes );
331  ABC_FREE( p->pWidthCofs );
332  p->HTable = ABC_CALLOC( reo_hash, p->nTableSize );
335  // p->pMemChunks should be reallocated because it contains pointers currently in use
336  pTemp = ABC_ALLOC( reo_unit *, p->nMemChunksAlloc );
337  memmove( pTemp, p->pMemChunks, sizeof(reo_unit *) * nMemChunksAllocPrev );
338  ABC_FREE( p->pMemChunks );
339  p->pMemChunks = pTemp;
340  }
341 
342  // resize the data structures depending on the number of functions
343  if ( p->nTopsAlloc == 0 )
344  {
345  p->pTops = ABC_ALLOC( reo_unit *, nFuncs );
346  p->nTopsAlloc = nFuncs;
347  }
348  else if ( p->nTopsAlloc < nFuncs )
349  {
350  ABC_FREE( p->pTops );
351  p->pTops = ABC_ALLOC( reo_unit *, nFuncs );
352  p->nTopsAlloc = nFuncs;
353  }
354 }
355 
356 
357 /**Function*************************************************************
358 
359  Synopsis [Dereferences units the data structure after reordering.]
360 
361  Description [This function is only useful for debugging.]
362 
363  SideEffects []
364 
365  SeeAlso []
366 
367 ***********************************************************************/
369 {
370  reo_unit * pUnitR;
371  pUnitR = Unit_Regular(pUnit);
372  pUnitR->n--;
373  if ( Unit_IsConstant(pUnitR) )
374  return 1;
375  if ( pUnitR->n == 0 )
376  {
377  reoRecursiveDeref( pUnitR->pE );
378  reoRecursiveDeref( pUnitR->pT );
379  }
380  return 1;
381 }
382 
383 /**Function*************************************************************
384 
385  Synopsis [Checks the zero references for the given plane.]
386 
387  Description [This function is only useful for debugging.]
388 
389  SideEffects []
390 
391  SeeAlso []
392 
393 ***********************************************************************/
395 {
396  reo_unit * pUnit;
397  for ( pUnit = pPlane->pHead; pUnit; pUnit = pUnit->Next )
398  {
399  if ( pUnit->n != 0 )
400  {
401  assert( 0 );
402  }
403  }
404  return 1;
405 }
406 
407 /**Function*************************************************************
408 
409  Synopsis [Checks the zero references for the given plane.]
410 
411  Description [This function is only useful for debugging.]
412 
413  SideEffects []
414 
415  SeeAlso []
416 
417 ***********************************************************************/
419 {
420  reo_unit * pUnit;
421  int i;
422 
423  for ( i = 0; i < p->nSupp; i++ )
424  {
425  // there are some nodes left on each level
426  assert( p->pPlanes[i].statsNodes );
427  for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next )
428  {
429  // the level is properly set
430  assert( pUnit->lev == i );
431  }
432  }
433  return 1;
434 }
435 
436 ////////////////////////////////////////////////////////////////////////
437 /// END OF FILE ///
438 ////////////////////////////////////////////////////////////////////////
439 
441 
int fMinApl
Definition: reo.h:105
int fVerbose
Definition: reo.h:106
int nWidthBeg
Definition: reo.h:130
short lev
Definition: reo.h:68
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
static Llb_Mgr_t * p
Definition: llb3Image.c:950
void reoProfileAplStart(reo_man *p)
Definition: reoProfile.c:78
static int reoCheckZeroRefs(reo_plane *pPlane)
Definition: reoCore.c:394
reo_unit ** pWidthCofs
Definition: reo.h:123
double * pVarCosts
Definition: reo.h:121
double nAplCur
Definition: reo.h:132
int size
Definition: cuddInt.h:361
void reoProfileWidthStart(reo_man *p)
Definition: reoProfile.c:130
int nTops
Definition: reo.h:145
void reoProfileWidthPrint(reo_man *p)
Definition: reoProfile.c:321
DdManager * dd
Definition: reo.h:112
int nTopsAlloc
Definition: reo.h:146
reo_unit * reoTransferNodesToUnits_rec(reo_man *p, DdNode *F)
DECLARATIONS ///.
Definition: reoTransfer.c:43
int * pMapToPlanes
Definition: reo.h:137
int Signature
Definition: reo.h:151
int nNodesCur
Definition: reo.h:127
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int nUnitsUsed
Definition: reo.h:164
int fThisIsAdd
Definition: reo.h:116
int nNodesMaxAlloc
Definition: reo.h:154
int nSupp
Definition: reo.h:119
int * Extra_VectorSupportArray(DdManager *dd, DdNode **F, int n, int *support)
Definition: extraBddMisc.c:572
DdNode * reoTransferUnitsToNodes_rec(reo_man *p, reo_unit *pUnit)
Definition: reoTransfer.c:120
void reoUnitsRecycleUnitList(reo_man *p, reo_plane *pPlane)
Definition: reoUnits.c:87
int nRefNodes
Definition: reo.h:156
double nAplBeg
Definition: reo.h:133
int nNISwaps
Definition: reo.h:170
int * pOrder
Definition: reo.h:113
char * memmove()
int * pMapToDdVarsFinal
Definition: reo.h:139
int fRemapUp
Definition: reo.h:108
int nSuppAlloc
Definition: reo.h:118
DdNode * Cudd_addPermute(DdManager *manager, DdNode *node, int *permut)
Definition: cuddCompose.c:242
int * pLevelOrder
Definition: reo.h:122
reo_unit * pT
Definition: reo.h:75
int fMinWidth
Definition: reo.h:104
void reoProfileNodesStart(reo_man *p)
DECLARATIONS ///.
Definition: reoProfile.c:46
double s_AplBefore
Definition: reoCore.c:32
DdNode ** pRefNodes
Definition: reo.h:155
DdNode * Cudd_bddPermute(DdManager *manager, DdNode *node, int *permut)
Definition: cuddCompose.c:332
reo_unit * Next
Definition: reo.h:76
short n
Definition: reo.h:71
int nIters
Definition: reo.h:109
int nNodesBeg
Definition: reo.h:126
reo_unit * pE
Definition: reo.h:74
static ABC_NAMESPACE_IMPL_START int reoRecursiveDeref(reo_unit *pUnit)
DECLARATIONS ///.
Definition: reoCore.c:368
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
double s_AplAfter
Definition: reoCore.c:33
#define ddMax(x, y)
Definition: cuddInt.h:832
if(last==0)
Definition: sparse_int.h:34
reo_hash * HTable
Definition: reo.h:149
int nTableSize
Definition: reo.h:150
static int Counter
int nRefNodesAlloc
Definition: reo.h:157
Definition: reo.h:80
reo_unit ** pTops
Definition: reo.h:144
void reoProfileAplPrint(reo_man *p)
Definition: reoProfile.c:305
#define Unit_Regular(u)
Definition: reo.h:174
void reoReorderSift(reo_man *p)
DECLARATIONS ///.
Definition: reoSift.c:44
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int * pSupp
Definition: reo.h:117
int * pMapToDdVarsOrig
Definition: reo.h:138
#define Unit_IsConstant(u)
Definition: reo.h:177
reo_plane * pPlanes
Definition: reo.h:142
void reoReorderArray(reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder)
FUNCTION DEFINITIONS ///.
Definition: reoCore.c:50
int nMemChunksAlloc
Definition: reo.h:163
int nSwaps
Definition: reo.h:169
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define REO_CHUNK_SIZE
Definition: reo.h:42
int nWidthEnd
Definition: reo.h:131
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
Definition: reo.h:66
void reoProfileNodesPrint(reo_man *p)
Definition: reoProfile.c:289
reo_unit ** pMemChunks
Definition: reo.h:161
#define assert(ex)
Definition: util_old.h:213
int fVerify
Definition: reo.h:107
int * invperm
Definition: cuddInt.h:388
int nNodesEnd
Definition: reo.h:128
int statsNodes
Definition: reo.h:83
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
reo_unit * pHead
Definition: reo.h:90
void reoResizeStructures(reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
Definition: reoCore.c:269
int Cudd_SharingSize(DdNode **nodeArray, int n)
Definition: cuddUtil.c:544
double nAplEnd
Definition: reo.h:134
int * pOrderInt
Definition: reo.h:120
static int reoCheckLevels(reo_man *p)
Definition: reoCore.c:418
int nWidthCur
Definition: reo.h:129
Definition: reo.h:101
Definition: reo.h:93