Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members

Annealer.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002 ***    
00003 *** Copyright (c) 1995-2000 Regents of the University of California,
00004 ***               Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov
00005 *** Copyright (c) 2000-2004 Regents of the University of Michigan,
00006 ***               Saurabh N. Adya, Jarrod A. Roy and Igor L. Markov
00007 ***
00008 ***  Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu
00009 ***  Original Affiliation:   UCLA, Computer Science Department,
00010 ***                          Los Angeles, CA 90095-1596 USA
00011 ***
00012 ***  Permission is hereby granted, free of charge, to any person obtaining 
00013 ***  a copy of this software and associated documentation files (the
00014 ***  "Software"), to deal in the Software without restriction, including
00015 ***  without limitation 
00016 ***  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00017 ***  and/or sell copies of the Software, and to permit persons to whom the 
00018 ***  Software is furnished to do so, subject to the following conditions:
00019 ***
00020 ***  The above copyright notice and this permission notice shall be included
00021 ***  in all copies or substantial portions of the Software.
00022 ***
00023 *** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00024 *** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00025 *** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00026 *** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00027 *** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
00028 *** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00029 *** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00030 ***
00031 ***
00032 ***************************************************************************/
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 #include "FPcommon.h"
00048 #include "PlToSP.h"
00049 #include "Annealer.h"
00050 #include "CommandLine.h"
00051 #include "ABKCommon/infolines.h"
00052 
00053 using namespace parquetfp;
00054 
00055 #define VANILLA
00056 
00057 Annealer::Annealer(const Command_Line *const params,
00058                    DB *const db)
00059    : BaseAnnealer(params, db),
00060      _sp(new SeqPair(_db->getNumNodes())),
00061      _spEval(new SPeval(_db->getNodes()->getNodeHeights(),
00062                         _db->getNodes()->getNodeWidths(),
00063                         _params->useFastSP))     
00064 {}
00065 
00066 Annealer::~Annealer()
00067 {
00068    if(_sp != NULL)  delete _sp;
00069    if(_spEval != NULL) delete _spEval;
00070 }
00071 
00072 void Annealer::compactSoln()
00073 {
00074    eval();
00075    double currArea = getXSize() * getYSize();
00076    double lastArea = currArea;
00077    
00078    bool whichDir = false;
00079    evalCompact(whichDir);
00080    do
00081    {
00082       whichDir = !whichDir;
00083       takeSPfromDB();
00084       evalCompact(whichDir);
00085 
00086       lastArea = currArea;
00087       currArea = getXSize() * getYSize();
00088       if(_params->verb.forMajStats > 0)
00089          cout << "area: " << lastArea << " -> " << currArea << endl;
00090    }
00091    while(int(currArea) < int(lastArea));
00092 }
00093 
00094 void Annealer::takePlfromDB()
00095 {
00096    takeSPfromDB();
00097    eval();
00098 }
00099 
00100 void Annealer::takeSPfromDB()  //converts the present placement to a sequence pair
00101 {
00102    vector<double> heights = _db->getNodeHeights();
00103    vector<double> widths = _db->getNodeWidths();
00104    vector<double> xloc = _db->getXLocs();
00105    vector<double> yloc = _db->getYLocs();
00106 
00107    PL2SP_ALGO useAlgo = TCG_ALGO;
00108    Pl2SP pl2sp(xloc, yloc, widths, heights, useAlgo);
00109    _sp->putX(pl2sp.getXSP());
00110    _sp->putY(pl2sp.getYSP());
00111    _spEval->changeWidths(widths);
00112    _spEval->changeHeights(heights);
00113 }
00114 
00115 bool Annealer::go()
00116 {
00117    MaxMem::update("Parquet before annealing");
00118 
00119    Timer T;
00120    T.stop();
00121    T.start(0.0);
00122    anneal();
00123    T.stop();
00124 
00125    annealTime += T.getUserTime();
00126 
00127    _spEval->evaluate(_sp->getX(), _sp->getY());
00128    _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00129 
00130    if(_params->softBlocks)
00131    {
00132       //cout<<"Before area is "<<_spEval->xSize*_spEval->ySize<<endl;
00133       packSoftBlocks(100);
00134       _spEval->evaluate(_sp->getX(), _sp->getY());
00135       _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00136    }
00137    _spEval->evalSlacks(_sp->getX(), _sp->getY());
00138    
00139    /*
00140    int blocknum = _sp->getX().size();
00141    vector<double> xSlacks(blocknum); // absolute x-slacks
00142    vector<double> ySlacks(blocknum); // absolute y-slacks
00143    for (int i = 0; i < blocknum; i++)
00144    {
00145       xSlacks[i] = (_spEval->xSlacks[i]/100) * _spEval->xSize;
00146       ySlacks[i] = (_spEval->ySlacks[i]/100) * _spEval->ySize;
00147    }      
00148    _db->updateSlacks(xSlacks, ySlacks);
00149    */
00150    _db->updateSlacks(_spEval->xSlacks, _spEval->ySlacks);
00151    
00152    SolutionInfo currSoln;
00153    currSoln.area =  _spEval->xSize*_spEval->ySize;
00154    currSoln.width = _spEval->xSize;
00155    currSoln.height = _spEval->ySize;
00156    currSoln.HPWL = _db->evalHPWL();
00157    printResults(T, currSoln);
00158    
00159    return true;
00160 }
00161 
00162 void Annealer::updatePlacement(void)
00163 {
00164    _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00165 }
00166 
00167 void Annealer::eval(void)
00168 {
00169    _spEval->evaluate(_sp->getX(), _sp->getY());
00170    _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00171 }
00172 
00173 void Annealer::evalSlacks(void)
00174 {
00175    _spEval->evalSlacks(_sp->getX(), _sp->getY());
00176    _db->updateSlacks(_spEval->xSlacks, _spEval->ySlacks);
00177 }
00178 
00179 void Annealer::evalCompact(bool whichDir)
00180 {
00181    _spEval->evaluateCompact(_sp->getX(), _sp->getY(), whichDir);
00182    _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00183 }
00184 
00185 void Annealer::anneal()
00186 { 
00187    bool budgetTime = _params->budgetTime;
00188    double seconds = _params->seconds;
00189   
00190    vector<unsigned> tempX, tempY;
00191    vector<unsigned> vddX, vddY;
00192 
00193    bool minWL = _params->minWL;
00194    double wireWeight = _params->wireWeight;
00195    double areaWeight = _params->areaWeight;
00196    double ARWeight = 1 - areaWeight - wireWeight;
00197    if(ARWeight < 0)
00198       ARWeight = 0;
00199 
00200    double tempArea = 0;
00201    double tempHeight = 0;
00202    double tempWidth = 0;
00203    double tempAR=0;
00204    double bestHPWL = 1e100;
00205    double bestArea = 1e100;
00206    double currArea = 1e100;
00207    double deltaArea = 0, deltaAR, delta;
00208    double blocksArea = _db->getNodesArea();
00209    double currHeight = 1;
00210    double currWidth = 1;
00211    double currTime = _params->startTime;
00212    double size = _sp->getX().size();
00213    double alpha = 0, r;
00214    double reqdAR = _params->reqdAR, currAR;
00215    int move = 0, test=0,count=0, ran, finalPower = 100, prevPower = 100, prevNumIslands = 0, prevNodesInIslands = 0, prevMaxIsland = 0;
00216    SetOfVoltages islandSetIn;
00217    unsigned timeChangeCtr = 0;
00218    unsigned indexOrient = 0, moveSelect, iter, masterMoveSel=0; 
00219    parquetfp::ORIENT newOrient = N; 
00220    parquetfp::ORIENT oldOrient = N;
00221    double oldWidth=0, oldHeight=0, newWidth=0, newHeight=0;
00222    bool moveAccepted=0;
00223  
00224    const double reqdArea = blocksArea * (1+(_params->maxWS/100.0));
00225    const double reqdWidth = sqrt(reqdArea*reqdAR);
00226    const double reqdHeight = reqdWidth/reqdAR;
00227 
00228    bool brokeFromLoop;
00229 
00230    double tempHPWL=1e100;
00231    double currHPWL=1e100;
00232    double deltaHPWL=0;
00233   
00234    unsigned numNodes = _db->getNumNodes();
00235    bool updatedBestSoln=false;
00236    Point dummy;
00237    dummy.x=0;
00238    dummy.y=0;
00239    vector<Point> bestSolnPl(numNodes, dummy);
00240    vector<parquetfp::ORIENT> bestSolnOrient(numNodes, N);
00241    vector<double> bestSolnWidth(numNodes, 0);
00242    vector<double> bestSolnHeight(numNodes, 0);
00243    vector<unsigned> bestXSP(numNodes, 0);
00244    vector<unsigned> bestYSP(numNodes, 0);
00245 //    const vector<unsigned>& spX = _sp->getX();
00246 //    const vector<unsigned>& spY = _sp->getY();
00247 
00248    Timer looptm;
00249    looptm.stop();
00250    double unit=0, total=seconds, percent=1;
00251    unsigned moves=2000;
00252 here: currTime = _params->startTime;
00253    while(currTime>_params->timeCool || budgetTime)
00254    {
00255       brokeFromLoop = 0;
00256       iter=0;
00257       do
00258       {
00259          if (budgetTime)
00260          {
00261             if (count==0)
00262             {
00263                looptm.start(0.0);
00264             }
00265             else if (count==1000)
00266             {  
00267                looptm.stop();
00268                unit=looptm.getUserTime()/1000;
00269                if(unit == 0)
00270                {
00271                   unit = 10e-6;
00272                }
00273                seconds-=looptm.getUserTime();
00274                if(_params->verb.forMajStats > 0)
00275                   cout<<int(seconds/unit)<<" moves left with "<<
00276                         unit*1000000<<" micro seconds per move.\n";
00277                moves=unsigned(seconds/unit/125.0);//moves every .08 degree
00278             }
00279             else if (count > 1000)
00280             {
00281                seconds-=unit;
00282                if (seconds <= 0)
00283                {
00284                   brokeFromLoop=1;
00285                   break;
00286                   //return;
00287                }
00288             }
00289          }
00290          else
00291          {
00292             if (count==0)
00293             {
00294                looptm.start(0.0);
00295             }
00296             else if (count==1000)
00297             {  
00298                looptm.stop();
00299                unit=looptm.getUserTime()/1000;
00300                if(unit == 0)
00301                {
00302                   unit = 10e-6;
00303                }
00304                if(_params->verb.forMajStats > 0)
00305                   cout << (unit*1000000) << " micro seconds per move." << endl;
00306             }
00307          }
00308           
00309          ++count; 
00310          ++iter;
00311           
00312          tempX = _sp->getX();
00313          tempY = _sp->getY();
00314 
00315 //       cout << "voltage of node " << indexOrient << " is: " << _db->getNodes()->getNode(indexOrient).getVoltage() << endl;
00316 
00317          //select the types of moves here
00318          if(_params->softBlocks && currTime < 30)
00319             masterMoveSel = rand()%1000;
00320          moveSelect = rand()%1000;
00321 
00322          currAR = currWidth/currHeight;
00323          move = -1;
00324 
00325 #ifdef VANILLA
00326          if(_params->softBlocks && masterMoveSel > 990)
00327             move = packSoftBlocks(2);
00328          else if(_params->softBlocks && masterMoveSel > 930)
00329             move = makeSoftBlMove(tempX, tempY, indexOrient, newWidth, 
00330                                   newHeight);
00331          else if(((reqdAR-currAR)/reqdAR > 0.00005 || 
00332                   (currAR-reqdAR)/reqdAR > 0.00005) && 
00333                  (timeChangeCtr%4)==0 && reqdAR != -9999)
00334             move = makeARMove(tempX, tempY, currAR);
00335          else if(moveSelect < 150 && minWL == 1 && reqdAR != -9999)
00336             move = makeARWLMove(tempX, tempY, currAR);     
00337          else if(moveSelect < 300 && minWL == 1)
00338             move = makeHPWLMove(tempX, tempY);
00339          else if(moveSelect < 500)
00340             move = makeMoveOrient(indexOrient, oldOrient, newOrient);
00341          else
00342             move = makeMove(tempX, tempY);
00343 #else
00344          if(_params->softBlocks && masterMoveSel > 470)
00345             move = packSoftBlocks(2);
00346          else if(_params->softBlocks && masterMoveSel > 400)
00347             move = makeSoftBlMove(tempX, tempY, indexOrient, newWidth, 
00348                                   newHeight);
00349          else if(((reqdAR-currAR)/reqdAR > 0.00007 || 
00350                   (currAR-reqdAR)/reqdAR >0.00005) 
00351                  && (timeChangeCtr%2)==0 && reqdAR != -9999)
00352             move = makeARMove(tempX, tempY, currAR);
00353          else if(moveSelect < 150 && minWL == 1 && reqdAR != -9999)
00354             move = makeARWLMove(tempX, tempY, currAR);
00355          else if(moveSelect < 300 && minWL == 1)
00356             move = makeHPWLMove(tempX, tempY);
00357          else if(moveSelect < 400)
00358             move = makeMoveSlacks(tempX, tempY);
00359          else if(moveSelect < 600)
00360             move = makeMoveSlacksOrient(tempX, tempY, indexOrient, oldOrient, 
00361                                         newOrient);
00362          else if(moveSelect < 700)
00363             move = makeMoveOrient(indexOrient, oldOrient, newOrient);
00364          else
00365             move = makeMove(tempX, tempY);
00366 #endif
00367 
00368          //for orientation moves
00369          if(move == 10)
00370          {
00371             if(oldOrient%2 != newOrient%2)
00372                _spEval->changeOrient(indexOrient);
00373 
00374             if(minWL)
00375                _db->getNodes()->changeOrient(indexOrient, newOrient,
00376                                              *(_db->getNets())); 
00377          }
00378          if(move == 11)  //softBlocks move
00379          {
00380             oldHeight = _db->getNodes()->getNodeHeight(indexOrient);
00381             oldWidth = _db->getNodes()->getNodeWidth(indexOrient);
00382             _spEval->changeNodeWidth(indexOrient, newWidth);
00383             _spEval->changeNodeHeight(indexOrient, newHeight);
00384          }
00385 
00386          _spEval->evaluate(tempX, tempY);
00387          tempHeight = _spEval->ySize;
00388          tempWidth = _spEval->xSize;
00389          tempArea = tempHeight*tempWidth;
00390          tempAR = tempWidth/tempHeight;
00391 
00392          /*area objective*/
00393           
00394          if(currTime>30)
00395             deltaArea=((tempArea-currArea)*1.2*_params->timeInit)/blocksArea;
00396          else
00397             deltaArea=((tempArea-currArea)*1.5*_params->timeInit)/blocksArea;
00398             
00399          /* x-viol + y-viol objective
00400             deltaArea=0.5*1.3*_params->timeInit*((tempHeight-currHeight)/(reqdHeight)+(tempWidth-currWidth)/(reqdWidth));
00401          */
00402 
00403          /*max(x-viol, y-viol) objective
00404            if((tempHeight-currHeight)>(tempWidth-currWidth))
00405            deltaArea=((tempHeight-currHeight)*1.3*_params->timeInit)/(reqdHeight);
00406            else
00407            deltaArea=((tempWidth-currWidth)*1.3*_params->timeInit)/(reqdWidth);
00408          */
00409           
00410          delta = deltaArea;
00411 
00412          _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00413          if(minWL)
00414          {
00415             tempHPWL = _db->evalHPWL();
00416 
00417             if(currHPWL == 0)
00418                deltaHPWL = 0;
00419             else
00420              {
00421                if(currTime>30)
00422                  deltaHPWL=((tempHPWL-currHPWL)*1.2*_params->timeInit)/currHPWL;
00423                else
00424                  deltaHPWL=((tempHPWL-currHPWL)*1.5*_params->timeInit)/currHPWL;
00425              }
00426          }
00427 
00428          if(reqdAR != -9999)
00429          {
00430             if(currTime>30)
00431                deltaAR = ((tempAR - reqdAR)*(tempAR - reqdAR) - (currAR - reqdAR)*(currAR - reqdAR))*10*_params->timeInit;
00432             else
00433                deltaAR = ((tempAR - reqdAR)*(tempAR - reqdAR) - (currAR - reqdAR)*(currAR - reqdAR))*10*_params->timeInit;
00434 
00435             //deltaAR = 0;
00436             if(minWL)
00437                delta = areaWeight*deltaArea + wireWeight*deltaHPWL +
00438                   ARWeight*deltaAR;
00439             else
00440                delta = (areaWeight+wireWeight/2.0)*deltaArea + 
00441                   (ARWeight+wireWeight/2.0)*deltaAR;
00442          }
00443          else if(minWL)
00444          {
00445             delta = (areaWeight+ARWeight/2.0)*deltaArea + 
00446                (wireWeight+ARWeight/2.0)*deltaHPWL;
00447          }
00448          else
00449             delta = deltaArea;
00450 
00451                  vddX = _sp->getX();
00452                  vddY = _sp->getY();
00453                 islandSetIn.clearIslandNodes();
00454                 makeIslands(&islandSetIn, vddX, vddY);
00455 
00456                 int curPower=100;
00457                 if(test == 0){
00458                    cout << "--- Examining Power Reduction from Voltage Island Creation at Start---" << endl;
00459                    for(int i = 0; i < islandSetIn.numCurrentGroups; i++) {
00460                         finalPower = finalPower - (islandSetIn.voltageInGroup(i)*islandSetIn.numIslandInGroup(i));
00461                    }
00462                   cout << "Total power overhead reduced from 100 to " << finalPower << endl;
00463                   test = 1;
00464                 }
00465                  
00466                  for(int i = 0; i < islandSetIn.numCurrentGroups; i++) {
00467                      curPower = curPower - (islandSetIn.voltageInGroup(i)*islandSetIn.numIslandInGroup(i));
00468                  }
00469 
00470                  if((islandSetIn.numCurrentGroups > prevNumIslands) && (currTime > 50)) {
00471                    delta = delta/2;
00472                  }
00473 
00474                  if((islandSetIn.numIslandNodes() > prevNodesInIslands) && (currTime > 50)) {
00475                    delta = delta/4;
00476                  }
00477                  
00478                  if((islandSetIn.maxIslandNodes() > prevMaxIsland) && (currTime > 50)) {
00479                    delta = delta/6;
00480                  }
00481 
00482                  if((curPower < prevPower) && (currTime > 50)) {
00483                    delta = delta/8;
00484                  }
00485 
00486                  if(prevPower > curPower) prevPower = curPower;
00487                  if(prevNumIslands<islandSetIn.numCurrentGroups) prevNumIslands = islandSetIn.numCurrentGroups;
00488                  if(prevNodesInIslands<islandSetIn.numIslandNodes()) prevNodesInIslands = islandSetIn.numIslandNodes();
00489                  if(prevMaxIsland<islandSetIn.maxIslandNodes()) prevMaxIsland = islandSetIn.maxIslandNodes();
00490 
00491          if(delta<0 || move == -1)
00492                    moveAccepted = 1;
00493          else if(currTime>_params->timeCool) 
00494             //become greedy below time>timeCool
00495          {
00496             ran=rand()%10000;
00497             r=double(ran)/9999.0;
00498             if(r<exp(-1*delta/currTime))
00499                moveAccepted = 1;
00500             else
00501                moveAccepted = 0;
00502          }
00503          else
00504             moveAccepted = 0;
00505 
00506          if(moveAccepted)
00507          {
00508             currHeight=tempHeight;
00509             currWidth=tempWidth;
00510             currArea=tempArea;
00511             currHPWL=tempHPWL;
00512             _sp->putX(tempX);
00513             _sp->putY(tempY);
00514 
00515             if(move == 10)
00516                _db->getNodes()->changeOrient(indexOrient, newOrient,
00517                                              *(_db->getNets())); 
00518             else if(move == 11)
00519             {
00520                _db->getNodes()->putNodeWidth(indexOrient, newWidth);
00521                _db->getNodes()->putNodeHeight(indexOrient, newHeight);
00522             }
00523          }
00524          else
00525          {
00526             if(move == 10) //if move not accepted then put back orient
00527             {
00528                if(oldOrient%2 != newOrient%2)
00529                   _spEval->changeOrient(indexOrient);
00530 
00531                if(minWL)
00532                   _db->getNodes()->changeOrient(indexOrient, oldOrient,
00533                                                 *(_db->getNets())); 
00534             }
00535             else if(move == 11) //if move not accepted then put back old HW's
00536             {
00537                _spEval->changeNodeWidth(indexOrient, oldWidth);
00538                _spEval->changeNodeHeight(indexOrient, oldHeight);
00539             }
00540          }
00541 
00542          //cout<<"currTime "<<currTime<<" currHPWL "<<currHPWL<<" deltaHPWL "<<deltaHPWL<<" deltaArea "<<deltaArea<<" delta "<<delta<<" param "<<exp(-1*delta/currTime)<<endl;
00543 
00544          bool saveSolnInBestCopy=false;
00545          if(moveAccepted)
00546          {
00547             double oldCurrArea = currArea;
00548             double oldCurrWidth = currWidth;
00549             double oldCurrHeight = currHeight;
00550               
00551             if(reqdAR != -9999)
00552             {
00553                if(_params->solveTop && _params->dontClusterMacros)
00554                {
00555                   double tempXSize = _db->getXSizeWMacroOnly();
00556                   double tempYSize = _db->getYSizeWMacroOnly();
00557                   if(tempXSize > 1e-5 && tempYSize > 1e-5)
00558                   {
00559                      currArea = tempXSize*tempYSize;
00560                      currHeight = tempYSize;
00561                      currWidth = tempXSize;
00562                   }
00563                }
00564 
00565                if(minWL)
00566                {
00567                   if(currArea <= reqdArea && currHeight <= reqdHeight && 
00568                      currWidth <= reqdWidth && bestHPWL > currHPWL)
00569                   {
00570                      bestHPWL = currHPWL;
00571                      bestArea = currArea;
00572                      updatedBestSoln = true;
00573                      saveSolnInBestCopy = true;
00574                   }
00575                }
00576                else
00577                {
00578                   if(currArea <= reqdArea && currHeight <= reqdHeight && 
00579                      currWidth <= reqdWidth && bestArea > currArea)
00580                   {
00581                      bestHPWL = currHPWL;
00582                      bestArea = currArea;
00583                      updatedBestSoln = true;
00584                      saveSolnInBestCopy = true;
00585                   }
00586                }
00587             }
00588             else
00589             {
00590                if(minWL)
00591                {
00592                   if(currArea <= bestArea && currHPWL <= bestHPWL)
00593                   {
00594                      bestHPWL = currHPWL;
00595                      bestArea = currArea;
00596                      updatedBestSoln = true;
00597                      saveSolnInBestCopy = true;
00598                   }
00599                }
00600                else
00601                {
00602                   if(currArea <= bestArea)
00603                   {
00604                      bestHPWL = currHPWL;
00605                      bestArea = currArea;
00606                      updatedBestSoln = true;
00607                      saveSolnInBestCopy = true;
00608                   }
00609                }
00610             }
00611             if(saveSolnInBestCopy)
00612             {
00613                itNode node;
00614                unsigned nodeId=0;
00615                for(node = _db->getNodes()->nodesBegin(); node != _db->getNodes()->nodesEnd(); ++node)
00616                {
00617                   bestSolnPl[nodeId].x = node->getX();
00618                   bestSolnPl[nodeId].y = node->getY();
00619                   bestSolnOrient[nodeId] = node->getOrient();
00620                   bestSolnWidth[nodeId] = node->getWidth();
00621                   bestSolnHeight[nodeId] = node->getHeight();
00622                   bestXSP[nodeId] = (_sp->getX())[nodeId]; 
00623                   bestYSP[nodeId] = (_sp->getY())[nodeId];
00624                   ++nodeId;
00625                }
00626             }
00627           
00628             if(minWL/* && _params->startTime > 100*/)//for lowT anneal don't have this condition
00629             {
00630                if(reqdAR != -9999 && currTime < 0.5 && updatedBestSoln)
00631                {
00632                   brokeFromLoop = 1;
00633                   if(_params->verb.forMajStats > 0)
00634                      cout<<"Fixed-outline FPing SUCCESS"<<endl;
00635                   break;
00636                   //return;
00637                }
00638             }
00639             else
00640             {
00641                if(updatedBestSoln && reqdAR != -9999)
00642                {
00643                   brokeFromLoop = 1;
00644                   if(_params->verb.forMajStats > 0)
00645                      cout<<"Fixed-outline FPing SUCCESS"<<endl;
00646                   break;
00647                   //return;
00648                }
00649             }
00650               
00651             if(reqdAR != -9999 && _params->solveTop && _params->dontClusterMacros)
00652             {
00653                currArea = oldCurrArea;
00654                currWidth = oldCurrWidth;
00655                currHeight = oldCurrHeight;
00656             }
00657          }
00658           
00659          if (iter>=moves && budgetTime)
00660             break;
00661       }
00662       while(iter<size*4 || budgetTime);
00663 
00664       /*
00665         if(reqdAR != -9999)
00666         {
00667         if(minWL)
00668         if(currArea <= reqdArea && currHeight <= reqdHeight && 
00669         currWidth <= reqdWidth && bestHPWL > currHPWL)
00670         {
00671         _db->saveInBestCopy();
00672         bestHPWL = currHPWL;
00673         }
00674         else
00675         {
00676         if(currArea <= reqdArea && currHeight <= reqdHeight && 
00677         currWidth <= reqdWidth && bestArea > currArea)
00678         {
00679         _db->saveInBestCopy();
00680         bestArea = currArea;
00681         }
00682         }
00683         }
00684       */
00685 
00686       ++timeChangeCtr;
00687 
00688       if (budgetTime)
00689       {
00690          percent=seconds/total;
00691         
00692          if(percent<.066666 && percent>.033333)
00693             alpha=0.9;
00694          else if(percent<.033333 && percent>.016666)
00695             alpha=0.95;
00696          else if(percent<.016666 && percent>.006666)
00697             alpha=0.96;
00698          else if(percent<.006666 && percent>.000333)
00699             alpha=0.8;
00700          else if(percent<.000333 && percent>.000003)
00701             alpha=0.98;
00702          else
00703             alpha=0.85;
00704       }
00705       else
00706       {
00707          if(currTime<2000 && currTime>1000)
00708             alpha=0.95;
00709          else if(currTime<1000 && currTime>500)
00710             alpha=0.95;
00711          else if(currTime<500 && currTime>200)
00712             alpha=0.96;
00713          else if(currTime<200 && currTime>10)
00714             alpha=0.96;
00715          else if(currTime<15 && currTime>0.1)
00716             alpha=0.98;
00717          else
00718             alpha=0.95;
00719       }
00720       currTime = alpha*currTime;
00721 
00722       if(brokeFromLoop == 1)
00723          break;
00724 
00725       //cout<<currTime<<endl;
00726    }
00727 
00728    if(updatedBestSoln)
00729    {
00730       itNode node;
00731       unsigned nodeId=0;
00732       for(node = _db->getNodes()->nodesBegin(); node != _db->getNodes()->nodesEnd(); ++node)
00733       {
00734          node->putX(bestSolnPl[nodeId].x);
00735          node->putY(bestSolnPl[nodeId].y);
00736          node->changeOrient(bestSolnOrient[nodeId], *(_db->getNets()));
00737          node->putWidth(bestSolnWidth[nodeId]);
00738          node->putHeight(bestSolnHeight[nodeId]);
00739          
00740          _spEval->changeNodeWidth(nodeId, bestSolnWidth[nodeId]);
00741          _spEval->changeNodeHeight(nodeId, bestSolnHeight[nodeId]);
00742          ++nodeId;
00743       }
00744       // update the sequence-pair here
00745       _sp->putX(bestXSP);
00746       _sp->putY(bestYSP);
00747    }
00748 
00749    if(_params->verb.forActions > 0)
00750       cout << "NumMoves attempted: " << count << endl;
00751 
00752 
00753 
00754   int power = 100;
00755   for(int i = 0; i < islandSetIn.numCurrentGroups; i++) {
00756         power = power - (islandSetIn.voltageInGroup(i)*islandSetIn.numIslandInGroup(i));
00757   }
00758 
00759   if(power > finalPower) goto here;
00760 
00761   _sp->printX();
00762   _sp->printY();
00763 
00764   tempX = _sp->getX();
00765   tempY = _sp->getY();
00766 
00767   cout << "number of distinct islands " << islandSetIn.numCurrentGroups << endl;
00768   islandSetIn.printIslands();
00769 
00770   cout << "Total number of nodes in islands is " << islandSetIn.numIslandNodes() << endl;
00771   cout << "The largest island has " << islandSetIn.maxIslandNodes() << " nodes" << endl;
00772 
00773   power = 100;
00774   cout << "--- Examining Power Reduction from Voltage Island Creation ---" << endl;
00775   for(int i = 0; i < islandSetIn.numCurrentGroups; i++) {
00776         cout << "Island[" << i << "] has VDD " << islandSetIn.voltageInGroup(i) << " with number of nodes " << islandSetIn.numIslandInGroup(i) << " -- overhead reduced by " << islandSetIn.voltageInGroup(i)*islandSetIn.numIslandInGroup(i) << endl;
00777         power = power - (islandSetIn.voltageInGroup(i)*islandSetIn.numIslandInGroup(i));
00778   }
00779   cout << "Total power overhead reduced from 100 to " << power << endl;
00780 }
00781 
00782 
00783 void Annealer::sortSlacks(vector<Point>& sortedXSlacks, 
00784                           vector<Point>& sortedYSlacks)
00785 {
00786    sortedXSlacks.erase(sortedXSlacks.begin(), sortedXSlacks.end());
00787    sortedYSlacks.erase(sortedYSlacks.begin(), sortedYSlacks.end());
00788    Point tempPoint;
00789 
00790    for(unsigned i=0;i<_spEval->xSlacks.size();++i)
00791    {
00792       tempPoint.x = _spEval->xSlacks[i];
00793       tempPoint.y = i;
00794       sortedXSlacks.push_back(tempPoint);
00795       tempPoint.x = _spEval->ySlacks[i];
00796       tempPoint.y = i;
00797       sortedYSlacks.push_back(tempPoint);
00798    }
00799    std::sort(sortedXSlacks.begin(),sortedXSlacks.end(),sort_slacks());
00800    std::sort(sortedYSlacks.begin(),sortedYSlacks.end(),sort_slacks());
00801 }
00802 
00803 void Annealer::makeIslands(SetOfVoltages* islandSet, vector<unsigned>& A, vector<unsigned>& B)
00804 {
00805   int size = A.size();  
00806   //SetOfVoltages islandSet;
00807   for(unsigned i=0;i<(size-1);i++)
00808   {
00809    if(_db->getNodes()->getNode(A[i]).getVoltage() == _db->getNodes()->getNode(A[i+1]).getVoltage())
00810    {
00811 //     cout << "Node " << A[i] << " can be voltage island with " << A[i+1] << endl;
00812          islandSet->addIslandNodes(_db->getNodes()->getNode(A[i]).getVoltage(), A[i], A[i+1]);
00813    }
00814    if(_db->getNodes()->getNode(B[i]).getVoltage() == _db->getNodes()->getNode(B[i+1]).getVoltage())
00815    {
00816 //     cout << "Node " << B[i] << " can be voltage island with " << B[i+1] << endl;
00817          islandSet->addIslandNodes(_db->getNodes()->getNode(B[i]).getVoltage(), B[i], B[i+1]);
00818    }
00819   }
00820 
00821   islandSet->createVoltageIslands();
00822 
00823 /*
00824   cout << "number of distinct islands " << islandSet.numCurrentGroups << endl;
00825   islandSet.printIslands();
00826 */
00827 //  return islandSet;
00828 } 
00829 
00830 int Annealer::makeMove(vector<unsigned>& A, vector<unsigned>& B)
00831 {
00832    int elem1,elem2,i=0,voltage1=0,voltage2=0;
00833    int size = A.size();
00834    if(size == 1)
00835       return -1;
00836 
00837    unsigned temporary;
00838    int moverand = rand()%1000;
00839    int movedir;
00840 
00841    elem1=rand()%size;
00842    elem2=rand()%size;
00843 
00844 /*
00845    voltage1 = _db->getNodes()->getNode(elem1).getVoltage();
00846  
00847    while(voltage1 != voltage2)
00848    {
00849      elem2=rand()%size;
00850      voltage2 = _db->getNodes()->getNode(elem2).getVoltage();
00851    }
00852 */
00853    
00854    std::vector<unsigned>::iterator itb;
00855 
00856    moverand=rand()%600;
00857 
00858    if(moverand<75)
00859    {
00860       temporary=A[elem1];
00861       A[elem1]=A[elem2];
00862       A[elem2]=temporary;
00863       return 1;
00864    }
00865    else if(moverand>75 && moverand<150)
00866    {
00867       temporary=B[elem1];
00868       B[elem1]=B[elem2];
00869       B[elem2]=temporary;
00870       return 2;
00871    }
00872    else if(moverand>150 && moverand<200)
00873    {
00874       temporary=A[elem1];
00875       A[elem1]=A[elem2];
00876       A[elem2]=temporary;
00877       elem1=rand()%size;
00878       elem2=rand()%size;
00879       temporary=B[elem1];
00880       B[elem1]=B[elem2];
00881       B[elem2]=temporary;
00882       return 3;
00883    }
00884    else if(moverand>200 && moverand<400)
00885    {
00886       movedir=rand()%100;
00887       if(movedir<50)
00888       {
00889          i=0;
00890          for(itb=A.begin();i!=elem1;++itb,++i)
00891          { }
00892          temporary=*itb;
00893          A.erase(itb);
00894          i=0;
00895          for(itb=A.begin();i!=elem2;++itb,++i)
00896          { }
00897          A.insert(itb,1,temporary);
00898       }
00899       else
00900       {
00901          i=0;
00902          for(itb=B.begin();i!=elem1;++itb,++i)
00903          { }
00904          temporary=*itb;
00905          B.erase(itb);
00906          i=0;
00907          for(itb=B.begin();i!=elem2;++itb,++i)
00908          {
00909          }
00910          B.insert(itb,1,temporary);     
00911       }
00912       return 4;
00913    }
00914    else if(moverand>400 && moverand<600)
00915    {
00916       elem2=rand()%(int(ceil(size/4.0)));
00917       movedir=rand()%100;
00918       if(movedir<50)
00919       {
00920          if((elem1-elem2)<0)
00921             elem2=elem1+elem2;
00922          else
00923             elem2=elem1-elem2;
00924       }
00925       else
00926       {
00927          if((elem1+elem2)>size-1)
00928             elem2=elem1-elem2;
00929          else
00930             elem2=elem1+elem2;
00931       }
00932       if(moverand<500)
00933       {
00934          temporary=A[elem1];
00935          A[elem1]=A[elem2];
00936          A[elem2]=temporary;
00937       }
00938       else
00939       {
00940          temporary=B[elem1];
00941          B[elem1]=B[elem2];
00942          B[elem2]=temporary;
00943       }
00944       return 5;
00945    }
00946    return -1;
00947 }
00948 
00949 int Annealer::makeMoveOrient(unsigned& index, parquetfp::ORIENT& oldOrient,
00950                              parquetfp::ORIENT& newOrient)
00951 {
00952 
00953    index = rand()%_sp->getSize();
00954    Node& node = _db->getNodes()->getNode(index);
00955    if(node.isOrientFixed())
00956      return -1;
00957 
00958    oldOrient = node.getOrient();
00959    newOrient = parquetfp::ORIENT(rand()%8);   //one of the 8 orientations
00960   
00961    return 10;
00962 }
00963 
00964 int Annealer::makeMoveSlacksOrient(vector<unsigned>& A, vector<unsigned>& B,
00965                                    unsigned& index, parquetfp::ORIENT& oldOrient, parquetfp::ORIENT& newOrient)
00966 {
00967    unsigned size = A.size();
00968    _spEval->evalSlacks(A, B);
00969 
00970    sortSlacks(sortedXSlacks, sortedYSlacks);
00971    unsigned elem1=0;
00972    unsigned movedir = rand()%100;
00973    index = elem1;
00974    if(movedir<50)
00975    {
00976       for(unsigned i=0;i<size;++i)
00977       {
00978          elem1 = unsigned(sortedXSlacks[i].y);
00979          if(_db->getNodes()->getNodeWidth(elem1) >
00980             _db->getNodes()->getNodeHeight(elem1))
00981             break;
00982       }
00983       index = elem1;
00984    }
00985    else
00986    {
00987       for(unsigned i=0;i<size;++i)
00988       {
00989          elem1 = unsigned(sortedYSlacks[i].y);
00990          if(_db->getNodes()->getNodeHeight(elem1) >
00991             _db->getNodes()->getNodeWidth(elem1))
00992             break;
00993       }
00994       index = elem1;
00995    }
00996 
00997    Node& node = _db->getNodes()->getNode(index);
00998    if(node.isOrientFixed())
00999      return -1;
01000 
01001    oldOrient = node.getOrient();
01002    unsigned r = rand()%4;
01003   
01004    if(oldOrient%2 == 0)
01005       newOrient = parquetfp::ORIENT(2*r+1);
01006    else
01007       newOrient = parquetfp::ORIENT(2*r);
01008     
01009    return 10;
01010 }
01011 
01012 
01013 int Annealer::makeMoveSlacks(vector<unsigned>& A, vector<unsigned>& B)
01014 {
01015    unsigned size = A.size();
01016    if(size == 1)
01017       return -1;
01018 
01019    _spEval->evalSlacks(A, B);
01020 
01021    sortSlacks(sortedXSlacks, sortedYSlacks);
01022 
01023    std::vector<unsigned>::iterator itb;
01024    unsigned temporary;
01025    unsigned elem1, elem2;
01026    unsigned movedir = rand()%100;
01027    unsigned choseElem1=rand()%int(ceil(size/5.0));
01028    unsigned choseElem2=size-rand()%int(ceil(size/5.0))-1;
01029    if(movedir<50)
01030    {
01031       elem1 = unsigned(sortedXSlacks[choseElem1].y);
01032       for(itb=A.begin();(*itb)!=elem1;++itb)
01033       { }
01034       temporary=*itb;
01035       A.erase(itb);
01036       
01037       elem2=unsigned(sortedXSlacks[choseElem2].y);
01038       for(itb=A.begin();(*itb)!=elem2;++itb)
01039       { }
01040       A.insert(itb,1,temporary);
01041       //for B seqPair
01042       for(itb=B.begin();(*itb)!=elem1;++itb)
01043       { }
01044       temporary=*itb;
01045       B.erase(itb);
01046       
01047       for(itb=B.begin();(*itb)!=elem2;++itb)
01048       { }
01049       B.insert(itb,1,temporary);
01050    }
01051    else
01052    {
01053       elem1 = unsigned(sortedYSlacks[choseElem1].y);
01054       for(itb=A.begin();(*itb)!=elem1;++itb)
01055       { }
01056       temporary=*itb;
01057       A.erase(itb);
01058       
01059       elem2=unsigned(sortedYSlacks[choseElem2].y);
01060       for(itb=A.begin();(*itb)!=elem2;++itb)
01061       { }
01062       A.insert(itb,1,temporary);
01063       
01064       //for B seqPair
01065       for(itb=B.begin();(*itb)!=elem1;++itb)
01066       { }
01067       temporary=*itb;
01068       B.erase(itb);
01069       
01070       for(itb=B.begin();(*itb)!=elem2;++itb)
01071       { }
01072       B.insert(itb,1,temporary);
01073    }
01074    return 6;
01075 }
01076 
01077 int Annealer::makeARMove(vector<unsigned>& A, vector<unsigned>& B, 
01078                          double currAR)
01079 {
01080    unsigned size = A.size();
01081    if(size == 1)
01082       return -1;
01083 
01084    unsigned direction, temp;
01085    _spEval->evalSlacks(A, B);
01086 
01087    sortSlacks(sortedXSlacks, sortedYSlacks);
01088 
01089    std::vector<unsigned>::iterator itb;
01090    unsigned chooseElem1=0;
01091    unsigned elem1=0;
01092    unsigned chooseElem2=0;
01093    unsigned elem2=0;
01094    unsigned temporary=0;
01095 
01096    bool HVDir=0;
01097    if(currAR > 1.0*_params->reqdAR)//width is greater than reqd,(a little bias 
01098       //to increase width for better performance
01099       HVDir = 0;  // width needs to reduce
01100    else
01101       HVDir = 1;  // height needs to reduce
01102 
01103    chooseElem1=rand()%int(ceil(size/5.0));
01104    chooseElem2=size-rand()%int(ceil(size/5.0))-1;
01105 
01106    if(HVDir == 0)    //horizontal
01107    { 
01108       elem1 = unsigned(sortedXSlacks[chooseElem1].y); 
01109       elem2 = unsigned(sortedXSlacks[chooseElem2].y); 
01110    }
01111    else //vertical
01112    {
01113       elem1 = unsigned(sortedYSlacks[chooseElem1].y);
01114       elem2 = unsigned(sortedYSlacks[chooseElem2].y);
01115    }
01116 
01117    temp = rand() % 2;
01118    if(HVDir == 0)
01119    {
01120       if(temp == 0)
01121          direction = 0;  //left
01122       else
01123          direction = 3;  //right
01124    }
01125    else
01126    {
01127       if(temp == 0)
01128          direction = 1;  //top
01129       else
01130          direction = 2;  //bottom
01131    }
01132 
01133    for(itb=A.begin();(*itb)!=unsigned(elem1);++itb)
01134    { }
01135    temporary=*itb;
01136    A.erase(itb);
01137       
01138    for(itb=A.begin();(*itb)!=unsigned(elem2);++itb)
01139    { }
01140    switch(direction)
01141    {
01142    case 0:   //left
01143    case 1:   //top
01144       break;
01145    case 2:   //bottom
01146    case 3:   //right
01147       ++itb;
01148       break;
01149    }
01150    A.insert(itb,1,temporary);
01151 
01152    //for B seqPair
01153    for(itb=B.begin();(*itb)!=unsigned(elem1);++itb)
01154    { }
01155    temporary=*itb;
01156    B.erase(itb);
01157   
01158    for(itb=B.begin();(*itb)!=unsigned(elem2);++itb)
01159    { }
01160    switch(direction)
01161    {
01162    case 0:   //left
01163    case 2:   //bottom
01164       break;
01165    case 1:   //top
01166    case 3:   //right
01167       ++itb;
01168       break;
01169    }
01170 
01171    B.insert(itb,1,temporary);  
01172 
01173    return 7;
01174 }
01175 
01176 int Annealer::makeSoftBlMove(const vector<unsigned>& A,
01177                              const vector<unsigned>& B,
01178                              unsigned &index,
01179                              double &newWidth, double &newHeight)
01180 {
01181    unsigned size = A.size();
01182    _spEval->evalSlacks(A, B);
01183 
01184    sortSlacks(sortedXSlacks, sortedYSlacks);
01185    unsigned elem1=0;
01186    double minAR, maxAR, currAR;  
01187    unsigned movedir = rand()%100;
01188    double maxWidth, maxHeight;
01189    index = elem1;
01190    bool brokeFromLoop=0;
01191 
01192    if(movedir<50)
01193    {
01194       for(unsigned i=0;i<size;++i)
01195       {
01196          elem1 = unsigned(sortedXSlacks[i].y);
01197          Node& node = _db->getNodes()->getNode(elem1);
01198          minAR = node.getminAR();
01199          maxAR = node.getmaxAR();
01200          currAR = node.getWidth()/node.getHeight();
01201   
01202          if(_spEval->ySlacks[elem1] > 0 && minAR != maxAR && currAR > minAR)
01203          {
01204             brokeFromLoop = 1;
01205             break;
01206          }
01207       }
01208       index = elem1;
01209    }
01210   
01211    if(movedir >= 50 || brokeFromLoop == 0)
01212    {
01213       for(unsigned i=0;i<size;++i)
01214       {
01215          elem1 = unsigned(sortedYSlacks[i].y);
01216          Node& node = _db->getNodes()->getNode(elem1);
01217          minAR = node.getminAR();
01218          maxAR = node.getmaxAR();
01219          currAR = node.getWidth()/node.getHeight();
01220           
01221          if(_spEval->xSlacks[elem1] > 0 && minAR != maxAR && currAR < maxAR)
01222             break;
01223       }
01224       index = elem1;
01225    }
01226 
01227    Node& node = _db->getNodes()->getNode(index);
01228    double origHeight = node.getHeight();
01229    double origWidth = node.getWidth();
01230    currAR = origWidth/origHeight;
01231    double area = node.getArea();
01232 
01233    if(node.getminAR() > node.getmaxAR())
01234    {
01235       minAR = node.getmaxAR();
01236       maxAR = node.getminAR();
01237    }
01238    else
01239    {
01240       minAR = node.getminAR();
01241       maxAR = node.getmaxAR();
01242    }
01243 
01244    if(node.getOrient()%2 == 0)
01245    {
01246       maxHeight = sqrt(area/minAR);
01247       maxWidth = sqrt(area*maxAR);
01248    }
01249    else
01250    {
01251       maxHeight = sqrt(area*maxAR);
01252       maxWidth = sqrt(area/minAR);
01253    }
01254 
01255    double absSlackX = _spEval->xSlacks[index]*_spEval->xSize/100;
01256    double absSlackY = _spEval->ySlacks[index]*_spEval->ySize/100;
01257 
01258    newHeight = origHeight;
01259    newWidth = origWidth;
01260 
01261    if(absSlackX > absSlackY)  //need to elongate in X direction
01262    {
01263       if(currAR < maxAR)     //need to satisfy this constraint
01264       {
01265          newWidth = origWidth + absSlackX;
01266          if(newWidth > maxWidth)
01267             newWidth = maxWidth;
01268          newHeight = area/newWidth;
01269       }
01270    }
01271    else                       //need to elongate in Y direction
01272    {
01273       if(currAR > minAR)     //need to satisfy this constraint
01274       {
01275          newHeight = origHeight + absSlackY;
01276          if(newHeight > maxHeight)
01277             newHeight = maxHeight;
01278          newWidth = area/newHeight;
01279       }
01280    }
01281 
01282    if(minAR == maxAR)
01283    {
01284       newHeight = origHeight;
01285       newWidth = origWidth;
01286    }
01287 
01288    return 11;
01289 }
01290 
01291 int Annealer::makeIndexSoftBlMove(const vector<unsigned>& A,
01292                                   const vector<unsigned>& B,
01293                                   unsigned index,
01294                                   double &newWidth, double &newHeight)
01295 {
01296    _spEval->evalSlacks(A, B);
01297 
01298    //sortSlacks(sortedXSlacks, sortedYSlacks);
01299    double minAR, maxAR, currAR;  
01300    double maxWidth, maxHeight;
01301 
01302    Node& node = _db->getNodes()->getNode(index);
01303    double origHeight = node.getHeight();
01304    double origWidth = node.getWidth();
01305    currAR = origWidth/origHeight;
01306    double area = node.getArea();
01307   
01308    if(node.getminAR() > node.getmaxAR())
01309    {
01310       minAR = node.getmaxAR();
01311       maxAR = node.getminAR();
01312    }
01313    else
01314    {
01315       minAR = node.getminAR();
01316       maxAR = node.getmaxAR();
01317    }
01318   
01319    if(node.getOrient()%2 == 0)  
01320    {
01321       maxHeight = sqrt(area/minAR);
01322       maxWidth = sqrt(area*maxAR);
01323    }
01324    else
01325    {
01326       maxHeight = sqrt(area*maxAR);
01327       maxWidth = sqrt(area/minAR);
01328    }
01329 
01330    double absSlackX = _spEval->xSlacks[index]*_spEval->xSize/100;
01331    double absSlackY = _spEval->ySlacks[index]*_spEval->ySize/100;
01332 
01333    newHeight = origHeight;
01334    newWidth = origWidth;
01335 
01336    if(absSlackX > absSlackY)  //need to elongate in X direction
01337    {
01338       newWidth = origWidth + absSlackX;
01339       if(newWidth > maxWidth)
01340          newWidth = maxWidth;
01341       newHeight = area/newWidth;
01342 
01343    }
01344    else                       //need to elongate in Y direction
01345    {
01346       newHeight = origHeight + absSlackY;
01347       if(newHeight > maxHeight)
01348          newHeight = maxHeight;
01349       newWidth = area/newHeight;
01350    }
01351 
01352    if(fabs(minAR-maxAR) < 0.0000001)
01353    {
01354       newHeight = origHeight;
01355       newWidth = origWidth;
01356    }
01357 
01358    return 11;
01359 }
01360 
01361 int Annealer::packSoftBlocks(unsigned numIter)
01362 {
01363    unsigned index;
01364    double origHeight, origWidth;
01365    double newHeight, newWidth;
01366    double oldArea;
01367    double newArea;
01368    double change=-1;
01369 
01370    unsigned size = (_sp->getX()).size();
01371   
01372    _spEval->evaluate(_sp->getX(), _sp->getY());
01373    oldArea = _spEval->ySize * _spEval->xSize;
01374    unsigned iter = 0;
01375    while(iter < numIter)
01376    {
01377       ++iter;
01378      
01379       _spEval->evalSlacks(_sp->getX(), _sp->getY());
01380       sortSlacks(sortedXSlacks, sortedYSlacks);
01381      
01382       for(unsigned i = 0; i<size; ++i)
01383       {
01384          if(numIter%2 == 0)
01385             index = unsigned(sortedXSlacks[i].y);
01386          else
01387             index = unsigned(sortedYSlacks[i].y);
01388       
01389          origHeight = _db->getNodes()->getNodeHeight(index);
01390          origWidth = _db->getNodes()->getNodeWidth(index);
01391               
01392          makeIndexSoftBlMove(_sp->getX(), _sp->getY(), index, newWidth, newHeight);
01393          _spEval->changeNodeWidth(index, newWidth);
01394          _spEval->changeNodeHeight(index, newHeight);
01395          _spEval->evaluate(_sp->getX(), _sp->getY());
01396        
01397          newArea = _spEval->ySize * _spEval->xSize;
01398          change = newArea-oldArea;
01399          if(change > 1)  //do not accept
01400          {
01401             _spEval->changeNodeWidth(index, origWidth);
01402             _spEval->changeNodeHeight(index, origHeight);
01403          }
01404          else
01405          {
01406             _db->getNodes()->putNodeWidth(index, newWidth);
01407             _db->getNodes()->putNodeHeight(index, newHeight);
01408             oldArea = newArea;
01409          }
01410       }
01411    }
01412    return -1;
01413 }
01414 
01415 int Annealer::makeHPWLMove(vector<unsigned>& A, vector<unsigned>& B)
01416 {
01417 
01418    int size = A.size();
01419 
01420    if(size == 1)
01421       return -1;
01422 
01423    int i, j, temp, direction;
01424    int elem1,elem2;
01425 
01426    elem1=rand()%size;
01427    int searchRadiusNum = int(ceil(size/5.0));
01428    double searchRadius;
01429    double distance;
01430    double xDist;
01431    double yDist;
01432 
01433    std::vector<unsigned>::iterator itb;
01434    int temporary;
01435 
01436    vector<bool> seenBlocks;
01437    seenBlocks.resize(size);
01438 
01439    double unitRadiusSize;
01440 
01441    vector<int> searchBlocks;
01442 
01443    vector<double>& xloc = _spEval->xloc;
01444    vector<double>& yloc = _spEval->yloc;
01445 
01446   
01447    _spEval->evaluate(A, B); //evaluate SP to determine locs, may be redundant
01448    //can use db locs instead
01449 
01450    if(_spEval->xSize > _spEval->ySize)
01451       unitRadiusSize = _spEval->xSize;
01452    else
01453       unitRadiusSize = _spEval->ySize;
01454 
01455    unitRadiusSize /= sqrt(double(size));
01456 
01457    Point idealLoc = _analSolve->getOptLoc(elem1, _spEval->xloc, _spEval->yloc);
01458    //get optimum location of elem1
01459 
01460    fill(seenBlocks.begin(), seenBlocks.end(), 0);
01461    searchRadius = 0;
01462    for(i=0; i<searchRadiusNum; ++i)
01463    {
01464       searchRadius += unitRadiusSize;
01465       for(j = 0; j<size; ++j)
01466       {
01467          if(seenBlocks[j] == 0 && j != elem1)
01468          {
01469             xDist = xloc[j]-idealLoc.x;
01470             yDist = yloc[j]-idealLoc.y;
01471             distance = sqrt(xDist*xDist + yDist*yDist);
01472             if(distance < searchRadius)
01473             {
01474                seenBlocks[j] = 1;
01475                searchBlocks.push_back(j);
01476                if(searchBlocks.size() >= unsigned(searchRadiusNum))
01477                   break;
01478                continue;
01479             }
01480          }
01481       }
01482       if(searchBlocks.size() >= unsigned(searchRadiusNum))
01483          break;
01484    }
01485 
01486    if(searchBlocks.size() != 0)
01487    {
01488       temp = rand() % searchBlocks.size();
01489       elem2 = searchBlocks[temp];
01490    }
01491    else
01492    {
01493       do
01494          elem2 = rand() % size;
01495       while(elem2 == elem1);
01496    }
01497 
01498    if(elem1 == elem2)
01499       return -1;
01500 
01501    direction = rand() % 4;
01502 
01503 
01504    for(itb=A.begin();(*itb)!=unsigned(elem1);++itb)
01505    { }
01506    temporary=*itb;
01507    A.erase(itb);
01508       
01509    for(itb=A.begin();(*itb)!=unsigned(elem2);++itb)
01510    { }
01511    switch(direction)
01512    {
01513    case 0:   //left
01514    case 1:   //top
01515       break;
01516    case 2:   //bottom
01517    case 3:   //right
01518       ++itb;
01519       break;
01520    }
01521    A.insert(itb,1,temporary);
01522 
01523    //for B seqPair
01524    for(itb=B.begin();(*itb)!=unsigned(elem1);++itb)
01525    { }
01526    temporary=*itb;
01527    B.erase(itb);
01528   
01529    for(itb=B.begin();(*itb)!=unsigned(elem2);++itb)
01530    { }
01531    switch(direction)
01532    {
01533    case 0:   //left
01534    case 2:   //bottom
01535       break;
01536    case 1:   //top
01537    case 3:   //right
01538       ++itb;
01539       break;
01540    }
01541 
01542    B.insert(itb,1,temporary);  
01543    return 12;
01544 
01545    return -1;
01546 }
01547 
01548 int Annealer::makeARWLMove(vector<unsigned>& A, vector<unsigned>& B, 
01549                            double currAR)
01550 {
01551    unsigned size = A.size();
01552 
01553    if(size == 1)
01554       return -1;
01555   
01556    std::vector<unsigned>::iterator itb;
01557    unsigned chooseElem1=0;
01558    unsigned elem1=0;
01559    unsigned elem2=0;
01560    unsigned temporary=0;
01561    unsigned i, j, direction, temp;
01562    double maxSlack;
01563    unsigned searchRadiusNum = unsigned(ceil(size/5.0));
01564    double searchRadius;
01565    double distance;
01566    double xDist;
01567    double yDist;
01568 
01569    vector<bool> seenBlocks;
01570    seenBlocks.resize(size);
01571    double unitRadiusSize;
01572 
01573    vector<int> searchBlocks;
01574 
01575    vector<double>& xloc = _spEval->xloc;
01576    vector<double>& yloc = _spEval->yloc;
01577 
01578    _spEval->evalSlacks(A, B);
01579 
01580    sortSlacks(sortedXSlacks, sortedYSlacks);
01581 
01582    _spEval->evaluate(A, B); //evaluate SP to determine locs, may be redundant
01583    //can use db locs instead
01584 
01585    bool HVDir=0;
01586    if(currAR > _params->reqdAR) //width is greater than reqd,(a little bias 
01587       //to increase width for better performance
01588       HVDir = 0;  // width needs to reduce
01589    else
01590       HVDir = 1;  // height needs to reduce
01591 
01592    chooseElem1=rand()%int(ceil(size/5.0));
01593 
01594    if(HVDir == 0)    //horizontal
01595       elem1 = unsigned(sortedXSlacks[chooseElem1].y); 
01596    else //vertical
01597       elem1 = unsigned(sortedYSlacks[chooseElem1].y);
01598 
01599    if(_spEval->xSize > _spEval->ySize)
01600       unitRadiusSize = _spEval->xSize;
01601    else
01602       unitRadiusSize = _spEval->ySize;
01603    unitRadiusSize /= sqrt(double(size));
01604 
01605    Point idealLoc = _analSolve->getOptLoc(elem1, xloc, yloc);
01606    //get optimum location of elem1
01607 
01608    fill(seenBlocks.begin(), seenBlocks.end(), 0);
01609    searchRadius = 0;
01610    for(i=0; i<searchRadiusNum; ++i)
01611    {
01612       searchRadius += unitRadiusSize;
01613       for(j = 0; j<size; ++j)
01614       {
01615          if(seenBlocks[j] == 0 && j != elem1)
01616          {
01617             xDist = xloc[j]-idealLoc.x;
01618             yDist = yloc[j]-idealLoc.y;
01619             distance = sqrt(xDist*xDist + yDist*yDist);
01620             if(distance < searchRadius)
01621             {
01622                seenBlocks[j] = 1;
01623                searchBlocks.push_back(j);
01624                if(searchBlocks.size() >= unsigned(searchRadiusNum))
01625                   break;
01626                continue;
01627             }
01628          }
01629       }
01630       if(searchBlocks.size() >= unsigned(searchRadiusNum))
01631          break;
01632    }
01633   
01634    maxSlack = -1e100;
01635    if(HVDir == 0)  //width reduction. find max xSlack block
01636    {
01637       for(i=0; i<searchBlocks.size(); ++i)
01638       {
01639          if(_spEval->xSlacks[searchBlocks[i]] > maxSlack)
01640          {
01641             maxSlack = _spEval->xSlacks[searchBlocks[i]];
01642             elem2 = searchBlocks[i];
01643          }
01644       }
01645    }
01646    else  //height reduction. find max yslack block
01647    {
01648       for(i=0; i<searchBlocks.size(); ++i)
01649       {
01650          if(_spEval->ySlacks[searchBlocks[i]] > maxSlack)
01651          {
01652             maxSlack = _spEval->ySlacks[searchBlocks[i]];
01653             elem2 = searchBlocks[i];
01654          }
01655       }
01656    }
01657 
01658    if(searchBlocks.size() == 0)
01659       do
01660          elem2 = rand() % size;
01661       while(elem2 == elem1);
01662 
01663    temp = rand() % 2;
01664    if(HVDir == 0)
01665    {
01666       if(temp == 0)
01667          direction = 0;  //left
01668       else
01669          direction = 3;  //right
01670    }
01671    else
01672    {
01673       if(temp == 0)
01674          direction = 1;  //top
01675       else
01676          direction = 2;  //bottom
01677    }
01678 
01679    for(itb=A.begin();(*itb)!=unsigned(elem1);++itb)
01680    { }
01681    temporary=*itb;
01682    A.erase(itb);
01683       
01684    for(itb=A.begin();(*itb)!=unsigned(elem2);++itb)
01685    { }
01686    switch(direction)
01687    {
01688    case 0:   //left
01689    case 1:   //top
01690       break;
01691    case 2:   //bottom
01692    case 3:   //right
01693       ++itb;
01694       break;
01695    }
01696    A.insert(itb,1,temporary);
01697 
01698    //for B seqPair
01699    for(itb=B.begin();(*itb)!=unsigned(elem1);++itb)
01700    { }
01701    temporary=*itb;
01702    B.erase(itb);
01703   
01704    for(itb=B.begin();(*itb)!=unsigned(elem2);++itb)
01705    { }
01706    switch(direction)
01707    {
01708    case 0:   //left
01709    case 2:   //bottom
01710       break;
01711    case 1:   //top
01712    case 3:   //right
01713       ++itb;
01714       break;
01715    }
01716 
01717    B.insert(itb,1,temporary);  
01718 
01719    return 13;
01720 }
01721 
01722 
01723 double Annealer::getXSize(void)
01724 {
01725    return _spEval->xSize;
01726 }
01727 
01728 
01729 double Annealer::getYSize(void)
01730 {
01731    return _spEval->ySize;
01732 }
01733  

Generated on Mon Apr 25 01:09:23 2005 for Parquete by doxygen 1.3.2