abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
reo.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include "misc/extra/extraBdd.h"

Go to the source code of this file.

Data Structures

struct  _reo_unit
 
struct  _reo_plane
 
struct  _reo_hash
 
struct  _reo_man
 

Macros

#define REO_REORDER_LIMIT   1.15
 MACRO DEFINITIONS ///. More...
 
#define REO_QUAL_PAR   3
 
#define REO_CONST_LEVEL   30000
 
#define REO_TOPREF_UNDEF   30000
 
#define REO_CHUNK_SIZE   5000
 
#define REO_COST_EPSILON   0.0000001
 
#define REO_HIGH_VALUE   10000000
 
#define REO_ENABLE   1
 
#define REO_DISABLE   0
 
#define Unit_Regular(u)   ((reo_unit *)((ABC_PTRUINT_T)(u) & ~01))
 
#define Unit_Not(u)   ((reo_unit *)((ABC_PTRUINT_T)(u) ^ 01))
 
#define Unit_NotCond(u, c)   ((reo_unit *)((ABC_PTRUINT_T)(u) ^ (c)))
 
#define Unit_IsConstant(u)   ((int)((u)->lev == REO_CONST_LEVEL))
 

Typedefs

typedef struct _reo_unit reo_unit
 DATA STRUCTURES ///. More...
 
typedef struct _reo_plane reo_plane
 
typedef struct _reo_hash reo_hash
 
typedef struct _reo_man reo_man
 
typedef struct _reo_test reo_test
 

Enumerations

enum  reo_min_type { REO_MINIMIZE_NODES, REO_MINIMIZE_WIDTH, REO_MINIMIZE_APL }
 

Functions

reo_manExtra_ReorderInit (int nDdVarsMax, int nNodesMax)
 FUNCTION DECLARATIONS ///. More...
 
void Extra_ReorderQuit (reo_man *p)
 
void Extra_ReorderSetMinimizationType (reo_man *p, reo_min_type fMinType)
 
void Extra_ReorderSetRemapping (reo_man *p, int fRemapUp)
 
void Extra_ReorderSetIterations (reo_man *p, int nIters)
 
void Extra_ReorderSetVerbosity (reo_man *p, int fVerbose)
 
void Extra_ReorderSetVerification (reo_man *p, int fVerify)
 
DdNodeExtra_Reorder (reo_man *p, DdManager *dd, DdNode *Func, int *pOrder)
 
void Extra_ReorderArray (reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder)
 
void reoReorderArray (reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder)
 FUNCTION DEFINITIONS ///. More...
 
void reoResizeStructures (reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
 
void reoProfileNodesStart (reo_man *p)
 DECLARATIONS ///. More...
 
void reoProfileAplStart (reo_man *p)
 
void reoProfileWidthStart (reo_man *p)
 
void reoProfileWidthStart2 (reo_man *p)
 
void reoProfileAplPrint (reo_man *p)
 
void reoProfileNodesPrint (reo_man *p)
 
void reoProfileWidthPrint (reo_man *p)
 
void reoProfileWidthVerifyLevel (reo_plane *pPlane, int Level)
 
void reoReorderSift (reo_man *p)
 DECLARATIONS ///. More...
 
double reoReorderSwapAdjacentVars (reo_man *p, int Level, int fMovingUp)
 FUNCTION DEFINITIONS ///. More...
 
reo_unitreoTransferNodesToUnits_rec (reo_man *p, DdNode *F)
 DECLARATIONS ///. More...
 
DdNodereoTransferUnitsToNodes_rec (reo_man *p, reo_unit *pUnit)
 
reo_unitreoUnitsGetNextUnit (reo_man *p)
 FUNCTION DEFINITIONS ///. More...
 
void reoUnitsRecycleUnit (reo_man *p, reo_unit *pUnit)
 
void reoUnitsRecycleUnitList (reo_man *p, reo_plane *pPlane)
 
void reoUnitsAddUnitToPlane (reo_plane *pPlane, reo_unit *pUnit)
 
void reoUnitsStopDispenser (reo_man *p)
 
void Extra_ReorderTest (DdManager *dd, DdNode *Func)
 DECLARATIONS ///. More...
 
DdNodeExtra_ReorderCudd (DdManager *dd, DdNode *aFunc, int pPermuteReo[])
 
int Extra_bddReorderTest (DdManager *dd, DdNode *bF)
 
int Extra_addReorderTest (DdManager *dd, DdNode *aF)
 

Macro Definition Documentation

#define REO_CHUNK_SIZE   5000

Definition at line 42 of file reo.h.

#define REO_CONST_LEVEL   30000

Definition at line 40 of file reo.h.

#define REO_COST_EPSILON   0.0000001

Definition at line 43 of file reo.h.

#define REO_DISABLE   0

Definition at line 47 of file reo.h.

#define REO_ENABLE   1

Definition at line 46 of file reo.h.

#define REO_HIGH_VALUE   10000000

Definition at line 44 of file reo.h.

#define REO_QUAL_PAR   3

Definition at line 38 of file reo.h.

#define REO_REORDER_LIMIT   1.15

MACRO DEFINITIONS ///.

CFile****************************************************************

FileName [reo.h]

PackageName [REO: A specialized DD reordering engine.]

Synopsis [External and internal declarations.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - October 15, 2002.]

Revision [

Id:
reo.h,v 1.0 2002/15/10 03:00:00 alanmi Exp

]

Definition at line 37 of file reo.h.

#define REO_TOPREF_UNDEF   30000

Definition at line 41 of file reo.h.

#define Unit_IsConstant (   u)    ((int)((u)->lev == REO_CONST_LEVEL))

Definition at line 177 of file reo.h.

#define Unit_Not (   u)    ((reo_unit *)((ABC_PTRUINT_T)(u) ^ 01))

Definition at line 175 of file reo.h.

#define Unit_NotCond (   u,
 
)    ((reo_unit *)((ABC_PTRUINT_T)(u) ^ (c)))

Definition at line 176 of file reo.h.

#define Unit_Regular (   u)    ((reo_unit *)((ABC_PTRUINT_T)(u) & ~01))

Definition at line 174 of file reo.h.

Typedef Documentation

typedef struct _reo_hash reo_hash

Definition at line 62 of file reo.h.

typedef struct _reo_man reo_man

Definition at line 63 of file reo.h.

typedef struct _reo_plane reo_plane

Definition at line 61 of file reo.h.

typedef struct _reo_test reo_test

Definition at line 64 of file reo.h.

typedef struct _reo_unit reo_unit

DATA STRUCTURES ///.

Definition at line 60 of file reo.h.

Enumeration Type Documentation

Enumerator
REO_MINIMIZE_NODES 
REO_MINIMIZE_WIDTH 
REO_MINIMIZE_APL 

Definition at line 50 of file reo.h.

50  {
52  REO_MINIMIZE_WIDTH, // may not work for BDDs with complemented edges
54 } reo_min_type;
reo_min_type
Definition: reo.h:50

Function Documentation

int Extra_addReorderTest ( DdManager dd,
DdNode aF 
)

Function*************************************************************

Synopsis []

Description [Transfers the ADD into another manager minimizes it and returns the min number of nodes; disposes of the BDD in the new manager. Useful for debugging or comparing the performance of other reordering procedures.]

SideEffects []

SeeAlso []

Definition at line 217 of file reoTest.c.

