ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
reo.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include "bdd/extrab/extraBdd.h"
Include dependency graph for reo.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _reo_unit
 
struct  _reo_plane
 
struct  _reo_hash
 
struct  _reo_man
 

Macros

#define REO_REORDER_LIMIT   1.15
 MACRO DEFINITIONS ///.
 
#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)
 
#define Unit_Not(u)
 
#define Unit_NotCond(u, c)
 
#define Unit_IsConstant(u)
 

Typedefs

typedef struct _reo_unit reo_unit
 DATA STRUCTURES ///.
 
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 ///.
 
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)
 
DdNode * Extra_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 ///.
 
void reoResizeStructures (reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
 
void reoProfileNodesStart (reo_man *p)
 DECLARATIONS ///.
 
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 ///.
 
double reoReorderSwapAdjacentVars (reo_man *p, int Level, int fMovingUp)
 FUNCTION DEFINITIONS ///.
 
reo_unitreoTransferNodesToUnits_rec (reo_man *p, DdNode *F)
 DECLARATIONS ///.
 
DdNode * reoTransferUnitsToNodes_rec (reo_man *p, reo_unit *pUnit)
 
reo_unitreoUnitsGetNextUnit (reo_man *p)
 FUNCTION DEFINITIONS ///.
 
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 ///.
 
DdNode * Extra_ReorderCudd (DdManager *dd, DdNode *aFunc, int pPermuteReo[])
 
int Extra_bddReorderTest (DdManager *dd, DdNode *bF)
 
int Extra_addReorderTest (DdManager *dd, DdNode *aF)
 

Macro Definition Documentation

◆ REO_CHUNK_SIZE

#define REO_CHUNK_SIZE   5000

Definition at line 42 of file reo.h.

◆ REO_CONST_LEVEL

#define REO_CONST_LEVEL   30000

Definition at line 40 of file reo.h.

◆ REO_COST_EPSILON

#define REO_COST_EPSILON   0.0000001

Definition at line 43 of file reo.h.

◆ REO_DISABLE

#define REO_DISABLE   0

Definition at line 47 of file reo.h.

◆ REO_ENABLE

#define REO_ENABLE   1

Definition at line 46 of file reo.h.

◆ REO_HIGH_VALUE

#define REO_HIGH_VALUE   10000000

Definition at line 44 of file reo.h.

◆ REO_QUAL_PAR

#define REO_QUAL_PAR   3

Definition at line 38 of file reo.h.

◆ REO_REORDER_LIMIT

#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.

◆ REO_TOPREF_UNDEF

#define REO_TOPREF_UNDEF   30000

Definition at line 41 of file reo.h.

◆ Unit_IsConstant

#define Unit_IsConstant ( u)
Value:
((int)((u)->lev == REO_CONST_LEVEL))
#define REO_CONST_LEVEL
Definition reo.h:40

Definition at line 177 of file reo.h.

◆ Unit_Not

#define Unit_Not ( u)
Value:
((reo_unit *)((ABC_PTRUINT_T)(u) ^ 01))
struct _reo_unit reo_unit
DATA STRUCTURES ///.
Definition reo.h:60

Definition at line 175 of file reo.h.

◆ Unit_NotCond

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

Definition at line 176 of file reo.h.

◆ Unit_Regular

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

Definition at line 174 of file reo.h.

Typedef Documentation

◆ reo_hash

typedef struct _reo_hash reo_hash

Definition at line 62 of file reo.h.

◆ reo_man

typedef struct _reo_man reo_man

Definition at line 63 of file reo.h.

◆ reo_plane

typedef struct _reo_plane reo_plane

Definition at line 61 of file reo.h.

◆ reo_test

typedef struct _reo_test reo_test

Definition at line 64 of file reo.h.

◆ reo_unit

typedef struct _reo_unit reo_unit

DATA STRUCTURES ///.

Definition at line 60 of file reo.h.

Enumeration Type Documentation

◆ reo_min_type

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
reo_min_type
Definition reo.h:50
@ REO_MINIMIZE_NODES
Definition reo.h:51
@ REO_MINIMIZE_APL
Definition reo.h:53
@ REO_MINIMIZE_WIDTH
Definition reo.h:52

Function Documentation

◆ Extra_addReorderTest()

int Extra_addReorderTest ( DdManager * dd,
DdNode * aF )
extern

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 );
240 Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SIFT,1);
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}
ABC_INT64_T abctime
Definition abc_global.h:332

