src/bdd/reo/reoSift.c File Reference

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

Go to the source code of this file.

Functions

void reoReorderSift (reo_man *p)

Function Documentation

void reoReorderSift ( reo_man p  ) 

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

] DECLARATIONS /// 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 41 of file reoSift.c.

00042 {
00043         double CostCurrent;  // the cost of the current permutation
00044         double CostLimit;    // the maximum increase in cost that can be tolerated
00045         double CostBest;     // the best cost
00046         int BestQ;           // the best position
00047         int VarCurrent;      // the current variable to move   
00048         int q;               // denotes the current position of the variable
00049         int c;               // performs the loops over variables until all of them are sifted
00050         int v;               // used for other purposes
00051 
00052         assert( p->nSupp > 0 );
00053 
00054         // set the current cost depending on the minimization criteria
00055         if ( p->fMinWidth )
00056                 CostCurrent = p->nWidthCur;
00057         else if ( p->fMinApl )
00058                 CostCurrent = p->nAplCur;
00059         else
00060                 CostCurrent = p->nNodesCur;
00061 
00062         // find the upper bound on tbe cost growth
00063         CostLimit = 1 + (int)(REO_REORDER_LIMIT * CostCurrent);
00064 
00065         // perform sifting for each of p->nSupp variables
00066         for ( c = 0; c < p->nSupp; c++ )
00067         {
00068                 // select the current variable to be the one with the largest number of nodes that is not sifted yet
00069                 VarCurrent = -1;
00070                 CostBest   = -1.0;
00071                 for ( v = 0; v < p->nSupp; v++ )
00072                 {
00073                         p->pVarCosts[v] = REO_HIGH_VALUE;
00074                         if ( !p->pPlanes[v].fSifted )
00075                         {
00076 //                              VarCurrent = v;
00077 //                              if ( CostBest < p->pPlanes[v].statsCost )
00078                                 if ( CostBest < p->pPlanes[v].statsNodes )
00079                                 {
00080 //                                      CostBest   = p->pPlanes[v].statsCost;
00081                                         CostBest   = p->pPlanes[v].statsNodes;
00082                                         VarCurrent = v;
00083                                 }
00084 
00085                         }
00086                 }
00087                 assert( VarCurrent != -1 );
00088                 // mark this variable as sifted
00089                 p->pPlanes[VarCurrent].fSifted = 1;
00090 
00091                 // set the current value
00092                 p->pVarCosts[VarCurrent] = CostCurrent;
00093 
00094                 // set the best cost
00095                 CostBest = CostCurrent;
00096                 BestQ    = VarCurrent; 
00097 
00098                 // determine which way to move the variable first (up or down)
00099                 // the rationale is that if we move the shorter way first
00100                 // it is more likely that the best position will be found on the longer way
00101                 // and the reverse movement (to take the best position) will be faster
00102                 if ( VarCurrent < p->nSupp/2 ) // move up first, then down
00103                 {
00104                         // set the total cost on all levels above the current level
00105                         p->pPlanes[0].statsCostAbove = 0;
00106                         for ( v = 1; v <= VarCurrent; v++ )
00107                                 p->pPlanes[v].statsCostAbove = p->pPlanes[v-1].statsCostAbove + p->pPlanes[v-1].statsCost;
00108                         // set the total cost on all levels below the current level
00109                         p->pPlanes[p->nSupp].statsCostBelow = 0;
00110                         for ( v = p->nSupp - 1; v >= VarCurrent; v-- )
00111                                 p->pPlanes[v].statsCostBelow = p->pPlanes[v+1].statsCostBelow + p->pPlanes[v+1].statsCost;
00112 
00113                         assert( CostCurrent == p->pPlanes[VarCurrent].statsCostAbove + 
00114                                                                         p->pPlanes[VarCurrent].statsCost +
00115                                                     p->pPlanes[VarCurrent].statsCostBelow );
00116 
00117                         // move up
00118                         for ( q = VarCurrent-1; q >= 0; q-- )
00119                         {
00120                                 CostCurrent -= reoReorderSwapAdjacentVars( p, q, 1 );
00121                                 // now q points to the position of this var in the order
00122                                 p->pVarCosts[q] = CostCurrent;
00123                                 // update the lower bound (assuming that for level q+1 it is set correctly)
00124                                 p->pPlanes[q].statsCostBelow = p->pPlanes[q+1].statsCostBelow + p->pPlanes[q+1].statsCost;
00125                                 // check the upper bound
00126                                 if ( CostCurrent >= CostLimit )
00127                                         break;
00128                                 // check the lower bound
00129                                 if ( p->pPlanes[q].statsCostBelow + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostAbove/REO_QUAL_PAR >= CostBest )
00130                                         break;
00131                                 // update the best cost
00132                                 if ( CostBest > CostCurrent )
00133                                 {
00134                                         CostBest = CostCurrent;
00135                                         BestQ    = q;
00136                                         // adjust node limit
00137                                         CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
00138                                 }
00139 
00140                                 // when we are reordering for width or APL, it may happen that
00141                                 // the number of nodes has grown above certain limit,
00142                                 // in which case we have to resize the data structures
00143                                 if ( p->fMinWidth || p->fMinApl )
00144                                 {
00145                                         if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
00146                                         {
00147 //                                              printf( "Resizing data structures. Old size = %6d. New size = %6d.\n",  p->nNodesMaxAlloc, p->nNodesCur );
00148                                                 reoResizeStructures( p, 0, p->nNodesCur, 0 );
00149                                         }
00150                                 }
00151                         }
00152                         // fix the plane index
00153                         if ( q == -1 )
00154                                 q++;
00155                         // now p points to the position of this var in the order
00156 
00157                         // move down
00158                         for ( ; q < p->nSupp-1; )
00159                         {
00160                                 CostCurrent -= reoReorderSwapAdjacentVars( p, q, 0 );
00161                                 q++;    // change q to point to the position of this var in the order
00162                                 // sanity check: the number of nodes on the back pass should be the same
00163                                 if ( p->pVarCosts[q] != REO_HIGH_VALUE && fabs( p->pVarCosts[q] - CostCurrent ) > REO_COST_EPSILON )
00164                                         printf("reoReorderSift(): Error! On the backward move, the costs are different.\n");
00165                                 p->pVarCosts[q] = CostCurrent;
00166                                 // update the lower bound (assuming that for level q-1 it is set correctly)
00167                                 p->pPlanes[q].statsCostAbove = p->pPlanes[q-1].statsCostAbove + p->pPlanes[q-1].statsCost;
00168                                 // check the bounds only if the variable already reached its previous position
00169                                 if ( q >= BestQ )
00170                                 {
00171                                         // check the upper bound
00172                                         if ( CostCurrent >= CostLimit )
00173                                                 break;
00174                                         // check the lower bound
00175                                         if ( p->pPlanes[q].statsCostAbove + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostBelow/REO_QUAL_PAR >= CostBest )
00176                                                 break;
00177                                 }
00178                                 // update the best cost
00179                                 if ( CostBest >= CostCurrent )
00180                                 {
00181                                         CostBest = CostCurrent;
00182                                         BestQ    = q;
00183                                         // adjust node limit
00184                                         CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
00185                                 }
00186 
00187                                 // when we are reordering for width or APL, it may happen that
00188                                 // the number of nodes has grown above certain limit,
00189                                 // in which case we have to resize the data structures
00190                                 if ( p->fMinWidth || p->fMinApl )
00191                                 {
00192                                         if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
00193                                         {
00194 //                                              printf( "Resizing data structures. Old size = %6d. New size = %6d.\n",  p->nNodesMaxAlloc, p->nNodesCur );
00195                                                 reoResizeStructures( p, 0, p->nNodesCur, 0 );
00196                                         }
00197                                 }
00198                         }
00199                         // move the variable up from the given position (q) to the best position (BestQ)
00200                         assert( q >= BestQ );
00201                         for ( ; q > BestQ; q-- )
00202                         {
00203                                 CostCurrent -= reoReorderSwapAdjacentVars( p, q-1, 1 );
00204                                 // sanity check: the number of nodes on the back pass should be the same
00205                                 if ( fabs( p->pVarCosts[q-1] - CostCurrent ) > REO_COST_EPSILON )
00206                                 {
00207                                         printf("reoReorderSift():  Error! On the return move, the costs are different.\n" );
00208                                         fflush(stdout);
00209                                 }
00210                         }
00211                 }
00212                 else // move down first, then up
00213                 {
00214                         // set the current number of nodes on all levels above the given level
00215                         p->pPlanes[0].statsCostAbove = 0;
00216                         for ( v = 1; v <= VarCurrent; v++ )
00217                                 p->pPlanes[v].statsCostAbove = p->pPlanes[v-1].statsCostAbove + p->pPlanes[v-1].statsCost;
00218                         // set the current number of nodes on all levels below the given level
00219                         p->pPlanes[p->nSupp].statsCostBelow = 0;
00220                         for ( v = p->nSupp - 1; v >= VarCurrent; v-- )
00221                                 p->pPlanes[v].statsCostBelow = p->pPlanes[v+1].statsCostBelow + p->pPlanes[v+1].statsCost;
00222                         
00223                         assert( CostCurrent == p->pPlanes[VarCurrent].statsCostAbove + 
00224                                                                         p->pPlanes[VarCurrent].statsCost +
00225                                                     p->pPlanes[VarCurrent].statsCostBelow );
00226 
00227                         // move down
00228                         for ( q = VarCurrent; q < p->nSupp-1; )
00229                         {
00230                                 CostCurrent -= reoReorderSwapAdjacentVars( p, q, 0 );
00231                                 q++;    // change q to point to the position of this var in the order
00232                                 p->pVarCosts[q] = CostCurrent;
00233                                 // update the lower bound (assuming that for level q-1 it is set correctly)
00234                                 p->pPlanes[q].statsCostAbove = p->pPlanes[q-1].statsCostAbove + p->pPlanes[q-1].statsCost;
00235                                 // check the upper bound
00236                                 if ( CostCurrent >= CostLimit )
00237                                         break;
00238                                 // check the lower bound
00239                                 if ( p->pPlanes[q].statsCostAbove + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostBelow/REO_QUAL_PAR >= CostBest )
00240                                         break;
00241                                 // update the best cost
00242                                 if ( CostBest > CostCurrent )
00243                                 {
00244                                         CostBest = CostCurrent;
00245                                         BestQ    = q;
00246                                         // adjust node limit
00247                                         CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
00248                                 }
00249 
00250                                 // when we are reordering for width or APL, it may happen that
00251                                 // the number of nodes has grown above certain limit,
00252                                 // in which case we have to resize the data structures
00253                                 if ( p->fMinWidth || p->fMinApl )
00254                                 {
00255                                         if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
00256                                         {
00257 //                                              printf( "Resizing data structures. Old size = %6d. New size = %6d.\n",  p->nNodesMaxAlloc, p->nNodesCur );
00258                                                 reoResizeStructures( p, 0, p->nNodesCur, 0 );
00259                                         }
00260                                 }
00261                         }
00262 
00263                         // move up
00264                         for ( --q; q >= 0; q-- )
00265                         {
00266                                 CostCurrent -= reoReorderSwapAdjacentVars( p, q, 1 );
00267                                 // now q points to the position of this var in the order
00268                                 // sanity check: the number of nodes on the back pass should be the same
00269                                 if ( p->pVarCosts[q] != REO_HIGH_VALUE && fabs( p->pVarCosts[q] - CostCurrent ) > REO_COST_EPSILON )
00270                                         printf("reoReorderSift(): Error! On the backward move, the costs are different.\n");
00271                                 p->pVarCosts[q] = CostCurrent;
00272                                 // update the lower bound (assuming that for level q+1 it is set correctly)
00273                                 p->pPlanes[q].statsCostBelow = p->pPlanes[q+1].statsCostBelow + p->pPlanes[q+1].statsCost;
00274                                 // check the bounds only if the variable already reached its previous position
00275                                 if ( q <= BestQ )
00276                                 {
00277                                         // check the upper bound
00278                                         if ( CostCurrent >= CostLimit )
00279                                                 break;
00280                                         // check the lower bound
00281                                         if ( p->pPlanes[q].statsCostBelow + (REO_QUAL_PAR-1)*p->pPlanes[q].statsCostAbove/REO_QUAL_PAR >= CostBest )
00282                                                 break;
00283                                 }
00284                                 // update the best cost
00285                                 if ( CostBest >= CostCurrent )
00286                                 {
00287                                         CostBest = CostCurrent;
00288                                         BestQ    = q;
00289                                         // adjust node limit
00290                                         CostLimit = ddMin( CostLimit, 1 + (int)(REO_REORDER_LIMIT * CostCurrent) );
00291                                 }
00292 
00293                                 // when we are reordering for width or APL, it may happen that
00294                                 // the number of nodes has grown above certain limit,
00295                                 // in which case we have to resize the data structures
00296                                 if ( p->fMinWidth || p->fMinApl )
00297                                 {
00298                                         if ( p->nNodesCur >= 2 * p->nNodesMaxAlloc )
00299                                         {
00300 //                                              printf( "Resizing data structures. Old size = %6d. New size = %6d.\n",  p->nNodesMaxAlloc, p->nNodesCur );
00301                                                 reoResizeStructures( p, 0, p->nNodesCur, 0 );
00302                                         }
00303                                 }
00304                         }
00305                         // fix the plane index
00306                         if ( q == -1 )
00307                                 q++;
00308                         // now q points to the position of this var in the order
00309                         // move the variable down from the given position (q) to the best position (BestQ)
00310                         assert( q <= BestQ );
00311                         for ( ; q < BestQ; q++ )
00312                         {
00313                                 CostCurrent -= reoReorderSwapAdjacentVars( p, q, 0 );
00314                                 // sanity check: the number of nodes on the back pass should be the same
00315                                 if ( fabs( p->pVarCosts[q+1] - CostCurrent ) > REO_COST_EPSILON )
00316                                 {
00317                                         printf("reoReorderSift(): Error! On the return move, the costs are different.\n" );
00318                                         fflush(stdout);
00319                                 }
00320                         }
00321                 }
00322                 assert( fabs( CostBest - CostCurrent ) < REO_COST_EPSILON );
00323 
00324                 // update the cost 
00325                 if ( p->fMinWidth )
00326                         p->nWidthCur = (int)CostBest;
00327                 else if ( p->fMinApl )
00328                         p->nAplCur = CostCurrent;
00329                 else
00330                         p->nNodesCur = (int)CostBest;
00331         }
00332 
00333         // remove the sifted attributes if any
00334         for ( v = 0; v < p->nSupp; v++ )
00335                 p->pPlanes[v].fSifted = 0;
00336 }


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