218 {
219  static DdManager * s_ddmin;
220  DdNode * bF;
221  DdNode * bFmin;
222  DdNode * aFmin;
223  int nNodesBeg;
224  int nNodesEnd;
225  abctime clk1;
226 
227  if ( s_ddmin == NULL )
228  s_ddmin = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
229 
230 // Cudd_ShuffleHeap( s_ddmin, dd->invperm );
231 
232  clk1 = Abc_Clock();
233  bF = Cudd_addBddPattern( dd, aF ); Cudd_Ref( bF );
234  bFmin = Cudd_bddTransfer( dd, s_ddmin, bF ); Cudd_Ref( bFmin );
235  Cudd_RecursiveDeref( dd, bF );
236  aFmin = Cudd_BddToAdd( s_ddmin, bFmin ); Cudd_Ref( aFmin );
237  Cudd_RecursiveDeref( s_ddmin, bFmin );
238 
239  nNodesBeg = Cudd_DagSize( aFmin );
241 // Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT,1);
242  nNodesEnd = Cudd_DagSize( aFmin );
243  Cudd_RecursiveDeref( s_ddmin, aFmin );
244 
245  printf( "Classical reordering of ADDs: Before = %d. After = %d.\n", nNodesBeg, nNodesEnd );
246  printf( "Classical variable reordering time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
247  return nNodesEnd;
248 }
#define CUDD_UNIQUE_SLOTS
Definition: cudd.h:97
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
DdNode * Cudd_addBddPattern(DdManager *dd, DdNode *f)
Definition: cuddBridge.c:379
#define CUDD_CACHE_SLOTS
Definition: cudd.h:98
static abctime Abc_Clock()
Definition: abc_global.h:279
DdNode * Cudd_bddTransfer(DdManager *ddSource, DdManager *ddDestination, DdNode *f)
Definition: cuddBridge.c:409
DdManager * Cudd_Init(unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)
Definition: cuddInit.c:125
DdNode * Cudd_BddToAdd(DdManager *dd, DdNode *B)
Definition: cuddBridge.c:349
static DdManager * s_ddmin
Definition: casCore.c:927
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:176
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
ABC_INT64_T abctime
Definition: abc_global.h:278
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
int Extra_bddReorderTest ( DdManager dd,
DdNode bF 
)

Function*************************************************************

Synopsis []

Description [Transfers the BDD into another manager minimizes it and returns the min number of nodes; disposes of the BDD in the new manager. Useful for debugging or comparing the performance of other reordering procedures.]

SideEffects []

SeeAlso []

Definition at line 180 of file reoTest.c.

181 {
182  static DdManager * s_ddmin;
183  DdNode * bFmin;
184  int nNodes;
185 // abctime clk1;
186 
187  if ( s_ddmin == NULL )
188  s_ddmin = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
189 
190 // Cudd_ShuffleHeap( s_ddmin, dd->invperm );
191 
192 // clk1 = Abc_Clock();
193  bFmin = Cudd_bddTransfer( dd, s_ddmin, bF ); Cudd_Ref( bFmin );
195 // Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT,1);
196  nNodes = Cudd_DagSize( bFmin );
197  Cudd_RecursiveDeref( s_ddmin, bFmin );
198 
199 // printf( "Classical variable reordering time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
200  return nNodes;
201 }
#define CUDD_UNIQUE_SLOTS
Definition: cudd.h:97
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
#define CUDD_CACHE_SLOTS
Definition: cudd.h:98
DdNode * Cudd_bddTransfer(DdManager *ddSource, DdManager *ddDestination, DdNode *f)
Definition: cuddBridge.c:409
DdManager * Cudd_Init(unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)
Definition: cuddInit.c:125
static DdManager * s_ddmin
Definition: casCore.c:927
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:176
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
DdNode* Extra_Reorder ( reo_man p,
DdManager dd,
DdNode Func,
int *  pOrder 
)

Function*************************************************************

Synopsis [Performs reordering of the function.]

Description [Returns the DD minimized by variable reordering in the REO engine. Takes the CUDD decision diagram manager (dd) and the function (Func) represented as a BDD or ADD (MTBDD). If the variable array (pOrder) is not NULL, returns the resulting variable permutation. The permutation is such that if the resulting function is permuted by Cudd_(add,bdd)Permute() using pOrder as the permutation array, the initial function (Func) results. Several flag set by other interface functions specify reordering options:

  • Remappig can be set by Extra_ReorderSetRemapping(). Then the resulting DD after reordering is remapped into the topmost levels of the DD manager. Otherwise, the resulting DD after reordering is mapped using the same variables, on which it originally depended, only (possibly) permuted as a result of reordering.
  • Minimization type can be set by Extra_ReorderSetMinimizationType(). Note that when the BDD is minimized for the total width of the total APL, the number BDD nodes can increase. The total width is defines as sum total of widths on each level. The width on one level is defined as the number of distinct BDD nodes pointed by the nodes situated above the given level.
  • The number of iterations of sifting can be set by Extra_ReorderSetIterations(). The decision diagram returned by this procedure is not referenced.]

SideEffects []

SeeAlso []

Definition at line 262 of file reoApi.c.

263 {
264  DdNode * FuncRes;
265  Extra_ReorderArray( p, dd, &Func, &FuncRes, 1, pOrder );
266  Cudd_Deref( FuncRes );
267  return FuncRes;
268 }
Definition: cudd.h:278
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
void Extra_ReorderArray(reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder)
Definition: reoApi.c:283
void Extra_ReorderArray ( reo_man p,
DdManager dd,
DdNode Funcs[],
DdNode FuncsRes[],
int  nFuncs,
int *  pOrder 
)

Function*************************************************************

Synopsis [Performs reordering of the array of functions.]

Description [The options are similar to the procedure Extra_Reorder(), except that the user should also provide storage for the resulting DDs, which are returned referenced.]

SideEffects []

SeeAlso []

Definition at line 283 of file reoApi.c.

284 {
285  reoReorderArray( p, dd, Funcs, FuncsRes, nFuncs, pOrder );
286 }
void reoReorderArray(reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder)
FUNCTION DEFINITIONS ///.
Definition: reoCore.c:50
DdNode* Extra_ReorderCudd ( DdManager dd,
DdNode aFunc,
int  pPermuteReo[] 
)

Function*************************************************************

Synopsis [Reorders the DD using CUDD package.]

Description [Transfers the DD into a temporary manager in such a way that the level correspondence is preserved. Reorders the manager and transfers the DD back into the original manager using the topmost levels of the manager, in such a way that the ordering of levels is preserved. The resulting permutation is returned in the array given by the user.]

SideEffects []

SeeAlso []

Definition at line 109 of file reoTest.c.

110 {
111  static DdManager * ddReorder = NULL;
112  static int * Permute = NULL;
113  static int * PermuteReo1 = NULL;
114  static int * PermuteReo2 = NULL;
115  DdNode * aFuncReorder, * aFuncNew;
116  int lev, var;
117 
118  // start the reordering manager
119  if ( ddReorder == NULL )
120  {
121  Permute = ABC_ALLOC( int, dd->size );
122  PermuteReo1 = ABC_ALLOC( int, dd->size );
123  PermuteReo2 = ABC_ALLOC( int, dd->size );
124  ddReorder = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
125  Cudd_AutodynDisable(ddReorder);
126  }
127 
128  // determine the permutation of variable to make sure that var order in bFunc
129  // will not change when this function is transfered into the new manager
130  for ( lev = 0; lev < dd->size; lev++ )
131  {
132  Permute[ dd->invperm[lev] ] = ddReorder->invperm[lev];
133  PermuteReo1[ ddReorder->invperm[lev] ] = dd->invperm[lev];
134  }
135  // transfer this function into the new manager in such a way that ordering of vars does not change
136  aFuncReorder = Extra_TransferPermute( dd, ddReorder, aFunc, Permute ); Cudd_Ref( aFuncReorder );
137 // assert( Cudd_DagSize(aFunc) == Cudd_DagSize(aFuncReorder) );
138 
139  // perform the reordering
140 printf( "Nodes before = %d.\n", Cudd_DagSize(aFuncReorder) );
141  Cudd_ReduceHeap( ddReorder, CUDD_REORDER_SYMM_SIFT, 1 );
142 printf( "Nodes before = %d.\n", Cudd_DagSize(aFuncReorder) );
143 
144  // determine the reverse variable permutation
145  for ( lev = 0; lev < dd->size; lev++ )
146  {
147  Permute[ ddReorder->invperm[lev] ] = dd->invperm[lev];
148  PermuteReo2[ dd->invperm[lev] ] = ddReorder->invperm[lev];
149  }
150 
151  // transfer this function into the new manager in such a way that ordering of vars does not change
152  aFuncNew = Extra_TransferPermute( ddReorder, dd, aFuncReorder, Permute ); Cudd_Ref( aFuncNew );
153 // assert( Cudd_DagSize(aFuncNew) == Cudd_DagSize(aFuncReorder) );
154  Cudd_RecursiveDeref( ddReorder, aFuncReorder );
155 
156  // derive the resulting variable ordering
157  if ( pPermuteReo )
158  for ( var = 0; var < dd->size; var++ )
159  pPermuteReo[var] = PermuteReo1[ PermuteReo2[var] ];
160 
161  Cudd_Deref( aFuncNew );
162  return aFuncNew;
163 }
#define CUDD_UNIQUE_SLOTS
Definition: cudd.h:97
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
DdNode * Extra_TransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
Definition: extraBddMisc.c:87
#define CUDD_CACHE_SLOTS
Definition: cudd.h:98
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdManager * Cudd_Init(unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)
Definition: cuddInit.c:125
void Cudd_AutodynDisable(DdManager *unique)
Definition: cuddAPI.c:708
int * invperm
Definition: cuddInt.h:388
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:176
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
reo_man* Extra_ReorderInit ( int  nDdVarsMax,
int  nNodesMax 
)

FUNCTION DECLARATIONS ///.

FUNCTION DECLARATIONS ///.

CFile****************************************************************

FileName [reoApi.c]

PackageName [REO: A specialized DD reordering engine.]

Synopsis [Implementation of API functions.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - October 15, 2002.]

Revision [

Id:
reoApi.c,v 1.0 2002/15/10 03:00:00 alanmi Exp

]FUNCTION DEFINITIONS /// Function*************************************************************

Synopsis [Initializes the reordering engine.]

Description [The first argument is the max number of variables in the CUDD DD manager which will be used with the reordering engine (this number of should be the maximum of BDD and ZDD parts). The second argument is the maximum number of BDD nodes in the BDDs to be reordered. These limits are soft. Setting lower limits will later cause the reordering manager to resize internal data structures. However, setting the exact values will make reordering more efficient because resizing will be not necessary.]

SideEffects []

SeeAlso []

Definition at line 50 of file reoApi.c.

51 {
52  reo_man * p;
53  // allocate and clean the data structure
54  p = ABC_ALLOC( reo_man, 1 );
55  memset( p, 0, sizeof(reo_man) );
56  // resize the manager to meet user's needs
57  reoResizeStructures( p, nDdVarsMax, nNodesMax, 100 );
58  // set the defaults
59  p->fMinApl = 0;
60  p->fMinWidth = 0;
61  p->fRemapUp = 0;
62  p->fVerbose = 0;
63  p->fVerify = 0;
64  p->nIters = 1;
65  return p;
66 }
char * memset()
int fMinApl
Definition: reo.h:105
int fVerbose
Definition: reo.h:106
static Llb_Mgr_t * p
Definition: llb3Image.c:950
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int fRemapUp
Definition: reo.h:108
int fMinWidth
Definition: reo.h:104
void reoResizeStructures(reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
Definition: reoCore.c:269
int nIters
Definition: reo.h:109
int fVerify
Definition: reo.h:107
Definition: reo.h:101
void Extra_ReorderQuit ( reo_man p)

Function*************************************************************

Synopsis [Disposes of the reordering engine.]

Description [Removes all memory associated with the reordering engine.]

SideEffects []

SeeAlso []

Definition at line 79 of file reoApi.c.

80 {
81  ABC_FREE( p->pTops );
82  ABC_FREE( p->pSupp );
83  ABC_FREE( p->pOrderInt );
84  ABC_FREE( p->pWidthCofs );
85  ABC_FREE( p->pMapToPlanes );
88  ABC_FREE( p->pPlanes );
89  ABC_FREE( p->pVarCosts );
90  ABC_FREE( p->pLevelOrder );
91  ABC_FREE( p->HTable );
92  ABC_FREE( p->pRefNodes );
94  ABC_FREE( p->pMemChunks );
95  ABC_FREE( p );
96 }
reo_unit ** pWidthCofs
Definition: reo.h:123
double * pVarCosts
Definition: reo.h:121
int * pMapToPlanes
Definition: reo.h:137
int * pMapToDdVarsFinal
Definition: reo.h:139
void reoUnitsStopDispenser(reo_man *p)
Definition: reoUnits.c:115
int * pLevelOrder
Definition: reo.h:122
DdNode ** pRefNodes
Definition: reo.h:155
reo_hash * HTable
Definition: reo.h:149
reo_unit ** pTops
Definition: reo.h:144
int * pSupp
Definition: reo.h:117
int * pMapToDdVarsOrig
Definition: reo.h:138
reo_plane * pPlanes
Definition: reo.h:142
#define ABC_FREE(obj)
Definition: abc_global.h:232
reo_unit ** pMemChunks
Definition: reo.h:161
int * pOrderInt
Definition: reo.h:120
void Extra_ReorderSetIterations ( reo_man p,
int  nIters 
)

Function*************************************************************

Synopsis [Sets the number of iterations of sifting performed.]

Description [The default is one iteration. But a higher minimization quality is desired, it is possible to set the number of iterations to any number larger than 1. Convergence is often reached after several iterations, so typically it make no sense to set the number of iterations higher than 3.]

SideEffects []

SeeAlso []

Definition at line 192 of file reoApi.c.

193 {
194  p->nIters = nIters;
195 }
int nIters
Definition: reo.h:109
void Extra_ReorderSetMinimizationType ( reo_man p,
reo_min_type  fMinType 
)

Function*************************************************************

Synopsis [Sets the type of DD minimizationl that will be performed.]

Description [Currently, three different types of minimization are supported. It is possible to minimize the number of BDD nodes. This is a classical type of minimization, which is attempting to reduce the total number of nodes in the (shared) BDD of the given Boolean functions. It is also possible to minimize the BDD width, defined as the sum total of the number of cofactors on each level in the (shared) BDD (note that the number of cofactors on the given level may be larger than the number of nodes appearing on the given level). It is also possible to minimize the average path length in the (shared) BDD defined as the sum of products, for all BDD paths from the top node to any terminal node, of the number of minterms on the path by the number of nodes on the path. The default reordering type is minimization for the number of BDD nodes. Calling this function with REO_MINIMIZE_WIDTH or REO_MINIMIZE_APL as the second argument, changes the default minimization option for all the reorder calls performed afterwards.]

SideEffects []

SeeAlso []

Definition at line 122 of file reoApi.c.

123 {
124  if ( fMinType == REO_MINIMIZE_NODES )
125  {
126  p->fMinWidth = 0;
127  p->fMinApl = 0;
128  }
129  else if ( fMinType == REO_MINIMIZE_WIDTH )
130  {
131  p->fMinWidth = 1;
132  p->fMinApl = 0;
133  }
134  else if ( fMinType == REO_MINIMIZE_APL )
135  {
136  p->fMinWidth = 0;
137  p->fMinApl = 1;
138  }
139  else
140  {
141  assert( 0 );
142  }
143 }
int fMinApl
Definition: reo.h:105
int fMinWidth
Definition: reo.h:104
#define assert(ex)
Definition: util_old.h:213
void Extra_ReorderSetRemapping ( reo_man p,
int  fRemapUp 
)

Function*************************************************************

Synopsis [Sets the type of remapping performed by the engine.]

Description [The remapping refers to the way the resulting BDD is expressed using the elementary variables of the CUDD BDD manager. Currently, two types possibilities are supported: remapping and no remapping. Remapping means that the function(s) after reordering depend on the topmost variables in the manager. No remapping means that the function(s) after reordering depend on the same variables as before. Consider the following example. Suppose the initial four variable function depends on variables 2,4,5, and 9 on the CUDD BDD manager, which may be found anywhere in the current variable order. If remapping is set, the function after ordering depends on the topmost variables in the manager, which may or may not be the same as the variables 2,4,5, and 9. If no remapping is set, then the reordered function depend on the same variables 2,4,5, and 9, but the meaning of each variale has changed according to the new ordering. The resulting ordering is returned in the array "pOrder" filled out by the reordering engine in the call to Extra_Reorder(). The default is no remapping.]

SideEffects []

SeeAlso []

Definition at line 172 of file reoApi.c.

173 {
174  p->fRemapUp = fRemapUp;
175 }
int fRemapUp
Definition: reo.h:108
void Extra_ReorderSetVerbosity ( reo_man p,
int  fVerbose 
)

Function*************************************************************

Synopsis [Sets the verbosity level.]

Description [Setting the level to 1 results in printing statistics before and after the reordering.]

SideEffects []

SeeAlso []

Definition at line 229 of file reoApi.c.

230 {
231  p->fVerbose = fVerbose;
232 }
int fVerbose
Definition: reo.h:106
void Extra_ReorderSetVerification ( reo_man p,
int  fVerify 
)

Function*************************************************************

Synopsis [Sets the verification mode.]

Description [Setting the level to 1 results in verifying the results of variable reordering. Verification is performed by remapping the resulting functions into the original variable order and comparing them with the original functions given by the user. Enabling verification typically leads to 20-30% increase in the total runtime of REO.]

SideEffects []

SeeAlso []

Definition at line 212 of file reoApi.c.

213 {
214  p->fVerify = fVerify;
215 }
int fVerify
Definition: reo.h:107
void Extra_ReorderTest ( DdManager dd,
DdNode Func 
)

DECLARATIONS ///.

CFile****************************************************************

FileName [reoTest.c]

PackageName [REO: A specialized DD reordering engine.]

Synopsis [Various testing procedures (may be outdated).]

Author [Alan Mishchenko alanm.nosp@m.i@ec.nosp@m.e.pdx.nosp@m..edu]

Affiliation [ECE Department. Portland State University, Portland, Oregon.]

Date [Ver. 1.0. Started - October 15, 2002.]

Revision [

Id:
reoTest.c,v 1.0 2002/15/10 03:00:00 alanmi Exp

]FUNCTION DEFINITIONS /// Function*************************************************************

Synopsis [Reorders the DD using REO and CUDD.]

Description [This function can be used to test the performance of the reordering package.]

SideEffects []

SeeAlso []

Definition at line 43 of file reoTest.c.

44 {
45  reo_man * pReo;
46  DdNode * Temp, * Temp1;
47  int pOrder[1000];
48 
49  pReo = Extra_ReorderInit( 100, 100 );
50 
51 //Extra_DumpDot( dd, &Func, 1, "beforReo.dot", 0 );
52  Temp = Extra_Reorder( pReo, dd, Func, pOrder ); Cudd_Ref( Temp );
53 //Extra_DumpDot( dd, &Temp, 1, "afterReo.dot", 0 );
54 
55  Temp1 = Extra_ReorderCudd(dd, Func, NULL ); Cudd_Ref( Temp1 );
56 printf( "Initial = %d. Final = %d. Cudd = %d.\n", Cudd_DagSize(Func), Cudd_DagSize(Temp), Cudd_DagSize(Temp1) );
57  Cudd_RecursiveDeref( dd, Temp1 );
58  Cudd_RecursiveDeref( dd, Temp );
59 
60  Extra_ReorderQuit( pReo );
61 }
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * Extra_Reorder(reo_man *p, DdManager *dd, DdNode *Func, int *pOrder)
Definition: reoApi.c:262
DdNode * Extra_ReorderCudd(DdManager *dd, DdNode *aFunc, int pPermuteReo[])
Definition: reoTest.c:109
reo_man * Extra_ReorderInit(int nDdVarsMax, int nNodesMax)
FUNCTION DECLARATIONS ///.
Definition: reoApi.c:50
void Extra_ReorderQuit(reo_man *p)
Definition: reoApi.c:79
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
Definition: reo.h:101
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
void reoProfileAplPrint ( reo_man p)

Function********************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 305 of file reoProfile.c.

306 {
307  printf( "APL: Total = %8.2f. Average =%6.2f.\n", p->nAplCur, p->nAplCur / (float)p->nSupp );
308 }
double nAplCur
Definition: reo.h:132
int nSupp
Definition: reo.h:119
void reoProfileAplStart ( reo_man p)

Function*************************************************************

Synopsis [Start the profile for the APL.]

Description [Computes the total path length. The path length is normalized by dividing it by 2^|supp(f)|. To get the "real" APL, multiply by 2^|supp(f)|. This procedure assumes that Weight field of all nodes has been set to 0.0 before the call, except for the weight of the topmost node, which is set to 1.0 (1.0 is the probability of traversing the topmost node). This procedure assigns the edge weights. Because of the equal probability of selecting 0 and 1 assignment at a node, the edge weights are the same for the node. Instead of storing them, we store the weight of the node, which is the probability of traversing the node (pUnit->Weight) during the top down evalation of the BDD. ]

SideEffects []

SeeAlso []

Definition at line 78 of file reoProfile.c.

79 {
80  reo_unit * pER, * pTR;
81  reo_unit * pUnit;
82  double Res, Half;
83  int i;
84 
85  // clean the weights of all nodes
86  for ( i = 0; i < p->nSupp; i++ )
87  for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next )
88  pUnit->Weight = 0.0;
89  // to assign the node weights (the probability of visiting each node)
90  // we visit the node after visiting its predecessors
91 
92  // set the probability of visits to the top nodes
93  for ( i = 0; i < p->nTops; i++ )
94  Unit_Regular(p->pTops[i])->Weight += 1.0;
95 
96  // to compute the path length (the sum of products of edge weight by edge length)
97  // we visit the nodes in any order (the above order will do)
98  Res = 0.0;
99  for ( i = 0; i < p->nSupp; i++ )
100  {
101  p->pPlanes[i].statsCost = 0.0;
102  for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next )
103  {
104  pER = Unit_Regular(pUnit->pE);
105  pTR = Unit_Regular(pUnit->pT);
106  Half = 0.5 * pUnit->Weight;
107  pER->Weight += Half;
108  pTR->Weight += Half;
109  // add to the path length
110  p->pPlanes[i].statsCost += pUnit->Weight;
111  }
112  Res += p->pPlanes[i].statsCost;
113  }
114  p->pPlanes[p->nSupp].statsCost = 0.0;
115  p->nAplBeg = p->nAplCur = Res;
116 }
double Weight
Definition: reo.h:77
double nAplCur
Definition: reo.h:132
int nTops
Definition: reo.h:145
int nSupp
Definition: reo.h:119
double nAplBeg
Definition: reo.h:133
reo_unit * pT
Definition: reo.h:75
reo_unit * Next
Definition: reo.h:76
reo_unit * pE
Definition: reo.h:74
double statsCost
Definition: reo.h:86
reo_unit ** pTops
Definition: reo.h:144
#define Unit_Regular(u)
Definition: reo.h:174
reo_plane * pPlanes
Definition: reo.h:142
Definition: reo.h:66
reo_unit * pHead
Definition: reo.h:90
void reoProfileNodesPrint ( reo_man p)

