#include "reo.h"
Go to the source code of this file.
Functions | |
void | reoReorderSift (reo_man *p) |
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 [
] 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 }