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

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

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