Function********************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 289 of file reoProfile.c.

290 {
291  printf( "NODES: Total = %6d. Average = %6.2f.\n", p->nNodesCur, p->nNodesCur / (float)p->nSupp );
292 }
int nNodesCur
Definition: reo.h:127
int nSupp
Definition: reo.h:119
void reoProfileNodesStart ( reo_man p)

DECLARATIONS ///.

CFile****************************************************************

FileName [reoProfile.c]

PackageName [REO: A specialized DD reordering engine.]

Synopsis [Procudures that compute variables profiles (nodes, width, APL).]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - October 15, 2002.]

Revision [

Id:
reoProfile.c,v 1.0 2002/15/10 03:00:00 alanmi Exp

]FUNCTION DEFINITIONS /// Function********************************************************************

Synopsis [Start the profile for the BDD nodes.]

Description [TopRef is the first level, on this the given node counts towards the width of the BDDs. (In other words, it is the level of the referencing node plus 1.)]

SideEffects []

SeeAlso []

Definition at line 46 of file reoProfile.c.

47 {
48  int Total, i;
49  Total = 0;
50  for ( i = 0; i <= p->nSupp; i++ )
51  {
52  p->pPlanes[i].statsCost = p->pPlanes[i].statsNodes;
53  Total += p->pPlanes[i].statsNodes;
54  }
55  assert( Total == p->nNodesCur );
56  p->nNodesBeg = p->nNodesCur;
57 }
int nNodesCur
Definition: reo.h:127
int nSupp
Definition: reo.h:119
int nNodesBeg
Definition: reo.h:126
double statsCost
Definition: reo.h:86
reo_plane * pPlanes
Definition: reo.h:142
#define assert(ex)
Definition: util_old.h:213
int statsNodes
Definition: reo.h:83
void reoProfileWidthPrint ( reo_man p)

Function********************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 321 of file reoProfile.c.

322 {
323  int WidthMax;
324  int TotalWidth;
325  int i;
326 
327  WidthMax = 0;
328  TotalWidth = 0;
329  for ( i = 0; i <= p->nSupp; i++ )
330  {
331  printf( "Level = %2d. Width = %3d.\n", i, p->pPlanes[i].statsWidth );
332  if ( WidthMax < p->pPlanes[i].statsWidth )
333  WidthMax = p->pPlanes[i].statsWidth;
334  TotalWidth += p->pPlanes[i].statsWidth;
335  }
336  assert( p->nWidthCur == TotalWidth );
337  printf( "WIDTH: " );
338  printf( "Maximum = %5d. ", WidthMax );
339  printf( "Total = %7d. ", p->nWidthCur );
340  printf( "Average = %6.2f.\n", TotalWidth / (float)p->nSupp );
341 }
int nSupp
Definition: reo.h:119
int statsWidth
Definition: reo.h:84
reo_plane * pPlanes
Definition: reo.h:142
#define assert(ex)
Definition: util_old.h:213
int nWidthCur
Definition: reo.h:129
void reoProfileWidthStart ( reo_man p)

Function********************************************************************

Synopsis [Start the profile for the BDD width. Complexity of the algorithm is O(N + n).]

Description [TopRef is the first level, on which the given node counts towards the width of the BDDs. (In other words, it is the level of the referencing node plus 1.)]

SideEffects []

SeeAlso []

Definition at line 130 of file reoProfile.c.

131 {
132  reo_unit * pUnit;
133  int * pWidthStart;
134  int * pWidthStop;
135  int v;
136 
137  // allocate and clean the storage for starting and stopping levels
138  pWidthStart = ABC_ALLOC( int, p->nSupp + 1 );
139  pWidthStop = ABC_ALLOC( int, p->nSupp + 1 );
140  memset( pWidthStart, 0, sizeof(int) * (p->nSupp + 1) );
141  memset( pWidthStop, 0, sizeof(int) * (p->nSupp + 1) );
142 
143  // go through the non-constant nodes and set the topmost level of their cofactors
144  for ( v = 0; v <= p->nSupp; v++ )
145  for ( pUnit = p->pPlanes[v].pHead; pUnit; pUnit = pUnit->Next )
146  {
147  pUnit->TopRef = REO_TOPREF_UNDEF;
148  pUnit->Sign = 0;
149  }
150 
151  // add the topmost level of the width profile
152  for ( v = 0; v < p->nTops; v++ )
153  {
154  pUnit = Unit_Regular(p->pTops[v]);
155  if ( pUnit->TopRef == REO_TOPREF_UNDEF )
156  {
157  // set the starting level
158  pUnit->TopRef = 0;
159  pWidthStart[pUnit->TopRef]++;
160  // set the stopping level
161  if ( pUnit->lev != REO_CONST_LEVEL )
162  pWidthStop[pUnit->lev+1]++;
163  }
164  }
165 
166  for ( v = 0; v < p->nSupp; v++ )
167  for ( pUnit = p->pPlanes[v].pHead; pUnit; pUnit = pUnit->Next )
168  {
169  if ( pUnit->pE->TopRef == REO_TOPREF_UNDEF )
170  {
171  // set the starting level
172  pUnit->pE->TopRef = pUnit->lev + 1;
173  pWidthStart[pUnit->pE->TopRef]++;
174  // set the stopping level
175  if ( pUnit->pE->lev != REO_CONST_LEVEL )
176  pWidthStop[pUnit->pE->lev+1]++;
177  }
178  if ( pUnit->pT->TopRef == REO_TOPREF_UNDEF )
179  {
180  // set the starting level
181  pUnit->pT->TopRef = pUnit->lev + 1;
182  pWidthStart[pUnit->pT->TopRef]++;
183  // set the stopping level
184  if ( pUnit->pT->lev != REO_CONST_LEVEL )
185  pWidthStop[pUnit->pT->lev+1]++;
186  }
187  }
188 
189  // verify the top reference
190  for ( v = 0; v < p->nSupp; v++ )
191  reoProfileWidthVerifyLevel( p->pPlanes + v, v );
192 
193  // derive the profile
194  p->nWidthCur = 0;
195  for ( v = 0; v <= p->nSupp; v++ )
196  {
197  if ( v == 0 )
198  p->pPlanes[v].statsWidth = pWidthStart[v] - pWidthStop[v];
199  else
200  p->pPlanes[v].statsWidth = p->pPlanes[v-1].statsWidth + pWidthStart[v] - pWidthStop[v];
201  p->pPlanes[v].statsCost = p->pPlanes[v].statsWidth;
202  p->nWidthCur += p->pPlanes[v].statsWidth;
203  printf( "Level %2d: Width = %5d.\n", v, p->pPlanes[v].statsWidth );
204  }
205  p->nWidthBeg = p->nWidthCur;
206  ABC_FREE( pWidthStart );
207  ABC_FREE( pWidthStop );
208 }
char * memset()
int nWidthBeg
Definition: reo.h:130
short lev
Definition: reo.h:68
int nTops
Definition: reo.h:145
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int nSupp
Definition: reo.h:119
int statsWidth
Definition: reo.h:84
#define REO_TOPREF_UNDEF
Definition: reo.h:41
reo_unit * pT
Definition: reo.h:75
reo_unit * Next
Definition: reo.h:76
short TopRef
Definition: reo.h:69
reo_unit * pE
Definition: reo.h:74
double statsCost
Definition: reo.h:86
reo_unit ** pTops
Definition: reo.h:144
#define Unit_Regular(u)
Definition: reo.h:174
int Sign
Definition: reo.h:72
reo_plane * pPlanes
Definition: reo.h:142
void reoProfileWidthVerifyLevel(reo_plane *pPlane, int Level)
Definition: reoProfile.c:354
#define ABC_FREE(obj)
Definition: abc_global.h:232
Definition: reo.h:66
reo_unit * pHead
Definition: reo.h:90
#define REO_CONST_LEVEL
Definition: reo.h:40
int nWidthCur
Definition: reo.h:129
void reoProfileWidthStart2 ( reo_man p)

Function********************************************************************

Synopsis [Start the profile for the BDD width. Complexity of the algorithm is O(N * n).]

Description [TopRef is the first level, on which the given node counts towards the width of the BDDs. (In other words, it is the level of the referencing node plus 1.)]

SideEffects []

SeeAlso []

Definition at line 222 of file reoProfile.c.

223 {
224  reo_unit * pUnit;
225  int i, v;
226 
227  // clean the profile
228  for ( i = 0; i <= p->nSupp; i++ )
229  p->pPlanes[i].statsWidth = 0;
230 
231  // clean the node structures
232  for ( v = 0; v <= p->nSupp; v++ )
233  for ( pUnit = p->pPlanes[v].pHead; pUnit; pUnit = pUnit->Next )
234  {
235  pUnit->TopRef = REO_TOPREF_UNDEF;
236  pUnit->Sign = 0;
237  }
238 
239  // set the topref to the topmost nodes
240  for ( i = 0; i < p->nTops; i++ )
241  Unit_Regular(p->pTops[i])->TopRef = 0;
242 
243  // go through the non-constant nodes and set the topmost level of their cofactors
244  for ( i = 0; i < p->nSupp; i++ )
245  for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next )
246  {
247  if ( pUnit->pE->TopRef > i+1 )
248  pUnit->pE->TopRef = i+1;
249  if ( pUnit->pT->TopRef > i+1 )
250  pUnit->pT->TopRef = i+1;
251  }
252 
253  // verify the top reference
254  for ( i = 0; i < p->nSupp; i++ )
255  reoProfileWidthVerifyLevel( p->pPlanes + i, i );
256 
257  // compute the profile for the internal nodes
258  for ( i = 0; i < p->nSupp; i++ )
259  for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next )
260  for ( v = pUnit->TopRef; v <= pUnit->lev; v++ )
261  p->pPlanes[v].statsWidth++;
262 
263  // compute the profile for the constant nodes
264  for ( pUnit = p->pPlanes[p->nSupp].pHead; pUnit; pUnit = pUnit->Next )
265  for ( v = pUnit->TopRef; v <= p->nSupp; v++ )
266  p->pPlanes[v].statsWidth++;
267 
268  // get the width cost
269  p->nWidthCur = 0;
270  for ( i = 0; i <= p->nSupp; i++ )
271  {
272  p->pPlanes[i].statsCost = p->pPlanes[i].statsWidth;
273  p->nWidthCur += p->pPlanes[i].statsWidth;
274  }
275  p->nWidthBeg = p->nWidthCur;
276 }
int nWidthBeg
Definition: reo.h:130
int nTops
Definition: reo.h:145
int nSupp
Definition: reo.h:119
int statsWidth
Definition: reo.h:84
for(p=first;p->value< newval;p=p->next)
#define REO_TOPREF_UNDEF
Definition: reo.h:41
reo_unit * pT
Definition: reo.h:75
reo_unit * Next
Definition: reo.h:76
short TopRef
Definition: reo.h:69
reo_unit * pE
Definition: reo.h:74
double statsCost
Definition: reo.h:86
reo_unit ** pTops
Definition: reo.h:144
#define Unit_Regular(u)
Definition: reo.h:174
int Sign
Definition: reo.h:72
reo_plane * pPlanes
Definition: reo.h:142
void reoProfileWidthVerifyLevel(reo_plane *pPlane, int Level)
Definition: reoProfile.c:354
Definition: reo.h:66
reo_unit * pHead
Definition: reo.h:90
int nWidthCur
Definition: reo.h:129
void reoProfileWidthVerifyLevel ( reo_plane pPlane,
int  Level 
)

