00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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()
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
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
00141
00142
00143
00144
00145
00146
00147
00148
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
00246
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);
00278 }
00279 else if (count > 1000)
00280 {
00281 seconds-=unit;
00282 if (seconds <= 0)
00283 {
00284 brokeFromLoop=1;
00285 break;
00286
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
00316
00317
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
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)
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
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
00400
00401
00402
00403
00404
00405
00406
00407
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
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
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)
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)
00536 {
00537 _spEval->changeNodeWidth(indexOrient, oldWidth);
00538 _spEval->changeNodeHeight(indexOrient, oldHeight);
00539 }
00540 }
00541
00542
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)
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
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
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
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
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
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
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
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
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
00817 islandSet->addIslandNodes(_db->getNodes()->getNode(B[i]).getVoltage(), B[i], B[i+1]);
00818 }
00819 }
00820
00821 islandSet->createVoltageIslands();
00822
00823
00824
00825
00826
00827
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
00846
00847
00848
00849
00850
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);
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
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
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)
01098
01099 HVDir = 0;
01100 else
01101 HVDir = 1;
01102
01103 chooseElem1=rand()%int(ceil(size/5.0));
01104 chooseElem2=size-rand()%int(ceil(size/5.0))-1;
01105
01106 if(HVDir == 0)
01107 {
01108 elem1 = unsigned(sortedXSlacks[chooseElem1].y);
01109 elem2 = unsigned(sortedXSlacks[chooseElem2].y);
01110 }
01111 else
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;
01122 else
01123 direction = 3;
01124 }
01125 else
01126 {
01127 if(temp == 0)
01128 direction = 1;
01129 else
01130 direction = 2;
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:
01143 case 1:
01144 break;
01145 case 2:
01146 case 3:
01147 ++itb;
01148 break;
01149 }
01150 A.insert(itb,1,temporary);
01151
01152
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:
01163 case 2:
01164 break;
01165 case 1:
01166 case 3:
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)
01262 {
01263 if(currAR < maxAR)
01264 {
01265 newWidth = origWidth + absSlackX;
01266 if(newWidth > maxWidth)
01267 newWidth = maxWidth;
01268 newHeight = area/newWidth;
01269 }
01270 }
01271 else
01272 {
01273 if(currAR > minAR)
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
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)
01337 {
01338 newWidth = origWidth + absSlackX;
01339 if(newWidth > maxWidth)
01340 newWidth = maxWidth;
01341 newHeight = area/newWidth;
01342
01343 }
01344 else
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)
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);
01448
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
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:
01514 case 1:
01515 break;
01516 case 2:
01517 case 3:
01518 ++itb;
01519 break;
01520 }
01521 A.insert(itb,1,temporary);
01522
01523
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:
01534 case 2:
01535 break;
01536 case 1:
01537 case 3:
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);
01583
01584
01585 bool HVDir=0;
01586 if(currAR > _params->reqdAR)
01587
01588 HVDir = 0;
01589 else
01590 HVDir = 1;
01591
01592 chooseElem1=rand()%int(ceil(size/5.0));
01593
01594 if(HVDir == 0)
01595 elem1 = unsigned(sortedXSlacks[chooseElem1].y);
01596 else
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
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)
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
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;
01668 else
01669 direction = 3;
01670 }
01671 else
01672 {
01673 if(temp == 0)
01674 direction = 1;
01675 else
01676 direction = 2;
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:
01689 case 1:
01690 break;
01691 case 2:
01692 case 3:
01693 ++itb;
01694 break;
01695 }
01696 A.insert(itb,1,temporary);
01697
01698
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:
01709 case 2:
01710 break;
01711 case 1:
01712 case 3:
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