#include "reo.h"
Go to the source code of this file.
Defines | |
#define | CALLOC(type, num) ((type *) calloc((long)(num), (long)sizeof(type))) |
Functions | |
static int | reoRecursiveDeref (reo_unit *pUnit) |
static int | reoCheckZeroRefs (reo_plane *pPlane) |
static int | reoCheckLevels (reo_man *p) |
void | reoReorderArray (reo_man *p, DdManager *dd, DdNode *Funcs[], DdNode *FuncsRes[], int nFuncs, int *pOrder) |
void | reoResizeStructures (reo_man *p, int nDdVarsMax, int nNodesMax, int nFuncs) |
Variables | |
double | s_AplBefore |
double | s_AplAfter |
#define CALLOC | ( | type, | |||
num | ) | ((type *) calloc((long)(num), (long)sizeof(type))) |
CFile****************************************************************
FileName [reoCore.c]
PackageName [REO: A specialized DD reordering engine.]
Synopsis [Implementation of the core reordering procedure.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - October 15, 2002.]
Revision [
] DECLARATIONS ///
int reoCheckLevels | ( | reo_man * | p | ) | [static] |
Function*************************************************************
Synopsis [Checks the zero references for the given plane.]
Description [This function is only useful for debugging.]
SideEffects []
SeeAlso []
Definition at line 417 of file reoCore.c.
00418 { 00419 reo_unit * pUnit; 00420 int i; 00421 00422 for ( i = 0; i < p->nSupp; i++ ) 00423 { 00424 // there are some nodes left on each level 00425 assert( p->pPlanes[i].statsNodes ); 00426 for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next ) 00427 { 00428 // the level is properly set 00429 assert( pUnit->lev == i ); 00430 } 00431 } 00432 return 1; 00433 }
int reoCheckZeroRefs | ( | reo_plane * | pPlane | ) | [static] |
Function*************************************************************
Synopsis [Checks the zero references for the given plane.]
Description [This function is only useful for debugging.]
SideEffects []
SeeAlso []
int reoRecursiveDeref | ( | reo_unit * | pUnit | ) | [static] |
Function*************************************************************
Synopsis [Dereferences units the data structure after reordering.]
Description [This function is only useful for debugging.]
SideEffects []
SeeAlso []
Definition at line 367 of file reoCore.c.
00368 { 00369 reo_unit * pUnitR; 00370 pUnitR = Unit_Regular(pUnit); 00371 pUnitR->n--; 00372 if ( Unit_IsConstant(pUnitR) ) 00373 return 1; 00374 if ( pUnitR->n == 0 ) 00375 { 00376 reoRecursiveDeref( pUnitR->pE ); 00377 reoRecursiveDeref( pUnitR->pT ); 00378 } 00379 return 1; 00380 }
void reoReorderArray | ( | reo_man * | p, | |
DdManager * | dd, | |||
DdNode * | Funcs[], | |||
DdNode * | FuncsRes[], | |||
int | nFuncs, | |||
int * | pOrder | |||
) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 49 of file reoCore.c.
00050 { 00051 int Counter, i; 00052 00053 // set the initial parameters 00054 p->dd = dd; 00055 p->pOrder = pOrder; 00056 p->nTops = nFuncs; 00057 // get the initial number of nodes 00058 p->nNodesBeg = Cudd_SharingSize( Funcs, nFuncs ); 00059 // resize the internal data structures of the manager if necessary 00060 reoResizeStructures( p, ddMax(dd->size,dd->sizeZ), p->nNodesBeg, nFuncs ); 00061 // compute the support 00062 p->pSupp = Extra_VectorSupportArray( dd, Funcs, nFuncs, p->pSupp ); 00063 // get the number of support variables 00064 p->nSupp = 0; 00065 for ( i = 0; i < dd->size; i++ ) 00066 p->nSupp += p->pSupp[i]; 00067 00068 // if it is the constant function, no need to reorder 00069 if ( p->nSupp == 0 ) 00070 { 00071 for ( i = 0; i < nFuncs; i++ ) 00072 { 00073 FuncsRes[i] = Funcs[i]; Cudd_Ref( FuncsRes[i] ); 00074 } 00075 return; 00076 } 00077 00078 // create the internal variable maps 00079 // go through variable levels in the manager 00080 Counter = 0; 00081 for ( i = 0; i < dd->size; i++ ) 00082 if ( p->pSupp[ dd->invperm[i] ] ) 00083 { 00084 p->pMapToPlanes[ dd->invperm[i] ] = Counter; 00085 p->pMapToDdVarsOrig[Counter] = dd->invperm[i]; 00086 if ( !p->fRemapUp ) 00087 p->pMapToDdVarsFinal[Counter] = dd->invperm[i]; 00088 else 00089 p->pMapToDdVarsFinal[Counter] = dd->invperm[Counter]; 00090 p->pOrderInt[Counter] = Counter; 00091 Counter++; 00092 } 00093 00094 // set the initial parameters 00095 p->nUnitsUsed = 0; 00096 p->nNodesCur = 0; 00097 p->fThisIsAdd = 0; 00098 p->Signature++; 00099 // transfer the function from the CUDD package into REO"s internal data structure 00100 for ( i = 0; i < nFuncs; i++ ) 00101 p->pTops[i] = reoTransferNodesToUnits_rec( p, Funcs[i] ); 00102 assert( p->nNodesBeg == p->nNodesCur ); 00103 00104 if ( !p->fThisIsAdd && p->fMinWidth ) 00105 { 00106 printf( "An important message from the REO reordering engine:\n" ); 00107 printf( "The BDD given to the engine for reordering contains complemented edges.\n" ); 00108 printf( "Currently, such BDDs cannot be reordered for the minimum width.\n" ); 00109 printf( "Therefore, minimization for the number of BDD nodes is performed.\n" ); 00110 fflush( stdout ); 00111 p->fMinApl = 0; 00112 p->fMinWidth = 0; 00113 } 00114 00115 if ( p->fMinWidth ) 00116 reoProfileWidthStart(p); 00117 else if ( p->fMinApl ) 00118 reoProfileAplStart(p); 00119 else 00120 reoProfileNodesStart(p); 00121 00122 if ( p->fVerbose ) 00123 { 00124 printf( "INITIAL: " ); 00125 if ( p->fMinWidth ) 00126 reoProfileWidthPrint(p); 00127 else if ( p->fMinApl ) 00128 reoProfileAplPrint(p); 00129 else 00130 reoProfileNodesPrint(p); 00131 } 00132 00134 // performs the reordering 00135 p->nSwaps = 0; 00136 p->nNISwaps = 0; 00137 for ( i = 0; i < p->nIters; i++ ) 00138 { 00139 reoReorderSift( p ); 00140 // print statistics after each iteration 00141 if ( p->fVerbose ) 00142 { 00143 printf( "ITER #%d: ", i+1 ); 00144 if ( p->fMinWidth ) 00145 reoProfileWidthPrint(p); 00146 else if ( p->fMinApl ) 00147 reoProfileAplPrint(p); 00148 else 00149 reoProfileNodesPrint(p); 00150 } 00151 // if the cost function did not change, stop iterating 00152 if ( p->fMinWidth ) 00153 { 00154 p->nWidthEnd = p->nWidthCur; 00155 assert( p->nWidthEnd <= p->nWidthBeg ); 00156 if ( p->nWidthEnd == p->nWidthBeg ) 00157 break; 00158 } 00159 else if ( p->fMinApl ) 00160 { 00161 p->nAplEnd = p->nAplCur; 00162 assert( p->nAplEnd <= p->nAplBeg ); 00163 if ( p->nAplEnd == p->nAplBeg ) 00164 break; 00165 } 00166 else 00167 { 00168 p->nNodesEnd = p->nNodesCur; 00169 assert( p->nNodesEnd <= p->nNodesBeg ); 00170 if ( p->nNodesEnd == p->nNodesBeg ) 00171 break; 00172 } 00173 } 00174 assert( reoCheckLevels( p ) ); 00176 00177 s_AplBefore = p->nAplBeg; 00178 s_AplAfter = p->nAplEnd; 00179 00180 // set the initial parameters 00181 p->nRefNodes = 0; 00182 p->nNodesCur = 0; 00183 p->Signature++; 00184 // transfer the BDDs from REO's internal data structure to CUDD 00185 for ( i = 0; i < nFuncs; i++ ) 00186 { 00187 FuncsRes[i] = reoTransferUnitsToNodes_rec( p, p->pTops[i] ); Cudd_Ref( FuncsRes[i] ); 00188 } 00189 // undo the DDs referenced for storing in the cache 00190 for ( i = 0; i < p->nRefNodes; i++ ) 00191 Cudd_RecursiveDeref( dd, p->pRefNodes[i] ); 00192 // verify zero refs of the terminal nodes 00193 for ( i = 0; i < nFuncs; i++ ) 00194 { 00195 assert( reoRecursiveDeref( p->pTops[i] ) ); 00196 } 00197 assert( reoCheckZeroRefs( &(p->pPlanes[p->nSupp]) ) ); 00198 00199 // prepare the variable map to return to the user 00200 if ( p->pOrder ) 00201 { 00202 // i is the current level in the planes data structure 00203 // p->pOrderInt[i] is the original level in the planes data structure 00204 // p->pMapToDdVarsOrig[i] is the variable, into which we remap when we construct the BDD from planes 00205 // p->pMapToDdVarsOrig[ p->pOrderInt[i] ] is the original BDD variable corresponding to this level 00206 // Therefore, p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ] 00207 // creates the permutation, which remaps the resulting BDD variable into the original BDD variable 00208 for ( i = 0; i < p->nSupp; i++ ) 00209 p->pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ]; 00210 } 00211 00212 if ( p->fVerify ) 00213 { 00214 int fVerification; 00215 DdNode * FuncRemapped; 00216 int * pOrder; 00217 00218 if ( p->pOrder == NULL ) 00219 { 00220 pOrder = ALLOC( int, p->nSupp ); 00221 for ( i = 0; i < p->nSupp; i++ ) 00222 pOrder[ p->pMapToDdVarsFinal[i] ] = p->pMapToDdVarsOrig[ p->pOrderInt[i] ]; 00223 } 00224 else 00225 pOrder = p->pOrder; 00226 00227 fVerification = 1; 00228 for ( i = 0; i < nFuncs; i++ ) 00229 { 00230 // verify the result 00231 if ( p->fThisIsAdd ) 00232 FuncRemapped = Cudd_addPermute( dd, FuncsRes[i], pOrder ); 00233 else 00234 FuncRemapped = Cudd_bddPermute( dd, FuncsRes[i], pOrder ); 00235 Cudd_Ref( FuncRemapped ); 00236 00237 if ( FuncRemapped != Funcs[i] ) 00238 { 00239 fVerification = 0; 00240 printf( "REO: Internal verification has failed!\n" ); 00241 fflush( stdout ); 00242 } 00243 Cudd_RecursiveDeref( dd, FuncRemapped ); 00244 } 00245 if ( fVerification ) 00246 printf( "REO: Internal verification is okay!\n" ); 00247 00248 if ( p->pOrder == NULL ) 00249 free( pOrder ); 00250 } 00251 00252 // recycle the data structure 00253 for ( i = 0; i <= p->nSupp; i++ ) 00254 reoUnitsRecycleUnitList( p, p->pPlanes + i ); 00255 }
void reoResizeStructures | ( | reo_man * | p, | |
int | nDdVarsMax, | |||
int | nNodesMax, | |||
int | nFuncs | |||
) |
Function*************************************************************
Synopsis [Resizes the internal manager data structures.]
Description []
SideEffects []
SeeAlso []
Definition at line 268 of file reoCore.c.
00269 { 00270 // resize data structures depending on the number of variables in the DD manager 00271 if ( p->nSuppAlloc == 0 ) 00272 { 00273 p->pSupp = ALLOC( int, nDdVarsMax + 1 ); 00274 p->pOrderInt = ALLOC( int, nDdVarsMax + 1 ); 00275 p->pMapToPlanes = ALLOC( int, nDdVarsMax + 1 ); 00276 p->pMapToDdVarsOrig = ALLOC( int, nDdVarsMax + 1 ); 00277 p->pMapToDdVarsFinal = ALLOC( int, nDdVarsMax + 1 ); 00278 p->pPlanes = CALLOC( reo_plane, nDdVarsMax + 1 ); 00279 p->pVarCosts = ALLOC( double, nDdVarsMax + 1 ); 00280 p->pLevelOrder = ALLOC( int, nDdVarsMax + 1 ); 00281 p->nSuppAlloc = nDdVarsMax + 1; 00282 } 00283 else if ( p->nSuppAlloc < nDdVarsMax ) 00284 { 00285 free( p->pSupp ); 00286 free( p->pOrderInt ); 00287 free( p->pMapToPlanes ); 00288 free( p->pMapToDdVarsOrig ); 00289 free( p->pMapToDdVarsFinal ); 00290 free( p->pPlanes ); 00291 free( p->pVarCosts ); 00292 free( p->pLevelOrder ); 00293 00294 p->pSupp = ALLOC( int, nDdVarsMax + 1 ); 00295 p->pOrderInt = ALLOC( int, nDdVarsMax + 1 ); 00296 p->pMapToPlanes = ALLOC( int, nDdVarsMax + 1 ); 00297 p->pMapToDdVarsOrig = ALLOC( int, nDdVarsMax + 1 ); 00298 p->pMapToDdVarsFinal = ALLOC( int, nDdVarsMax + 1 ); 00299 p->pPlanes = CALLOC( reo_plane, nDdVarsMax + 1 ); 00300 p->pVarCosts = ALLOC( double, nDdVarsMax + 1 ); 00301 p->pLevelOrder = ALLOC( int, nDdVarsMax + 1 ); 00302 p->nSuppAlloc = nDdVarsMax + 1; 00303 } 00304 00305 // resize the data structures depending on the number of nodes 00306 if ( p->nRefNodesAlloc == 0 ) 00307 { 00308 p->nNodesMaxAlloc = nNodesMax; 00309 p->nTableSize = 3*nNodesMax + 1; 00310 p->nRefNodesAlloc = 3*nNodesMax + 1; 00311 p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1; 00312 00313 p->HTable = CALLOC( reo_hash, p->nTableSize ); 00314 p->pRefNodes = ALLOC( DdNode *, p->nRefNodesAlloc ); 00315 p->pWidthCofs = ALLOC( reo_unit *, p->nRefNodesAlloc ); 00316 p->pMemChunks = ALLOC( reo_unit *, p->nMemChunksAlloc ); 00317 } 00318 else if ( p->nNodesMaxAlloc < nNodesMax ) 00319 { 00320 void * pTemp; 00321 int nMemChunksAllocPrev = p->nMemChunksAlloc; 00322 00323 p->nNodesMaxAlloc = nNodesMax; 00324 p->nTableSize = 3*nNodesMax + 1; 00325 p->nRefNodesAlloc = 3*nNodesMax + 1; 00326 p->nMemChunksAlloc = (10*nNodesMax + 1)/REO_CHUNK_SIZE + 1; 00327 00328 free( p->HTable ); 00329 free( p->pRefNodes ); 00330 free( p->pWidthCofs ); 00331 p->HTable = CALLOC( reo_hash, p->nTableSize ); 00332 p->pRefNodes = ALLOC( DdNode *, p->nRefNodesAlloc ); 00333 p->pWidthCofs = ALLOC( reo_unit *, p->nRefNodesAlloc ); 00334 // p->pMemChunks should be reallocated because it contains pointers currently in use 00335 pTemp = ALLOC( reo_unit *, p->nMemChunksAlloc ); 00336 memmove( pTemp, p->pMemChunks, sizeof(reo_unit *) * nMemChunksAllocPrev ); 00337 free( p->pMemChunks ); 00338 p->pMemChunks = pTemp; 00339 } 00340 00341 // resize the data structures depending on the number of functions 00342 if ( p->nTopsAlloc == 0 ) 00343 { 00344 p->pTops = ALLOC( reo_unit *, nFuncs ); 00345 p->nTopsAlloc = nFuncs; 00346 } 00347 else if ( p->nTopsAlloc < nFuncs ) 00348 { 00349 free( p->pTops ); 00350 p->pTops = ALLOC( reo_unit *, nFuncs ); 00351 p->nTopsAlloc = nFuncs; 00352 } 00353 }
double s_AplAfter |
double s_AplBefore |