Function********************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 354 of file reoProfile.c.

355 {
356  reo_unit * pUnit;
357  for ( pUnit = pPlane->pHead; pUnit; pUnit = pUnit->Next )
358  {
359  assert( pUnit->TopRef <= Level );
360  assert( pUnit->pE->TopRef <= Level + 1 );
361  assert( pUnit->pT->TopRef <= Level + 1 );
362  }
363 }
reo_unit * pT
Definition: reo.h:75
reo_unit * Next
Definition: reo.h:76
short TopRef
Definition: reo.h:69
reo_unit * pE
Definition: reo.h:74
Definition: reo.h:66
#define assert(ex)
Definition: util_old.h:213
reo_unit * pHead
Definition: reo.h:90
void reoReorderArray ( reo_man p,
DdManager dd,
DdNode Funcs[],
DdNode FuncsRes[],
int  nFuncs,
int *  pOrder 
)

FUNCTION DEFINITIONS ///.

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 50 of file reoCore.c.

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 }
int fMinApl
Definition: reo.h:105
int fVerbose
Definition: reo.h:106
int nWidthBeg
Definition: reo.h:130
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void reoProfileAplStart(reo_man *p)
Definition: reoProfile.c:78
static int reoCheckZeroRefs(reo_plane *pPlane)
Definition: reoCore.c:394
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
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 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
int * pMapToDdVarsFinal
Definition: reo.h:139
int fRemapUp
Definition: reo.h:108
DdNode * Cudd_addPermute(DdManager *manager, DdNode *node, int *permut)
Definition: cuddCompose.c:242
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
int nIters
Definition: reo.h:109
int nNodesBeg
Definition: reo.h:126
static ABC_NAMESPACE_IMPL_START int reoRecursiveDeref(reo_unit *pUnit)
DECLARATIONS ///.
Definition: reoCore.c:368
double s_AplAfter
Definition: reoCore.c:33
#define ddMax(x, y)
Definition: cuddInt.h:832
if(last==0)
Definition: sparse_int.h:34
static int Counter
reo_unit ** pTops
Definition: reo.h:144
void reoProfileAplPrint(reo_man *p)
Definition: reoProfile.c:305
void reoReorderSift(reo_man *p)
DECLARATIONS ///.
Definition: reoSift.c:44
int * pSupp
Definition: reo.h:117
int * pMapToDdVarsOrig
Definition: reo.h:138
reo_plane * pPlanes
Definition: reo.h:142
int nSwaps
Definition: reo.h:169
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
int nWidthEnd
Definition: reo.h:131
void reoProfileNodesPrint(reo_man *p)
Definition: reoProfile.c:289
#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
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
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
void reoReorderSift ( reo_man p)

DECLARATIONS ///.

CFile****************************************************************

FileName [reoSift.c]

PackageName [REO: A specialized DD reordering engine.]

Synopsis [Implementation of the sifting algorihtm.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - October 15, 2002.]

Revision [

Id:
reoSift.c,v 1.0 2002/15/10 03:00:00 alanmi Exp

]FUNCTION DEFINITIONS /// Function*************************************************************

Synopsis [Implements the variable sifting algorithm.]

Description [Performs a sequence of adjacent variable swaps known as "sifting". Uses the cost functions determined by the flag.]

SideEffects []

SeeAlso []

Definition at line 44 of file reoSift.c.