◆ Extra_bddReorderTest()

int Extra_bddReorderTest ( DdManager * dd,
DdNode * bF )
extern

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 );
194 Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SIFT,1);
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}

◆ Extra_Reorder()

DdNode * Extra_Reorder ( reo_man * p,
DdManager * dd,
DdNode * Func,
int * pOrder )
extern

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}
Cube * p
Definition exorList.c:222
void Extra_ReorderArray(reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder)
Definition reoApi.c:283
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_ReorderArray()

void Extra_ReorderArray ( reo_man * p,
DdManager * dd,
DdNode * Funcs[],
DdNode * FuncsRes[],
int nFuncs,
int * pOrder )
extern

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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_ReorderCudd()

DdNode * Extra_ReorderCudd ( DdManager * dd,
DdNode * aFunc,
int pPermuteReo[] )
extern

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
140printf( "Nodes before = %d.\n", Cudd_DagSize(aFuncReorder) );
141 Cudd_ReduceHeap( ddReorder, CUDD_REORDER_SYMM_SIFT, 1 );
142printf( "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 ABC_ALLOC(type, num)
Definition abc_global.h:264
DdNode * Extra_TransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
unsigned short var
Definition giaNewBdd.h:35
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_ReorderInit()

reo_man * Extra_ReorderInit ( int nDdVarsMax,
int nNodesMax )
extern

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}
struct _reo_man reo_man
Definition reo.h:63
void reoResizeStructures(reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
Definition reoCore.c:269
char * memset()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_ReorderQuit()

void Extra_ReorderQuit ( reo_man * p)
extern

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 );
86 ABC_FREE( p->pMapToDdVarsOrig );
87 ABC_FREE( p->pMapToDdVarsFinal );
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}
#define ABC_FREE(obj)
Definition abc_global.h:267
void reoUnitsStopDispenser(reo_man *p)
Definition reoUnits.c:115
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extra_ReorderSetIterations()

void Extra_ReorderSetIterations ( reo_man * p,
int nIters )
extern

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}

◆ Extra_ReorderSetMinimizationType()

void Extra_ReorderSetMinimizationType ( reo_man * p,
reo_min_type fMinType )
extern

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}
#define assert(ex)
Definition util_old.h:213

◆ Extra_ReorderSetRemapping()

void Extra_ReorderSetRemapping ( reo_man * p,
int fRemapUp )
extern

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}

◆ Extra_ReorderSetVerbosity()

void Extra_ReorderSetVerbosity ( reo_man * p,
int fVerbose )
extern

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}

◆ Extra_ReorderSetVerification()

void Extra_ReorderSetVerification ( reo_man * p,
int fVerify )
extern

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}

◆ Extra_ReorderTest()

void Extra_ReorderTest ( DdManager * dd,
DdNode * Func )
extern

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 );
56printf( "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}
DdNode * Extra_ReorderCudd(DdManager *dd, DdNode *aFunc, int pPermuteReo[])
Definition reoTest.c:109
void Extra_ReorderQuit(reo_man *p)
Definition reoApi.c:79
DdNode * Extra_Reorder(reo_man *p, DdManager *dd, DdNode *Func, int *pOrder)
Definition reoApi.c:262
reo_man * Extra_ReorderInit(int nDdVarsMax, int nNodesMax)
FUNCTION DECLARATIONS ///.
Definition reoApi.c:50
Here is the call graph for this function:

◆ reoProfileAplPrint()

void reoProfileAplPrint ( reo_man * p)
extern

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}
Here is the caller graph for this function:

◆ reoProfileAplStart()

void reoProfileAplStart ( reo_man * p)
extern

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}
#define Unit_Regular(u)
Definition reo.h:174
reo_unit * Next
Definition reo.h:76
double Weight
Definition reo.h:77
reo_unit * pE
Definition reo.h:74
reo_unit * pT
Definition reo.h:75
Here is the caller graph for this function:

◆ reoProfileNodesPrint()

void reoProfileNodesPrint ( reo_man * p)
extern

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}
Here is the caller graph for this function:

◆ reoProfileNodesStart()

void reoProfileNodesStart ( reo_man * p)
extern

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}
Here is the caller graph for this function:

◆ reoProfileWidthPrint()

void reoProfileWidthPrint ( reo_man * p)
extern

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}
Here is the caller graph for this function:

◆ reoProfileWidthStart()

void reoProfileWidthStart ( reo_man * p)
extern

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}
void reoProfileWidthVerifyLevel(reo_plane *pPlane, int Level)
Definition reoProfile.c:354
#define REO_TOPREF_UNDEF
Definition reo.h:41
short lev
Definition reo.h:68
int Sign
Definition reo.h:72
short TopRef
Definition reo.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoProfileWidthStart2()

void reoProfileWidthStart2 ( reo_man * p)
extern

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}
Here is the call graph for this function:

◆ reoProfileWidthVerifyLevel()

void reoProfileWidthVerifyLevel ( reo_plane * pPlane,
int Level )
extern

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 * pHead
Definition reo.h:90
Here is the caller graph for this function:

◆ reoReorderArray()

void reoReorderArray ( reo_man * p,
DdManager * dd,
DdNode * Funcs[],
DdNode * FuncsRes[],
int nFuncs,
int * pOrder )
extern

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
90 p->pMapToDdVarsFinal[Counter] = dd->invperm[Counter];
91 p->pOrderInt[Counter] = Counter;
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
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 ) );
177
178s_AplBefore = p->nAplBeg;
179s_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 * Extra_VectorSupportArray(DdManager *dd, DdNode **F, int n, int *support)
void reoResizeStructures(reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs)
Definition reoCore.c:269
double s_AplBefore
Definition reoCore.c:32
double s_AplAfter
Definition reoCore.c:33
reo_unit * reoTransferNodesToUnits_rec(reo_man *p, DdNode *F)
DECLARATIONS ///.
Definition reoTransfer.c:43
void reoProfileWidthStart(reo_man *p)
Definition reoProfile.c:130
void reoUnitsRecycleUnitList(reo_man *p, reo_plane *pPlane)
Definition reoUnits.c:87
void reoReorderSift(reo_man *p)
DECLARATIONS ///.
Definition reoSift.c:44
void reoProfileNodesStart(reo_man *p)
DECLARATIONS ///.
Definition reoProfile.c:46
void reoProfileAplPrint(reo_man *p)
Definition reoProfile.c:305
DdNode * reoTransferUnitsToNodes_rec(reo_man *p, reo_unit *pUnit)
void reoProfileWidthPrint(reo_man *p)
Definition reoProfile.c:321
void reoProfileAplStart(reo_man *p)
Definition reoProfile.c:78
void reoProfileNodesPrint(reo_man *p)
Definition reoProfile.c:289
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoReorderSift()

void reoReorderSift ( reo_man * p)
extern

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}
double reoReorderSwapAdjacentVars(reo_man *p, int Level, int fMovingUp)
FUNCTION DEFINITIONS ///.
Definition reoSwap.c:46
#define REO_REORDER_LIMIT
MACRO DEFINITIONS ///.
Definition reo.h:37
#define REO_QUAL_PAR
Definition reo.h:38
#define REO_COST_EPSILON
Definition reo.h:43
#define REO_HIGH_VALUE
Definition reo.h:44
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoReorderSwapAdjacentVars()

