src/bdd/reo/reoCore.c File Reference

#include "reo.h"
Include dependency graph for reoCore.c:

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 Documentation

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

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

] DECLARATIONS ///

Definition at line 25 of file reoCore.c.


Function Documentation

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 []

Definition at line 393 of file reoCore.c.

00394 {
00395         reo_unit * pUnit;
00396         for ( pUnit = pPlane->pHead; pUnit; pUnit = pUnit->Next )
00397         {
00398                 if ( pUnit->n != 0 )
00399                 {
00400                         assert( 0 );
00401                 }
00402         }
00403         return 1;
00404 }

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 }


Variable Documentation

double s_AplAfter

Definition at line 32 of file reoCore.c.

double s_AplBefore

Definition at line 31 of file reoCore.c.


Generated on Tue Jan 5 12:19:01 2010 for abc70930 by  doxygen 1.6.1