45 {
46  double CostCurrent; // the cost of the current permutation
47  double CostLimit; // the maximum increase in cost that can be tolerated
48  double CostBest; // the best cost
49  int BestQ; // the best position
50  int VarCurrent; // the current variable to move
51  int q; // denotes the current position of the variable
52  int c; // performs the loops over variables until all of them are sifted
53  int v; // used for other purposes
54 
55  assert( p->nSupp > 0 );
56 
57  // set the current cost depending on the minimization criteria
58  if ( p->fMinWidth )
59  CostCurrent = p->nWidthCur;
60  else if ( p->fMinApl )
61  CostCurrent = p->nAplCur;
62  else
63  CostCurrent = p->nNodesCur;
64 
65  // find the upper bound on tbe cost growth
66  CostLimit = 1 + (int)(REO_REORDER_LIMIT * CostCurrent);
67 
68  // perform sifting for each of p->nSupp variables
69  for ( c = 0; c < p->nSupp; c++ )
70  {
71  // select the current variable to be the one with the largest number of nodes that is not sifted yet
72  VarCurrent = -1;
73  CostBest = -1.0;
74  for ( v = 0; v < p->nSupp; v++ )
75  {
76  p->pVarCosts[v] = REO_HIGH_VALUE;
77  if ( !p->pPlanes[v].fSifted )
78  {
79 // VarCurrent = v;
80 // if ( CostBest < p->pPlanes[v].statsCost )
81  if ( CostBest < p->pPlanes[v].statsNodes )
82  {
83 // CostBest = p->pPlanes[v].statsCost;
84  CostBest = p->pPlanes[v].statsNodes;
85  VarCurrent = v;
86  }
87 
88  }
89  }
90  assert( VarCurrent != -1 );
91  // mark this variable as sifted
92  p->pPlanes[VarCurrent].fSifted = 1;
93 
94  // set the current value
95  p->pVarCosts[VarCurrent] = CostCurrent;
96 
97  // set the best cost
98  CostBest = CostCurrent;
99  BestQ = VarCurrent;
100 
101  // determine which way to move the variable first (up or down)
102  // the rationale is that if we move the shorter way first
103  // it is more likely that the best position will be found on the longer way
104  // and the reverse movement (to take the best position) will be faster
105  if ( VarCurrent < p->nSupp/2 ) // move up first, then down
106  {
107  // set the total cost on all levels above the current level
108  p->pPlanes[0].statsCostAbove = 0;
109  for ( v = 1; v <= VarCurrent; v++ )
110  p->pPlanes[v].statsCostAbove = p->pPlanes[v-1].statsCostAbove + p->pPlanes[v-1].statsCost;
111  // set the total cost on all levels below the current level
112  p->pPlanes[p->nSupp].statsCostBelow = 0;
113  for ( v = p->nSupp - 1; v >= VarCurrent; v-- )
114  p->pPlanes[v].statsCostBelow = p->pPlanes[v+1].statsCostBelow + p->pPlanes[v+1].statsCost;
115 
116  assert( CostCurrent == p->pPlanes[VarCurrent].statsCostAbove +
117  p->pPlanes[VarCurrent].statsCost +
118  p->pPlanes[VarCurrent].statsCostBelow );
119 
120  // move up
121  for ( q = VarCurrent-1; q >= 0; q-- )
122  {
123  CostCurrent -= reoReorderSwapAdjacentVars( p, q, 1 );
124  // now q points to the position of this var in the order
125  p->pVarCosts[q] = CostCurrent;
126  // update the lower bound (assuming that for level q+1 it is set correctly)
127  p->pPlanes[q].statsCostBelow = p->pPlanes[q+1].statsCostBelow + p->pPlanes[q+1].statsCost;
128  // check the upper bound
129  if ( CostCurrent >= CostLimit )
130  break;
131  // check the lower bound
132  if ( p->pPlanes[q].statsCostBelow + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostAbove/REO_QUAL_PAR >= CostBest )
133  break;
134  // update the best cost
135  if ( CostBest > CostCurrent )
136  {
137  CostBest = CostCurrent;
138  BestQ = q;
139  // adjust node limit
140  CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
141  }
142 
143  // when we are reordering for width or APL, it may happen that
144  // the number of nodes has grown above certain limit,
145  // in which case we have to resize the data structures
146  if ( p->fMinWidth || p->fMinApl )
147  {
148  if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
149  {
150 // printf( "Resizing data structures. Old size = %6d. New size = %6d.\n", p->nNodesMaxAlloc, p->nNodesCur );
151  reoResizeStructures( p, 0, p->nNodesCur, 0 );
152  }
153  }
154  }
155  // fix the plane index
156  if ( q == -1 )
157  q++;
158  // now p points to the position of this var in the order
159 
160  // move down
161  for ( ; q < p->nSupp-1; )
162  {
163  CostCurrent -= reoReorderSwapAdjacentVars( p, q, 0 );
164  q++; // change q to point to the position of this var in the order
165  // sanity check: the number of nodes on the back pass should be the same
166  if ( p->pVarCosts[q] != REO_HIGH_VALUE && fabs( p->pVarCosts[q] - CostCurrent ) > REO_COST_EPSILON )
167  printf("reoReorderSift(): Error! On the backward move, the costs are different.\n");
168  p->pVarCosts[q] = CostCurrent;
169  // update the lower bound (assuming that for level q-1 it is set correctly)
170  p->pPlanes[q].statsCostAbove = p->pPlanes[q-1].statsCostAbove + p->pPlanes[q-1].statsCost;
171  // check the bounds only if the variable already reached its previous position
172  if ( q >= BestQ )
173  {
174  // check the upper bound
175  if ( CostCurrent >= CostLimit )
176  break;
177  // check the lower bound
178  if ( p->pPlanes[q].statsCostAbove + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostBelow/REO_QUAL_PAR >= CostBest )
179  break;
180  }
181  // update the best cost
182  if ( CostBest >= CostCurrent )
183  {
184  CostBest = CostCurrent;
185  BestQ = q;
186  // adjust node limit
187  CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
188  }
189 
190  // when we are reordering for width or APL, it may happen that
191  // the number of nodes has grown above certain limit,
192  // in which case we have to resize the data structures
193  if ( p->fMinWidth || p->fMinApl )
194  {
195  if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
196  {
197 // printf( "Resizing data structures. Old size = %6d. New size = %6d.\n", p->nNodesMaxAlloc, p->nNodesCur );
198  reoResizeStructures( p, 0, p->nNodesCur, 0 );
199  }
200  }
201  }
202  // move the variable up from the given position (q) to the best position (BestQ)
203  assert( q >= BestQ );
204  for ( ; q > BestQ; q-- )
205  {
206  CostCurrent -= reoReorderSwapAdjacentVars( p, q-1, 1 );
207  // sanity check: the number of nodes on the back pass should be the same
208  if ( fabs( p->pVarCosts[q-1] - CostCurrent ) > REO_COST_EPSILON )
209  {
210  printf("reoReorderSift(): Error! On the return move, the costs are different.\n" );
211  fflush(stdout);
212  }
213  }
214  }
215  else // move down first, then up
216  {
217  // set the current number of nodes on all levels above the given level
218  p->pPlanes[0].statsCostAbove = 0;
219  for ( v = 1; v <= VarCurrent; v++ )
220  p->pPlanes[v].statsCostAbove = p->pPlanes[v-1].statsCostAbove + p->pPlanes[v-1].statsCost;
221  // set the current number of nodes on all levels below the given level
222  p->pPlanes[p->nSupp].statsCostBelow = 0;
223  for ( v = p->nSupp - 1; v >= VarCurrent; v-- )
224  p->pPlanes[v].statsCostBelow = p->pPlanes[v+1].statsCostBelow + p->pPlanes[v+1].statsCost;
225 
226  assert( CostCurrent == p->pPlanes[VarCurrent].statsCostAbove +
227  p->pPlanes[VarCurrent].statsCost +
228  p->pPlanes[VarCurrent].statsCostBelow );
229 
230  // move down
231  for ( q = VarCurrent; q < p->nSupp-1; )
232  {
233  CostCurrent -= reoReorderSwapAdjacentVars( p, q, 0 );
234  q++; // change q to point to the position of this var in the order
235  p->pVarCosts[q] = CostCurrent;
236  // update the lower bound (assuming that for level q-1 it is set correctly)
237  p->pPlanes[q].statsCostAbove = p->pPlanes[q-1].statsCostAbove + p->pPlanes[q-1].statsCost;
238  // check the upper bound
239  if ( CostCurrent >= CostLimit )
240  break;
241  // check the lower bound
242  if ( p->pPlanes[q].statsCostAbove + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostBelow/REO_QUAL_PAR >= CostBest )
243  break;
244  // update the best cost
245  if ( CostBest > CostCurrent )
246  {
247  CostBest = CostCurrent;
248  BestQ = q;
249  // adjust node limit
250  CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
251  }
252 
253  // when we are reordering for width or APL, it may happen that
254  // the number of nodes has grown above certain limit,
255  // in which case we have to resize the data structures
256  if ( p->fMinWidth || p->fMinApl )
257  {
258  if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
259  {
260 // printf( "Resizing data structures. Old size = %6d. New size = %6d.\n", p->nNodesMaxAlloc, p->nNodesCur );
261  reoResizeStructures( p, 0, p->nNodesCur, 0 );
262  }
263  }
264  }
265 
266  // move up
267  for ( --q; q >= 0; q-- )
268  {
269  CostCurrent -= reoReorderSwapAdjacentVars( p, q, 1 );
270  // now q points to the position of this var in the order
271  // sanity check: the number of nodes on the back pass should be the same
272  if ( p->pVarCosts[q] != REO_HIGH_VALUE && fabs( p->pVarCosts[q] - CostCurrent ) > REO_COST_EPSILON )
273  printf("reoReorderSift(): Error! On the backward move, the costs are different.\n");
274  p->pVarCosts[q] = CostCurrent;
275  // update the lower bound (assuming that for level q+1 it is set correctly)
276  p->pPlanes[q].statsCostBelow = p->pPlanes[q+1].statsCostBelow + p->pPlanes[q+1].statsCost;
277  // check the bounds only if the variable already reached its previous position
278  if ( q <= BestQ )
279  {
280  // check the upper bound
281  if ( CostCurrent >= CostLimit )
282  break;
283  // check the lower bound
284  if ( p->pPlanes[q].statsCostBelow + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostAbove/REO_QUAL_PAR >= CostBest )
285  break;
286  }
287  // update the best cost
288  if ( CostBest >= CostCurrent )
289  {
290  CostBest = CostCurrent;
291  BestQ = q;
292  // adjust node limit
293  CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
294  }
295 
296  // when we are reordering for width or APL, it may happen that
297  // the number of nodes has grown above certain limit,
298  // in which case we have to resize the data structures
299  if ( p->fMinWidth || p->fMinApl )
300  {
301  if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
302  {
303 // printf( "Resizing data structures. Old size = %6d. New size = %6d.\n", p->nNodesMaxAlloc, p->nNodesCur );
304  reoResizeStructures( p, 0, p->nNodesCur, 0 );
305  }
306  }
307  }
308  // fix the plane index
309  if ( q == -1 )
310  q++;
311  // now q points to the position of this var in the order
312  // move the variable down from the given position (q) to the best position (BestQ)
313  assert( q <= BestQ );
314  for ( ; q < BestQ; q++ )
315  {
316  CostCurrent -= reoReorderSwapAdjacentVars( p, q, 0 );
317  // sanity check: the number of nodes on the back pass should be the same
318  if ( fabs( p->pVarCosts[q+1] - CostCurrent ) > REO_COST_EPSILON )
319  {
320  printf("reoReorderSift(): Error! On the return move, the costs are different.\n" );
321  fflush(stdout);
322  }
323  }
324  }
325  assert( fabs( CostBest - CostCurrent ) < REO_COST_EPSILON );
326 
327  // update the cost
328  if ( p->fMinWidth )
329  p->nWidthCur = (int)CostBest;
330  else if ( p->fMinApl )
331  p->nAplCur = CostCurrent;
332  else
333  p->nNodesCur = (int)CostBest;
334  }
335 
336  // remove the sifted attributes if any
337  for ( v = 0; v < p->nSupp; v++ )
338  p->pPlanes[v].fSifted = 0;
339 }
int fMinApl
Definition: reo.h:105
double * pVarCosts
Definition: reo.h:121
double nAplCur
Definition: reo.h:132
int nNodesCur
Definition: reo.h:127
double statsCostBelow
Definition: reo.h:88
int nNodesMaxAlloc
Definition: reo.h:154
int nSupp
Definition: reo.h:119
for(p=first;p->value< newval;p=p->next)
double statsCostAbove
Definition: reo.h:87
#define REO_HIGH_VALUE
Definition: reo.h:44
int fMinWidth
Definition: reo.h:104
void reoResizeStructures(reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
Definition: reoCore.c:269
double statsCost
Definition: reo.h:86
#define ddMin(x, y)
Definition: cuddInt.h:818
double reoReorderSwapAdjacentVars(reo_man *p, int Level, int fMovingUp)
FUNCTION DEFINITIONS ///.
Definition: reoSwap.c:46
reo_plane * pPlanes
Definition: reo.h:142
#define REO_QUAL_PAR
Definition: reo.h:38
#define assert(ex)
Definition: util_old.h:213
#define REO_COST_EPSILON
Definition: reo.h:43
int statsNodes
Definition: reo.h:83
#define REO_REORDER_LIMIT
MACRO DEFINITIONS ///.
Definition: reo.h:37
int fSifted
Definition: reo.h:82
int nWidthCur
Definition: reo.h:129
double reoReorderSwapAdjacentVars ( reo_man p,
int  lev0,
int  fMovingUp 
)

FUNCTION DEFINITIONS ///.

Function*************************************************************

Synopsis []

Description [Takes the level (lev0) of the plane, which should be swapped with the next plane. Returns the gain using the current cost function.]

SideEffects []

SeeAlso []

Definition at line 46 of file reoSwap.c.

47 {
48  // the levels in the decision diagram
49  int lev1 = lev0 + 1, lev2 = lev0 + 2;
50  // the new nodes on lev0
51  reo_unit * pLoop, * pUnit;
52  // the new nodes on lev1
53  reo_unit * pNewPlane20 = NULL, * pNewPlane21 = NULL; // Suppress "might be used uninitialized"
54  reo_unit * pNewPlane20R;
55  reo_unit * pUnitE, * pUnitER, * pUnitT;
56  // the nodes below lev1
57  reo_unit * pNew1E, * pNew1T, * pNew2E, * pNew2T;
58  reo_unit * pNew1ER, * pNew2ER;
59  // the old linked lists
60  reo_unit * pListOld0 = p->pPlanes[lev0].pHead;
61  reo_unit * pListOld1 = p->pPlanes[lev1].pHead;
62  // working planes and one more temporary plane
63  reo_unit * pListNew0 = NULL, ** ppListNew0 = &pListNew0;
64  reo_unit * pListNew1 = NULL, ** ppListNew1 = &pListNew1;
65  reo_unit * pListTemp = NULL, ** ppListTemp = &pListTemp;
66  // various integer variables
67  int fComp, fCompT, fFound, HKey, fInteract, temp, c;
68  int nWidthCofs = -1; // Suppress "might be used uninitialized"
69  // statistical variables
70  int nNodesUpMovedDown = 0;
71  int nNodesDownMovedUp = 0;
72  int nNodesUnrefRemoved = 0;
73  int nNodesUnrefAdded = 0;
74  int nWidthReduction = 0;
75  double AplWeightTotalLev0 = 0.0; // Suppress "might be used uninitialized"
76  double AplWeightTotalLev1 = 0.0; // Suppress "might be used uninitialized"
77  double AplWeightHalf = 0.0; // Suppress "might be used uninitialized"
78  double AplWeightPrev = 0.0; // Suppress "might be used uninitialized"
79  double AplWeightAfter = 0.0; // Suppress "might be used uninitialized"
80  double nCostGain;
81 
82  // set the old lists
83  assert( lev0 >= 0 && lev1 < p->nSupp );
84  pListOld0 = p->pPlanes[lev0].pHead;
85  pListOld1 = p->pPlanes[lev1].pHead;
86 
87  // make sure the planes have nodes
88  assert( p->pPlanes[lev0].statsNodes && p->pPlanes[lev1].statsNodes );
89  assert( pListOld0 && pListOld1 );
90 
91  if ( p->fMinWidth )
92  {
93  // verify that the width parameters are set correctly
94  reoProfileWidthVerifyLevel( p->pPlanes + lev0, lev0 );
95  reoProfileWidthVerifyLevel( p->pPlanes + lev1, lev1 );
96  // start the storage for cofactors
97  nWidthCofs = 0;
98  }
99  else if ( p->fMinApl )
100  {
101  AplWeightPrev = p->nAplCur;
102  AplWeightAfter = p->nAplCur;
103  AplWeightTotalLev0 = 0.0;
104  AplWeightTotalLev1 = 0.0;
105  }
106 
107  // check if the planes interact
108  fInteract = 0; // assume that they do not interact
109  for ( pUnit = pListOld0; pUnit; pUnit = pUnit->Next )
110  {
111  if ( pUnit->pT->lev == lev1 || Unit_Regular(pUnit->pE)->lev == lev1 )
112  {
113  fInteract = 1;
114  break;
115  }
116  // change the level now, this is done for efficiency reasons
117  pUnit->lev = lev1;
118  }
119 
120  // set the new signature for hashing
121  p->nSwaps++;
122  if ( !fInteract )
123 // if ( 0 )
124  {
125  // perform the swap without interaction
126  p->nNISwaps++;
127 
128  // change the levels
129  if ( p->fMinWidth )
130  {
131  // go through the current lower level, which will become upper
132  for ( pUnit = pListOld1; pUnit; pUnit = pUnit->Next )
133  {
134  pUnit->lev = lev0;
135 
136  pUnitER = Unit_Regular(pUnit->pE);
137  if ( pUnitER->TopRef > lev0 )
138  {
139  if ( pUnitER->Sign != p->nSwaps )
140  {
141  if ( pUnitER->TopRef == lev2 )
142  {
143  pUnitER->TopRef = lev1;
144  nWidthReduction--;
145  }
146  else
147  {
148  assert( pUnitER->TopRef == lev1 );
149  }
150  pUnitER->Sign = p->nSwaps;
151  }
152  }
153 
154  pUnitT = pUnit->pT;
155  if ( pUnitT->TopRef > lev0 )
156  {
157  if ( pUnitT->Sign != p->nSwaps )
158  {
159  if ( pUnitT->TopRef == lev2 )
160  {
161  pUnitT->TopRef = lev1;
162  nWidthReduction--;
163  }
164  else
165  {
166  assert( pUnitT->TopRef == lev1 );
167  }
168  pUnitT->Sign = p->nSwaps;
169  }
170  }
171 
172  }
173 
174  // go through the current upper level, which will become lower
175  for ( pUnit = pListOld0; pUnit; pUnit = pUnit->Next )
176  {
177  pUnit->lev = lev1;
178 
179  pUnitER = Unit_Regular(pUnit->pE);
180  if ( pUnitER->TopRef > lev0 )
181  {
182  if ( pUnitER->Sign != p->nSwaps )
183  {
184  assert( pUnitER->TopRef == lev1 );
185  pUnitER->TopRef = lev2;
186  pUnitER->Sign = p->nSwaps;
187  nWidthReduction++;
188  }
189  }
190 
191  pUnitT = pUnit->pT;
192  if ( pUnitT->TopRef > lev0 )
193  {
194  if ( pUnitT->Sign != p->nSwaps )
195  {
196  assert( pUnitT->TopRef == lev1 );
197  pUnitT->TopRef = lev2;
198  pUnitT->Sign = p->nSwaps;
199  nWidthReduction++;
200  }
201  }
202  }
203  }
204  else
205  {
206 // for ( pUnit = pListOld0; pUnit; pUnit = pUnit->Next )
207 // pUnit->lev = lev1;
208  for ( pUnit = pListOld1; pUnit; pUnit = pUnit->Next )
209  pUnit->lev = lev0;
210  }
211 
212  // set the new linked lists, which will be attached to the planes
213  pListNew0 = pListOld1;
214  pListNew1 = pListOld0;
215 
216  if ( p->fMinApl )
217  {
218  AplWeightTotalLev0 = p->pPlanes[lev1].statsCost;
219  AplWeightTotalLev1 = p->pPlanes[lev0].statsCost;
220  }
221 
222  // set the changes in terms of nodes
223  nNodesUpMovedDown = p->pPlanes[lev0].statsNodes;
224  nNodesDownMovedUp = p->pPlanes[lev1].statsNodes;
225  goto finish;
226  }
227  p->Signature++;
228 
229 
230  // two-variable swap is done in three easy steps
231  // previously I thought that steps (1) and (2) can be merged into one step
232  // now it is clear that this cannot be done without changing a lot of other stuff...
233 
234  // (1) walk through the upper level, find units without cofactors in the lower level
235  // and move them to the new lower level (while adding to the cache)
236  // (2) walk through the uppoer level, and tranform all the remaning nodes
237  // while employing cache for the new lower level
238  // (3) walk through the old lower level, find those nodes whose ref counters are not zero,
239  // and move them to the new uppoer level, free other nodes
240 
241  // (1) walk through the upper level, find units without cofactors in the lower level
242  // and move them to the new lower level (while adding to the cache)
243  for ( pLoop = pListOld0; pLoop; )
244  {
245  pUnit = pLoop;
246  pLoop = pLoop->Next;
247 
248  pUnitE = pUnit->pE;
249  pUnitER = Unit_Regular(pUnitE);
250  pUnitT = pUnit->pT;
251 
252  if ( pUnitER->lev != lev1 && pUnitT->lev != lev1 )
253  {
254  // before after
255  //
256  // <p1> .
257  // 0 / \ 1 .
258  // / \ .
259  // / \ .
260  // / \ <p2n> .
261  // / \ 0 / \ 1 .
262  // / \ / \ .
263  // / \ / \ .
264  // F0 F1 F0 F1
265 
266  // move to plane-2-new
267  // nothing changes in the process (cofactors, ref counter, APL weight)
268  pUnit->lev = lev1;
269  AddToLinkedList( ppListNew1, pUnit );
270  if ( p->fMinApl )
271  AplWeightTotalLev1 += pUnit->Weight;
272 
273  // add to cache - find the cell with different signature (not the current one!)
274  for ( HKey = hashKey3(p->Signature, pUnitE, pUnitT, p->nTableSize);
275  p->HTable[HKey].Sign == p->Signature;
276  HKey = (HKey+1) % p->nTableSize );
277  assert( p->HTable[HKey].Sign != p->Signature );
278  p->HTable[HKey].Sign = p->Signature;
279  p->HTable[HKey].Arg1 = pUnitE;
280  p->HTable[HKey].Arg2 = pUnitT;
281  p->HTable[HKey].Arg3 = pUnit;
282 
283  nNodesUpMovedDown++;
284 
285  if ( p->fMinWidth )
286  {
287  // update the cofactors's top ref
288  if ( pUnitER->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
289  {
290  assert( pUnitER->TopRef == lev1 );
291  pUnitER->TopRefNew = lev2;
292  if ( pUnitER->Sign != p->nSwaps )
293  {
294  pUnitER->Sign = p->nSwaps; // set the current signature
295  p->pWidthCofs[ nWidthCofs++ ] = pUnitER;
296  }
297  }
298  if ( pUnitT->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
299  {
300  assert( pUnitT->TopRef == lev1 );
301  pUnitT->TopRefNew = lev2;
302  if ( pUnitT->Sign != p->nSwaps )
303  {
304  pUnitT->Sign = p->nSwaps; // set the current signature
305  p->pWidthCofs[ nWidthCofs++ ] = pUnitT;
306  }
307  }
308  }
309  }
310  else
311  {
312  // add to the temporary plane
313  AddToLinkedList( ppListTemp, pUnit );
314  }
315  }
316 
317 
318  // (2) walk through the uppoer level, and tranform all the remaning nodes
319  // while employing cache for the new lower level
320  for ( pLoop = pListTemp; pLoop; )
321  {
322  pUnit = pLoop;
323  pLoop = pLoop->Next;
324 
325  pUnitE = pUnit->pE;
326  pUnitER = Unit_Regular(pUnitE);
327  pUnitT = pUnit->pT;
328  fComp = (int)(pUnitER != pUnitE);
329 
330  // count the amount of weight to reduce the APL of the children of this node
331  if ( p->fMinApl )
332  AplWeightHalf = 0.5 * pUnit->Weight;
333 
334  // determine what situation is this
335  if ( pUnitER->lev == lev1 && pUnitT->lev == lev1 )
336  {
337  if ( fComp == 0 )
338  {
339  // before after
340  //
341  // <p1> <p1n> .
342  // 0 / \ 1 0 / \ 1 .
343  // / \ / \ .
344  // / \ / \ .
345  // <p2> <p2> <p2n> <p2n> .
346  // 0 / \ 1 0 / \ 1 0 / \ 1 0 / \ 1 .
347  // / \ / \ / \ / \ .
348  // / \ / \ / \ / \ .
349  // F0 F1 F2 F3 F0 F2 F1 F3 .
350  // pNew1E pNew1T pNew2E pNew2T
351  //
352  pNew1E = pUnitE->pE; // F0
353  pNew1T = pUnitT->pE; // F2
354 
355  pNew2E = pUnitE->pT; // F1
356  pNew2T = pUnitT->pT; // F3
357  }
358  else
359  {
360  // before after
361  //
362  // <p1> <p1n> .
363  // 0 . \ 1 0 / \ 1 .
364  // . \ / \ .
365  // . \ / \ .
366  // <p2> <p2> <p2n> <p2n> .
367  // 0 / \ 1 0 / \ 1 0 . \ 1 0 . \ 1 .
368  // / \ / \ . \ . \ .
369  // / \ / \ . \ . \ .
370  // F0 F1 F2 F3 F0 F2 F1 F3 .
371  // pNew1E pNew1T pNew2E pNew2T
372  //
373  pNew1E = Unit_Not(pUnitER->pE); // F0
374  pNew1T = pUnitT->pE; // F2
375 
376  pNew2E = Unit_Not(pUnitER->pT); // F1
377  pNew2T = pUnitT->pT; // F3
378  }
379  // subtract ref counters - on the level P2
380  pUnitER->n--;
381  pUnitT->n--;
382 
383  // mark the change in the APL weights
384  if ( p->fMinApl )
385  {
386  pUnitER->Weight -= AplWeightHalf;
387  pUnitT->Weight -= AplWeightHalf;
388  AplWeightAfter -= pUnit->Weight;
389  }
390  }
391  else if ( pUnitER->lev == lev1 )
392  {
393  if ( fComp == 0 )
394  {
395  // before after
396  //
397  // <p1> <p1n> .
398  // 0 / \ 1 0 / \ 1 .
399  // / \ / \ .
400  // / \ / \ .
401  // <p2> \ <p2n> <p2n> .
402  // 0 / \ 1 \ 0 / \ 1 0 / \ 1 .
403  // / \ \ / \ / \ .
404  // / \ \ / \ / \ .
405  // F0 F1 F3 F0 F3 F1 F3 .
406  // pNew1E pNew1T pNew2E pNew2T
407  //
408  pNew1E = pUnitER->pE; // F0
409  pNew1T = pUnitT; // F3
410 
411  pNew2E = pUnitER->pT; // F1
412  pNew2T = pUnitT; // F3
413  }
414  else
415  {
416  // before after
417  //
418  // <p1> <p1n> .
419  // 0 . \ 1 0 / \ 1 .
420  // . \ / \ .
421  // . \ / \ .
422  // <p2> \ <p2n> <p2n> .
423  // 0 / \ 1 \ 0 . \ 1 0 . \ 1 .
424  // / \ \ . \ . \ .
425  // / \ \ . \ . \ .
426  // F0 F1 F3 F0 F3 F1 F3 .
427  // pNew1E pNew1T pNew2E pNew2T
428  //
429  pNew1E = Unit_Not(pUnitER->pE); // F0
430  pNew1T = pUnitT; // F3
431 
432  pNew2E = Unit_Not(pUnitER->pT); // F1
433  pNew2T = pUnitT; // F3
434  }
435  // subtract ref counter - on the level P2
436  pUnitER->n--;
437  // subtract ref counter - on other levels
438  pUnitT->n--; ///
439 
440  // mark the change in the APL weights
441  if ( p->fMinApl )
442  {
443  pUnitER->Weight -= AplWeightHalf;
444  AplWeightAfter -= AplWeightHalf;
445  }
446  }
447  else if ( pUnitT->lev == lev1 )
448  {
449  // before after
450  //
451  // <p1> <p1n> .
452  // 0 / \ 1 0 / \ 1 .
453  // / \ / \ .
454  // / \ / \ .
455  // / <p2> <p2n> <p2n> .
456  // / 0 / \ 1 0 / \ 1 0 / \ 1 .
457  // / / \ / \ / \ .
458  // / / \ / \ / \ .
459  // F0 F2 F3 F0 F2 F0 F3 .
460  // pNew1E pNew1T pNew2E pNew2T
461  //
462  pNew1E = pUnitE; // F0
463  pNew1T = pUnitT->pE; // F2
464 
465  pNew2E = pUnitE; // F0
466  pNew2T = pUnitT->pT; // F3
467 
468  // subtract incoming edge counter - on the level P2
469  pUnitT->n--;
470  // subtract ref counter - on other levels
471  pUnitER->n--; ///
472 
473  // mark the change in the APL weights
474  if ( p->fMinApl )
475  {
476  pUnitT->Weight -= AplWeightHalf;
477  AplWeightAfter -= AplWeightHalf;
478  }
479  }
480  else
481  {
482  assert( 0 ); // should never happen
483  }
484 
485 
486  // consider all the cases except the last one
487  if ( pNew1E == pNew1T )
488  {
489  pNewPlane20 = pNew1T;
490 
491  if ( p->fMinWidth )
492  {
493  // update the cofactors's top ref
494  if ( pNew1T->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
495  {
496  pNew1T->TopRefNew = lev1;
497  if ( pNew1T->Sign != p->nSwaps )
498  {
499  pNew1T->Sign = p->nSwaps; // set the current signature
500  p->pWidthCofs[ nWidthCofs++ ] = pNew1T;
501  }
502  }
503  }
504  }
505  else
506  {
507  // pNew1T can be complemented
508  fCompT = Cudd_IsComplement(pNew1T);
509  if ( fCompT )
510  {
511  pNew1E = Unit_Not(pNew1E);
512  pNew1T = Unit_Not(pNew1T);
513  }
514 
515  // check the hash-table
516  fFound = 0;
517  for ( HKey = hashKey3(p->Signature, pNew1E, pNew1T, p->nTableSize);
518  p->HTable[HKey].Sign == p->Signature;
519  HKey = (HKey+1) % p->nTableSize )
520  if ( p->HTable[HKey].Arg1 == pNew1E && p->HTable[HKey].Arg2 == pNew1T )
521  { // the entry is present
522  // assign this entry
523  pNewPlane20 = p->HTable[HKey].Arg3;
524  assert( pNewPlane20->lev == lev1 );
525  fFound = 1;
526  p->HashSuccess++;
527  break;
528  }
529 
530  if ( !fFound )
531  { // create the new entry
532  pNewPlane20 = reoUnitsGetNextUnit( p ); // increments the unit counter
533  pNewPlane20->pE = pNew1E;
534  pNewPlane20->pT = pNew1T;
535  pNewPlane20->n = 0; // ref will be added later
536  pNewPlane20->lev = lev1;
537  if ( p->fMinWidth )
538  {
539  pNewPlane20->TopRef = lev1;
540  pNewPlane20->Sign = 0;
541  }
542  // set the weight of this node
543  if ( p->fMinApl )
544  pNewPlane20->Weight = 0.0;
545 
546  // increment ref counters of children
547  pNew1ER = Unit_Regular(pNew1E);
548  pNew1ER->n++; //
549  pNew1T->n++; //
550 
551  // insert into the data structure
552  AddToLinkedList( ppListNew1, pNewPlane20 );
553 
554  // add this entry to cache
555  assert( p->HTable[HKey].Sign != p->Signature );
556  p->HTable[HKey].Sign = p->Signature;
557  p->HTable[HKey].Arg1 = pNew1E;
558  p->HTable[HKey].Arg2 = pNew1T;
559  p->HTable[HKey].Arg3 = pNewPlane20;
560 
561  nNodesUnrefAdded++;
562 
563  if ( p->fMinWidth )
564  {
565  // update the cofactors's top ref
566  if ( pNew1ER->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
567  {
568  if ( pNew1ER->Sign != p->nSwaps )
569  {
570  pNew1ER->TopRefNew = lev2;
571  if ( pNew1ER->Sign != p->nSwaps )
572  {
573  pNew1ER->Sign = p->nSwaps; // set the current signature
574  p->pWidthCofs[ nWidthCofs++ ] = pNew1ER;
575  }
576  }
577  // otherwise the level is already set correctly
578  else
579  {
580  assert( pNew1ER->TopRefNew == lev1 || pNew1ER->TopRefNew == lev2 );
581  }
582  }
583  // update the cofactors's top ref
584  if ( pNew1T->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
585  {
586  if ( pNew1T->Sign != p->nSwaps )
587  {
588  pNew1T->TopRefNew = lev2;
589  if ( pNew1T->Sign != p->nSwaps )
590  {
591  pNew1T->Sign = p->nSwaps; // set the current signature
592  p->pWidthCofs[ nWidthCofs++ ] = pNew1T;
593  }
594  }
595  // otherwise the level is already set correctly
596  else
597  {
598  assert( pNew1T->TopRefNew == lev1 || pNew1T->TopRefNew == lev2 );
599  }
600  }
601  }
602  }
603 
604  if ( p->fMinApl )
605  {
606  // increment the weight of this node
607  pNewPlane20->Weight += AplWeightHalf;
608  // mark the change in the APL weight
609  AplWeightAfter += AplWeightHalf;
610  // update the total weight of this level
611  AplWeightTotalLev1 += AplWeightHalf;
612  }
613 
614  if ( fCompT )
615  pNewPlane20 = Unit_Not(pNewPlane20);
616  }
617 
618  if ( pNew2E == pNew2T )
619  {
620  pNewPlane21 = pNew2T;
621 
622  if ( p->fMinWidth )
623  {
624  // update the cofactors's top ref
625  if ( pNew2T->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
626  {
627  pNew2T->TopRefNew = lev1;
628  if ( pNew2T->Sign != p->nSwaps )
629  {
630  pNew2T->Sign = p->nSwaps; // set the current signature
631  p->pWidthCofs[ nWidthCofs++ ] = pNew2T;
632  }
633  }
634  }
635  }
636  else
637  {
638  assert( !Cudd_IsComplement(pNew2T) );
639 
640  // check the hash-table
641  fFound = 0;
642  for ( HKey = hashKey3(p->Signature, pNew2E, pNew2T, p->nTableSize);
643  p->HTable[HKey].Sign == p->Signature;
644  HKey = (HKey+1) % p->nTableSize )
645  if ( p->HTable[HKey].Arg1 == pNew2E && p->HTable[HKey].Arg2 == pNew2T )
646  { // the entry is present
647  // assign this entry
648  pNewPlane21 = p->HTable[HKey].Arg3;
649  assert( pNewPlane21->lev == lev1 );
650  fFound = 1;
651  p->HashSuccess++;
652  break;
653  }
654 
655  if ( !fFound )
656  { // create the new entry
657  pNewPlane21 = reoUnitsGetNextUnit( p ); // increments the unit counter
658  pNewPlane21->pE = pNew2E;
659  pNewPlane21->pT = pNew2T;
660  pNewPlane21->n = 0; // ref will be added later
661  pNewPlane21->lev = lev1;
662  if ( p->fMinWidth )
663  {
664  pNewPlane21->TopRef = lev1;
665  pNewPlane21->Sign = 0;
666  }
667  // set the weight of this node
668  if ( p->fMinApl )
669  pNewPlane21->Weight = 0.0;
670 
671  // increment ref counters of children
672  pNew2ER = Unit_Regular(pNew2E);
673  pNew2ER->n++; //
674  pNew2T->n++; //
675 
676  // insert into the data structure
677 // reoUnitsAddUnitToPlane( &P2new, pNewPlane21 );
678  AddToLinkedList( ppListNew1, pNewPlane21 );
679 
680  // add this entry to cache
681  assert( p->HTable[HKey].Sign != p->Signature );
682  p->HTable[HKey].Sign = p->Signature;
683  p->HTable[HKey].Arg1 = pNew2E;
684  p->HTable[HKey].Arg2 = pNew2T;
685  p->HTable[HKey].Arg3 = pNewPlane21;
686 
687  nNodesUnrefAdded++;
688 
689 
690  if ( p->fMinWidth )
691  {
692  // update the cofactors's top ref
693  if ( pNew2ER->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
694  {
695  if ( pNew2ER->Sign != p->nSwaps )
696  {
697  pNew2ER->TopRefNew = lev2;
698  if ( pNew2ER->Sign != p->nSwaps )
699  {
700  pNew2ER->Sign = p->nSwaps; // set the current signature
701  p->pWidthCofs[ nWidthCofs++ ] = pNew2ER;
702  }
703  }
704  // otherwise the level is already set correctly
705  else
706  {
707  assert( pNew2ER->TopRefNew == lev1 || pNew2ER->TopRefNew == lev2 );
708  }
709  }
710  // update the cofactors's top ref
711  if ( pNew2T->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
712  {
713  if ( pNew2T->Sign != p->nSwaps )
714  {
715  pNew2T->TopRefNew = lev2;
716  if ( pNew2T->Sign != p->nSwaps )
717  {
718  pNew2T->Sign = p->nSwaps; // set the current signature
719  p->pWidthCofs[ nWidthCofs++ ] = pNew2T;
720  }
721  }
722  // otherwise the level is already set correctly
723  else
724  {
725  assert( pNew2T->TopRefNew == lev1 || pNew2T->TopRefNew == lev2 );
726  }
727  }
728  }
729  }
730 
731  if ( p->fMinApl )
732  {
733  // increment the weight of this node
734  pNewPlane21->Weight += AplWeightHalf;
735  // mark the change in the APL weight
736  AplWeightAfter += AplWeightHalf;
737  // update the total weight of this level
738  AplWeightTotalLev1 += AplWeightHalf;
739  }
740  }
741  // in all cases, the node will be added to the plane-1
742  // this should be the same node (pUnit) as was originally there
743  // because it is referenced by the above nodes
744 
745  assert( !Cudd_IsComplement(pNewPlane21) );
746  // should be the case; otherwise reordering is not a local operation
747 
748  pUnit->pE = pNewPlane20;
749  pUnit->pT = pNewPlane21;
750  assert( pUnit->lev == lev0 );
751  // reference counter remains the same; the APL weight remains the same
752 
753  // increment ref counters of children
754  pNewPlane20R = Unit_Regular(pNewPlane20);
755  pNewPlane20R->n++; ///
756  pNewPlane21->n++; ///
757 
758  // insert into the data structure
759  AddToLinkedList( ppListNew0, pUnit );
760  if ( p->fMinApl )
761  AplWeightTotalLev0 += pUnit->Weight;
762  }
763 
764  // (3) walk through the old lower level, find those nodes whose ref counters are not zero,
765  // and move them to the new uppoer level, free other nodes
766  for ( pLoop = pListOld1; pLoop; )
767  {
768  pUnit = pLoop;
769  pLoop = pLoop->Next;
770  if ( pUnit->n )
771  {
772  assert( !p->fMinApl || pUnit->Weight > 0.0 );
773  // the node should be added to the new level
774  // no need to check the hash table
775  pUnit->lev = lev0;
776  AddToLinkedList( ppListNew0, pUnit );
777  if ( p->fMinApl )
778  AplWeightTotalLev0 += pUnit->Weight;
779 
780  nNodesDownMovedUp++;
781 
782  if ( p->fMinWidth )
783  {
784  pUnitER = Unit_Regular(pUnit->pE);
785  pUnitT = pUnit->pT;
786 
787  // update the cofactors's top ref
788  if ( pUnitER->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
789  {
790  pUnitER->TopRefNew = lev1;
791  if ( pUnitER->Sign != p->nSwaps )
792  {
793  pUnitER->Sign = p->nSwaps; // set the current signature
794  p->pWidthCofs[ nWidthCofs++ ] = pUnitER;
795  }
796  }
797  if ( pUnitT->TopRef > lev0 ) // the cofactor's top ref level is one of the current two levels
798  {
799  pUnitT->TopRefNew = lev1;
800  if ( pUnitT->Sign != p->nSwaps )
801  {
802  pUnitT->Sign = p->nSwaps; // set the current signature
803  p->pWidthCofs[ nWidthCofs++ ] = pUnitT;
804  }
805  }
806  }
807  }
808  else
809  {
810  assert( !p->fMinApl || pUnit->Weight == 0.0 );
811  // decrement reference counters of children
812  pUnitER = Unit_Regular(pUnit->pE);
813  pUnitT = pUnit->pT;
814  pUnitER->n--; ///
815  pUnitT->n--; ///
816  // the node should be thrown away
817  reoUnitsRecycleUnit( p, pUnit );
818  nNodesUnrefRemoved++;
819  }
820  }
821 
822 finish:
823 
824  // attach the new levels to the planes
825  p->pPlanes[lev0].pHead = pListNew0;
826  p->pPlanes[lev1].pHead = pListNew1;
827 
828  // swap the sift status
829  temp = p->pPlanes[lev0].fSifted;
830  p->pPlanes[lev0].fSifted = p->pPlanes[lev1].fSifted;
831  p->pPlanes[lev1].fSifted = temp;
832 
833  // swap variables in the variable map
834  if ( p->pOrderInt )
835  {
836  temp = p->pOrderInt[lev0];
837  p->pOrderInt[lev0] = p->pOrderInt[lev1];
838  p->pOrderInt[lev1] = temp;
839  }
840 
841  // adjust the node profile
842  p->pPlanes[lev0].statsNodes -= (nNodesUpMovedDown - nNodesDownMovedUp);
843  p->pPlanes[lev1].statsNodes -= (nNodesDownMovedUp - nNodesUpMovedDown) + nNodesUnrefRemoved - nNodesUnrefAdded;
844  p->nNodesCur -= nNodesUnrefRemoved - nNodesUnrefAdded;
845 
846  // adjust the node profile on this level
847  if ( p->fMinWidth )
848  {
849  for ( c = 0; c < nWidthCofs; c++ )
850  {
851  if ( p->pWidthCofs[c]->TopRefNew < p->pWidthCofs[c]->TopRef )
852  {
853  p->pWidthCofs[c]->TopRef = p->pWidthCofs[c]->TopRefNew;
854  nWidthReduction--;
855  }
856  else if ( p->pWidthCofs[c]->TopRefNew > p->pWidthCofs[c]->TopRef )
857  {
858  p->pWidthCofs[c]->TopRef = p->pWidthCofs[c]->TopRefNew;
859  nWidthReduction++;
860  }
861  }
862  // verify that the profile is okay
863  reoProfileWidthVerifyLevel( p->pPlanes + lev0, lev0 );
864  reoProfileWidthVerifyLevel( p->pPlanes + lev1, lev1 );
865 
866  // compute the total gain in terms of width
867  nCostGain = (nNodesDownMovedUp - nNodesUpMovedDown + nNodesUnrefRemoved - nNodesUnrefAdded) + nWidthReduction;
868  // adjust the width on this level
869  p->pPlanes[lev1].statsWidth -= (int)nCostGain;
870  // set the cost
871  p->pPlanes[lev1].statsCost = p->pPlanes[lev1].statsWidth;
872  }
873  else if ( p->fMinApl )
874  {
875  // compute the total gain in terms of APL
876  nCostGain = AplWeightPrev - AplWeightAfter;
877  // make sure that the ALP is updated correctly
878 // assert( p->pPlanes[lev0].statsCost + p->pPlanes[lev1].statsCost - nCostGain ==
879 // AplWeightTotalLev0 + AplWeightTotalLev1 );
880  // adjust the profile
881  p->pPlanes[lev0].statsApl = AplWeightTotalLev0;
882  p->pPlanes[lev1].statsApl = AplWeightTotalLev1;
883  // set the cost
884  p->pPlanes[lev0].statsCost = p->pPlanes[lev0].statsApl;
885  p->pPlanes[lev1].statsCost = p->pPlanes[lev1].statsApl;
886  }
887  else
888  {
889  // compute the total gain in terms of the number of nodes
890  nCostGain = nNodesUnrefRemoved - nNodesUnrefAdded;
891  // adjust the profile (adjusted above)
892  // set the cost
893  p->pPlanes[lev0].statsCost = p->pPlanes[lev0].statsNodes;
894  p->pPlanes[lev1].statsCost = p->pPlanes[lev1].statsNodes;
895  }
896 
897  return nCostGain;
898 }
int fMinApl
Definition: reo.h:105
#define AddToLinkedList(ppList, pLink)
DECLARATIONS ///.
Definition: reoSwap.c:28
short lev
Definition: reo.h:68
int Sign
Definition: reo.h:95
double Weight
Definition: reo.h:77
reo_unit ** pWidthCofs
Definition: reo.h:123
double nAplCur
Definition: reo.h:132
reo_unit * reoUnitsGetNextUnit(reo_man *p)
FUNCTION DEFINITIONS ///.
Definition: reoUnits.c:45
int Signature
Definition: reo.h:151
int nNodesCur
Definition: reo.h:127
reo_unit * Arg2
Definition: reo.h:97
int statsWidth
Definition: reo.h:84
int nNISwaps
Definition: reo.h:170
#define hashKey3(a, b, c, TSIZE)
Definition: extraBdd.h:89
#define Cudd_IsComplement(node)
Definition: cudd.h:425
void reoProfileWidthVerifyLevel(reo_plane *pPlane, int Level)
Definition: reoProfile.c:354
reo_unit * pT
Definition: reo.h:75
int fMinWidth
Definition: reo.h:104
reo_unit * Next
Definition: reo.h:76
short TopRef
Definition: reo.h:69
short n
Definition: reo.h:71
reo_unit * pE
Definition: reo.h:74
reo_hash * HTable
Definition: reo.h:149
int nTableSize
Definition: reo.h:150
short TopRefNew
Definition: reo.h:70
double statsCost
Definition: reo.h:86
double statsApl
Definition: reo.h:85
#define Unit_Regular(u)
Definition: reo.h:174
int Sign
Definition: reo.h:72
reo_plane * pPlanes
Definition: reo.h:142
#define Unit_Not(u)
Definition: reo.h:175
int nSwaps
Definition: reo.h:169
reo_unit * Arg3
Definition: reo.h:98
void reoUnitsRecycleUnit(reo_man *p, reo_unit *pUnit)
Definition: reoUnits.c:69
reo_unit * Arg1
Definition: reo.h:96
Definition: reo.h:66
#define assert(ex)
Definition: util_old.h:213
int HashSuccess
Definition: reo.h:167
int statsNodes
Definition: reo.h:83
reo_unit * pHead
Definition: reo.h:90
int * pOrderInt
Definition: reo.h:120
int fSifted
Definition: reo.h:82
void reoResizeStructures ( reo_man p,
int  nDdVarsMax,
int  nNodesMax,
int  nFuncs 
)

Function*************************************************************

Synopsis [Resizes the internal manager data structures.]

Description []

SideEffects []

SeeAlso []

Definition at line 269 of file reoCore.c.

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 }
Definition: cudd.h:278
reo_unit ** pWidthCofs
Definition: reo.h:123
double * pVarCosts
Definition: reo.h:121
int nTopsAlloc
Definition: reo.h:146
int * pMapToPlanes
Definition: reo.h:137
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int nNodesMaxAlloc
Definition: reo.h:154
char * memmove()
int * pMapToDdVarsFinal
Definition: reo.h:139
int nSuppAlloc
Definition: reo.h:118
int * pLevelOrder
Definition: reo.h:122
DdNode ** pRefNodes
Definition: reo.h:155
reo_hash * HTable
Definition: reo.h:149
int nTableSize
Definition: reo.h:150
int nRefNodesAlloc
Definition: reo.h:157
Definition: reo.h:80
reo_unit ** pTops
Definition: reo.h:144
int * pSupp
Definition: reo.h:117
int * pMapToDdVarsOrig
Definition: reo.h:138
reo_plane * pPlanes
Definition: reo.h:142
int nMemChunksAlloc
Definition: reo.h:163
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define REO_CHUNK_SIZE
Definition: reo.h:42
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
Definition: reo.h:66
reo_unit ** pMemChunks
Definition: reo.h:161
int * pOrderInt
Definition: reo.h:120
Definition: reo.h:93
reo_unit* reoTransferNodesToUnits_rec ( reo_man p,
DdNode F 
)

DECLARATIONS ///.

CFile****************************************************************

FileName [reoTransfer.c]

PackageName [REO: A specialized DD reordering engine.]

Synopsis [Transfering a DD from the CUDD manager into REO"s internal data structures and back.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - October 15, 2002.]

Revision [

Id:
reoTransfer.c,v 1.0 2002/15/10 03:00:00 alanmi Exp

]FUNCTION DEFINITIONS /// Function*************************************************************

Synopsis [Transfers the DD into the internal reordering data structure.]

Description [It is important that the hash table is lossless.]

SideEffects []

SeeAlso []

Definition at line 43 of file reoTransfer.c.

44 {
45  DdManager * dd = p->dd;
46  reo_unit * pUnit;
47  int HKey = -1; // Suppress "might be used uninitialized"
48  int fComp;
49 
50  fComp = Cudd_IsComplement(F);
51  F = Cudd_Regular(F);
52 
53  // check the hash-table
54  if ( F->ref != 1 )
55  {
56  // search cache - use linear probing
57  for ( HKey = hashKey2(p->Signature,F,p->nTableSize); p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize )
58  if ( p->HTable[HKey].Arg1 == (reo_unit *)F )
59  {
60  pUnit = p->HTable[HKey].Arg2;
61  assert( pUnit );
62  // increment the edge counter
63  pUnit->n++;
64  return Unit_NotCond( pUnit, fComp );
65  }
66  }
67  // the entry in not found in the cache
68 
69  // create a new entry
70  pUnit = reoUnitsGetNextUnit( p );
71  pUnit->n = 1;
72  if ( cuddIsConstant(F) )
73  {
74  pUnit->lev = REO_CONST_LEVEL;
75  pUnit->pE = (reo_unit*)(ABC_PTRUINT_T)(cuddV(F));
76  pUnit->pT = NULL;
77  // check if the diagram that is being reordering has complement edges
78  if ( F != dd->one )
79  p->fThisIsAdd = 1;
80  // insert the unit into the corresponding plane
81  reoUnitsAddUnitToPlane( &(p->pPlanes[p->nSupp]), pUnit ); // increments the unit counter
82  }
83  else
84  {
85  pUnit->lev = p->pMapToPlanes[F->index];
86  pUnit->pE = reoTransferNodesToUnits_rec( p, cuddE(F) );
87  pUnit->pT = reoTransferNodesToUnits_rec( p, cuddT(F) );
88  // insert the unit into the corresponding plane
89  reoUnitsAddUnitToPlane( &(p->pPlanes[pUnit->lev]), pUnit ); // increments the unit counter
90  }
91 
92  // add to the hash table
93  if ( F->ref != 1 )
94  {
95  // the next free entry is already found - it is pointed to by HKey
96  // while we traversed the diagram, the hash entry to which HKey points,
97  // might have been used. Make sure that its signature is different.
98  for ( ; p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize );
99  p->HTable[HKey].Sign = p->Signature;
100  p->HTable[HKey].Arg1 = (reo_unit *)F;
101  p->HTable[HKey].Arg2 = pUnit;
102  }
103 
104  // increment the counter of nodes
105  p->nNodesCur++;
106  return Unit_NotCond( pUnit, fComp );
107 }
DdHalfWord ref
Definition: cudd.h:280
#define hashKey2(a, b, TSIZE)
Definition: extraBdd.h:86
short lev
Definition: reo.h:68
int Sign
Definition: reo.h:95
#define Cudd_Regular(node)
Definition: cudd.h:397
DdManager * dd
Definition: reo.h:112
reo_unit * reoUnitsGetNextUnit(reo_man *p)
FUNCTION DEFINITIONS ///.
Definition: reoUnits.c:45
int * pMapToPlanes
Definition: reo.h:137
int Signature
Definition: reo.h:151
int nNodesCur
Definition: reo.h:127
int fThisIsAdd
Definition: reo.h:116
int nSupp
Definition: reo.h:119
reo_unit * Arg2
Definition: reo.h:97
#define cuddV(node)
Definition: cuddInt.h:668
void reoUnitsAddUnitToPlane(reo_plane *pPlane, reo_unit *pUnit)
Definition: reoUnits.c:135
#define Cudd_IsComplement(node)
Definition: cudd.h:425
reo_unit * pT
Definition: reo.h:75
short n
Definition: reo.h:71
reo_unit * pE
Definition: reo.h:74
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define Unit_NotCond(u, c)
Definition: reo.h:176
reo_hash * HTable
Definition: reo.h:149
int nTableSize
Definition: reo.h:150
#define cuddT(node)
Definition: cuddInt.h:636
reo_plane * pPlanes
Definition: reo.h:142
DdHalfWord index
Definition: cudd.h:279
reo_unit * Arg1
Definition: reo.h:96
DdNode * one
Definition: cuddInt.h:345
Definition: reo.h:66
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
#define REO_CONST_LEVEL
Definition: reo.h:40
ABC_NAMESPACE_IMPL_START reo_unit * reoTransferNodesToUnits_rec(reo_man *p, DdNode *F)
DECLARATIONS ///.
Definition: reoTransfer.c:43
DdNode* reoTransferUnitsToNodes_rec ( reo_man p,
reo_unit pUnit 
)

Function*************************************************************

Synopsis [Creates the DD from the internal reordering data structure.]

Description [It is important that the hash table is lossless.]

SideEffects []

SeeAlso []

Definition at line 120 of file reoTransfer.c.

121 {
122  DdManager * dd = p->dd;
123  DdNode * bRes, * E, * T;
124  int HKey = -1; // Suppress "might be used uninitialized"
125  int fComp;
126 
127  fComp = Cudd_IsComplement(pUnit);
128  pUnit = Unit_Regular(pUnit);
129 
130  // check the hash-table
131  if ( pUnit->n != 1 )
132  {
133  for ( HKey = hashKey2(p->Signature,pUnit,p->nTableSize); p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize )
134  if ( p->HTable[HKey].Arg1 == pUnit )
135  {
136  bRes = (DdNode*) p->HTable[HKey].Arg2;
137  assert( bRes );
138  return Cudd_NotCond( bRes, fComp );
139  }
140  }
141 
142  // treat the case of constants
143  if ( Unit_IsConstant(pUnit) )
144  {
145  bRes = cuddUniqueConst( dd, ((double)((int)(ABC_PTRUINT_T)(pUnit->pE))) );
146  cuddRef( bRes );
147  }
148  else
149  {
150  // split and recur on children of this node
151  E = reoTransferUnitsToNodes_rec( p, pUnit->pE );
152  if ( E == NULL )
153  return NULL;
154  cuddRef(E);
155 
156  T = reoTransferUnitsToNodes_rec( p, pUnit->pT );
157  if ( T == NULL )
158  {
159  Cudd_RecursiveDeref(dd, E);
160  return NULL;
161  }
162  cuddRef(T);
163 
164  // consider the case when Res0 and Res1 are the same node
165  assert( E != T );
166  assert( !Cudd_IsComplement(T) );
167 
168  bRes = cuddUniqueInter( dd, p->pMapToDdVarsFinal[pUnit->lev], T, E );
169  if ( bRes == NULL )
170  {
171  Cudd_RecursiveDeref(dd,E);
172  Cudd_RecursiveDeref(dd,T);
173  return NULL;
174  }
175  cuddRef( bRes );
176  cuddDeref( E );
177  cuddDeref( T );
178  }
179 
180  // do not keep the result if the ref count is only 1, since it will not be visited again
181  if ( pUnit->n != 1 )
182  {
183  // while we traversed the diagram, the hash entry to which HKey points,
184  // might have been used. Make sure that its signature is different.
185  for ( ; p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize );
186  p->HTable[HKey].Sign = p->Signature;
187  p->HTable[HKey].Arg1 = pUnit;
188  p->HTable[HKey].Arg2 = (reo_unit *)bRes;
189 
190  // add the DD to the referenced DD list in order to be able to store it in cache
191  p->pRefNodes[p->nRefNodes++] = bRes; Cudd_Ref( bRes );
192  // no need to do this, because the garbage collection will not take bRes away
193  // it is held by the diagram in the making
194  }
195  // increment the counter of nodes
196  p->nNodesCur++;
197  cuddDeref( bRes );
198  return Cudd_NotCond( bRes, fComp );
199 }
#define cuddRef(n)
Definition: cuddInt.h:584
#define hashKey2(a, b, TSIZE)
Definition: extraBdd.h:86
#define cuddDeref(n)
Definition: cuddInt.h:604
short lev
Definition: reo.h:68
int Sign
Definition: reo.h:95
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * reoTransferUnitsToNodes_rec(reo_man *p, reo_unit *pUnit)
Definition: reoTransfer.c:120
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
DdManager * dd
Definition: reo.h:112
int Signature
Definition: reo.h:151
int nNodesCur
Definition: reo.h:127
reo_unit * Arg2
Definition: reo.h:97
int nRefNodes
Definition: reo.h:156
int * pMapToDdVarsFinal
Definition: reo.h:139
#define Cudd_IsComplement(node)
Definition: cudd.h:425
reo_unit * pT
Definition: reo.h:75
DdNode ** pRefNodes
Definition: reo.h:155
short n
Definition: reo.h:71
reo_unit * pE
Definition: reo.h:74
reo_hash * HTable
Definition: reo.h:149
int nTableSize
Definition: reo.h:150
#define Unit_Regular(u)
Definition: reo.h:174
#define Unit_IsConstant(u)
Definition: reo.h:177
reo_unit * Arg1
Definition: reo.h:96
Definition: reo.h:66
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define assert(ex)
Definition: util_old.h:213
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
void reoUnitsAddUnitToPlane ( reo_plane pPlane,
reo_unit pUnit 
)

Function*************************************************************

Synopsis [Adds one unit to the list of units which constitutes the plane.]

Description []

SideEffects []

SeeAlso []

Definition at line 135 of file reoUnits.c.

136 {
137  if ( pPlane->pHead == NULL )
138  {
139  pPlane->pHead = pUnit;
140  pUnit->Next = NULL;
141  }
142  else
143  {
144  pUnit->Next = pPlane->pHead;
145  pPlane->pHead = pUnit;
146  }
147  pPlane->statsNodes++;
148 }
reo_unit * Next
Definition: reo.h:76
int statsNodes
Definition: reo.h:83
reo_unit * pHead
Definition: reo.h:90
reo_unit* reoUnitsGetNextUnit ( reo_man p)

FUNCTION DEFINITIONS ///.

Function*************************************************************

Synopsis [Extract the next unit from the free unit list.]

Description []

SideEffects []

SeeAlso []

Definition at line 45 of file reoUnits.c.

46 {
47  reo_unit * pUnit;
48  // check there are stil units to extract
49  if ( p->pUnitFreeList == NULL )
51  // extract the next unit from the linked list
52  pUnit = p->pUnitFreeList;
53  p->pUnitFreeList = pUnit->Next;
54  p->nUnitsUsed++;
55  return pUnit;
56 }
static ABC_NAMESPACE_IMPL_START void reoUnitsAddToFreeUnitList(reo_man *p)
DECLARATIONS ///.
Definition: reoUnits.c:162
int nUnitsUsed
Definition: reo.h:164
reo_unit * pUnitFreeList
Definition: reo.h:160
reo_unit * Next
Definition: reo.h:76
Definition: reo.h:66
void reoUnitsRecycleUnit ( reo_man p,
reo_unit pUnit 
)

Function*************************************************************

Synopsis [Returns the unit to the free unit list.]

Description []

SideEffects []

SeeAlso []

Definition at line 69 of file reoUnits.c.

70 {
71  pUnit->Next = p->pUnitFreeList;
72  p->pUnitFreeList = pUnit;
73  p->nUnitsUsed--;
74 }
int nUnitsUsed
Definition: reo.h:164
reo_unit * pUnitFreeList
Definition: reo.h:160
reo_unit * Next
Definition: reo.h:76
void reoUnitsRecycleUnitList ( reo_man p,
reo_plane pPlane 
)

Function*************************************************************

Synopsis [Returns the list of units to the free unit list.]

Description []

SideEffects []

SeeAlso []

Definition at line 87 of file reoUnits.c.

88 {
89  reo_unit * pUnit;
90  reo_unit * pTail = NULL; // Suppress "might be used uninitialized"
91 
92  if ( pPlane->pHead == NULL )
93  return;
94 
95  // find the tail
96  for ( pUnit = pPlane->pHead; pUnit; pUnit = pUnit->Next )
97  pTail = pUnit;
98  pTail->Next = p->pUnitFreeList;
99  p->pUnitFreeList = pPlane->pHead;
100  memset( pPlane, 0, sizeof(reo_plane) );
101 // pPlane->pHead = NULL;
102 }
char * memset()
reo_unit * pUnitFreeList
Definition: reo.h:160
reo_unit * Next
Definition: reo.h:76
Definition: reo.h:80
Definition: reo.h:66
reo_unit * pHead
Definition: reo.h:90
void reoUnitsStopDispenser ( reo_man p)

Function*************************************************************

Synopsis [Stops the unit dispenser.]

Description []

SideEffects []

SeeAlso []

Definition at line 115 of file reoUnits.c.

116 {
117  int i;
118  for ( i = 0; i < p->nMemChunks; i++ )
119  ABC_FREE( p->pMemChunks[i] );
120 // printf("\nThe number of chunks used is %d, each of them %d units\n", p->nMemChunks, REO_CHUNK_SIZE );
121  p->nMemChunks = 0;
122 }
int nMemChunks
Definition: reo.h:162
#define ABC_FREE(obj)
Definition: abc_global.h:232
reo_unit ** pMemChunks
Definition: reo.h:161