double reoReorderSwapAdjacentVars ( reo_man * p,
int lev0,
int fMovingUp )
extern

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 = NULL, * pNew1T = NULL, * pNew2E = NULL, * pNew2T = NULL;
58 reo_unit * pNew1ER = NULL, * pNew2ER = NULL;
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
822finish:
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}
#define hashKey3(a, b, c, TSIZE)
Definition extraBdd.h:89
#define AddToLinkedList(ppList, pLink)
DECLARATIONS ///.
Definition reoSwap.c:28
void reoProfileWidthVerifyLevel(reo_plane *pPlane, int Level)
Definition reoProfile.c:354
#define Unit_Not(u)
Definition reo.h:175
void reoUnitsRecycleUnit(reo_man *p, reo_unit *pUnit)
Definition reoUnits.c:69
reo_unit * reoUnitsGetNextUnit(reo_man *p)
FUNCTION DEFINITIONS ///.
Definition reoUnits.c:45
short n
Definition reo.h:71
short TopRefNew
Definition reo.h:70
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoResizeStructures()

void reoResizeStructures ( reo_man * p,
int nDdVarsMax,
int nNodesMax,
int nFuncs )
extern

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 );
289 ABC_FREE( p->pMapToDdVarsOrig );
290 ABC_FREE( p->pMapToDdVarsFinal );
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 );
315 p->pRefNodes = ABC_ALLOC( DdNode *, p->nRefNodesAlloc );
316 p->pWidthCofs = ABC_ALLOC( reo_unit *, p->nRefNodesAlloc );
317 p->pMemChunks = ABC_ALLOC( reo_unit *, p->nMemChunksAlloc );
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 );
333 p->pRefNodes = ABC_ALLOC( DdNode *, p->nRefNodesAlloc );
334 p->pWidthCofs = ABC_ALLOC( reo_unit *, p->nRefNodesAlloc );
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}
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define REO_CHUNK_SIZE
Definition reo.h:42
struct _reo_plane reo_plane
Definition reo.h:61
struct _reo_hash reo_hash
Definition reo.h:62
char * memmove()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoTransferNodesToUnits_rec()

reo_unit * reoTransferNodesToUnits_rec ( reo_man * p,
DdNode * F )
extern

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}
#define hashKey2(a, b, TSIZE)
Definition extraBdd.h:86
ABC_NAMESPACE_IMPL_START reo_unit * reoTransferNodesToUnits_rec(reo_man *p, DdNode *F)
DECLARATIONS ///.
Definition reoTransfer.c:43
#define Unit_NotCond(u, c)
Definition reo.h:176
void reoUnitsAddUnitToPlane(reo_plane *pPlane, reo_unit *pUnit)
Definition reoUnits.c:135
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoTransferUnitsToNodes_rec()

DdNode * reoTransferUnitsToNodes_rec ( reo_man * p,
reo_unit * pUnit )
extern

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}
DdNode * reoTransferUnitsToNodes_rec(reo_man *p, reo_unit *pUnit)
#define Unit_IsConstant(u)
Definition reo.h:177
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoUnitsAddUnitToPlane()

void reoUnitsAddUnitToPlane ( reo_plane * pPlane,
reo_unit * pUnit )
extern

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}
int statsNodes
Definition reo.h:83
Here is the caller graph for this function:

◆ reoUnitsGetNextUnit()

reo_unit * reoUnitsGetNextUnit ( reo_man * p)
extern

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 )
50 reoUnitsAddToFreeUnitList( p );
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}
Here is the caller graph for this function:

◆ reoUnitsRecycleUnit()

void reoUnitsRecycleUnit ( reo_man * p,
reo_unit * pUnit )
extern

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}
Here is the caller graph for this function:

◆ reoUnitsRecycleUnitList()

void reoUnitsRecycleUnitList ( reo_man * p,
reo_plane * pPlane )
extern

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reoUnitsStopDispenser()

void reoUnitsStopDispenser ( reo_man * p)
extern

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}
Here is the caller graph for this function: