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 #include "FPcommon.h"
00038 #include "Annealer.h"
00039 #include "ClusterDB.h"
00040 #include "CommandLine.h"
00041 #include "SolveMulti.h"
00042 #include "mixedpacking.h"
00043 #include "baseannealer.h"
00044 #include "btreeanneal.h"
00045 #include "ABKCommon/infolines.h"
00046 using namespace parquetfp;
00047
00048 SolveMulti::SolveMulti(DB * db, Command_Line* params)
00049 {
00050 _db = db;
00051 _params = params;
00052 _newDB = new DB();
00053 clusterTime = 0.0;
00054 annealTime = 0.0;
00055 }
00056
00057 SolveMulti::~SolveMulti()
00058 {
00059 if(_newDB) delete _newDB;
00060 }
00061
00062 DB* SolveMulti::clusterOnly() const
00063 {
00064 ClusterDB multiCluster(_db, _params);
00065
00066 DB *clusteredDB = new DB();
00067 Timer T;
00068 if(_params->clusterPhysical)
00069 multiCluster.clusterMultiPhysical(clusteredDB);
00070 else
00071 multiCluster.clusterMulti(clusteredDB);
00072
00073 T.stop();
00074 MaxMem::update("Parquet after Clustering");
00075 clusterTime += T.getUserTime();
00076
00077 return clusteredDB;
00078 }
00079
00080 void SolveMulti::go(void)
00081 {
00082 ClusterDB multiCluster(_db, _params);
00083
00084
00085 Timer T;
00086
00087
00088
00089 if(_params->clusterPhysical)
00090 multiCluster.clusterMultiPhysical(_newDB);
00091 else
00092 multiCluster.clusterMulti(_newDB);
00093
00094 T.stop();
00095 MaxMem::update("Parquet after Clustering");
00096 clusterTime += T.getUserTime();
00097
00098
00099
00100 if(_params->verb.forSysRes > 0)
00101 cout<<"Clustering took "<<clusterTime<<" seconds "<<endl;
00102
00103 if(_params->verb.forMajStats > 0)
00104 cout<<"Num Nodes: "<<_newDB->getNumNodes()<<" Num Nets: "
00105 <<_newDB->getNets()->getNumNets()<<" Num Pins: "
00106 <<_newDB->getNets()->getNumPins()<<endl;
00107
00108
00109
00110
00111
00112
00113 double reqdWidth = 1e100;
00114 double reqdHeight = 1e100;
00115 double oldDBArea = _db->getNodesArea();
00116 double newDBArea = _newDB->getNodesArea();
00117
00118 double maxArea = (1+_params->maxWS/100)*oldDBArea;
00119 double newMaxWS = (maxArea/newDBArea-1)*100;
00120 double oldMaxWS = _params->maxWS;
00121 _params->maxWS = newMaxWS;
00122 if(_params->reqdAR != -9999 && _params->verb.forMajStats > 0)
00123 cout<<"newMaxWS is "<<_params->maxWS<<endl;
00124
00125 if(_params->reqdAR != -9999)
00126 {
00127 reqdHeight = sqrt(maxArea/_params->reqdAR);
00128 reqdWidth = maxArea/reqdHeight;
00129 }
00130 double currXSize, currYSize;
00131 int maxIter = 0;
00132
00133 BaseAnnealer *annealer = NULL;
00134 if (_params->FPrep == "BTree")
00135 {
00136 annealer =
00137 new BTreeAreaWireAnnealer(_params, _newDB);
00138 }
00139 else if (_params->FPrep == "SeqPair")
00140 {
00141 annealer = new Annealer(_params, _newDB);
00142 }
00143 else
00144 {
00145 abkfatal(false, "Invalid floorplan representation specified");
00146 exit(1);
00147 }
00148
00149
00150 if(_params->takePl)
00151 {
00152
00153 annealer->takePlfromDB();
00154 }
00155
00156 if(_params->initQP)
00157 {
00158 annealer->solveQP();
00159 annealer->takePlfromDB();
00160 }
00161
00162 if(_params->initCompact)
00163 {
00164 annealer->compactSoln();
00165
00166 }
00167
00168
00169 double startArea = _newDB->getXSize()*_newDB->getYSize();
00170 if(_params->verb.forMajStats > 0)
00171 cout<<"Starting whitespace "<<100*(startArea-newDBArea)/newDBArea<<"%. Starting AR "<<_newDB->getXSize()/_newDB->getYSize()<<endl;
00172
00173
00174
00175 unsigned numNodes = _newDB->getNumNodes();
00176 Point dummy;
00177 dummy.x=0;
00178 dummy.y=0;
00179 vector<Point> bestSolnPl(numNodes, dummy);
00180 vector<ORIENT> bestSolnOrient(numNodes, N);
00181 vector<double> bestSolnWidth(numNodes, 0);
00182 vector<double> bestSolnHeight(numNodes, 0);
00183 Nodes* newNodes = _newDB->getNodes();
00184
00185 double minViol = 1e100;
00186 bool satisfied=true;
00187 do
00188 {
00189 annealer->go();
00190
00191 if(_params->compact)
00192 annealer->compactSoln();
00193
00194
00195
00196
00197
00198 currXSize = _newDB->getXSize();
00199 currYSize = _newDB->getYSize();
00200
00201 if(_params->solveTop && _params->dontClusterMacros)
00202 {
00203 double tempXSize = _newDB->getXSizeWMacroOnly();
00204 double tempYSize = _newDB->getYSizeWMacroOnly();
00205 if(tempXSize > 1e-5 && tempYSize > 1e-5 )
00206 {
00207 currXSize = tempXSize;
00208 currYSize = tempYSize;
00209 }
00210 }
00211
00212 if(currXSize<=reqdWidth && currYSize<=reqdHeight)
00213 break;
00214
00215
00216 double viol=0;
00217 if(currXSize > reqdWidth)
00218 viol += (currXSize - reqdWidth);
00219 if(currYSize > reqdHeight)
00220 viol += (currYSize - reqdHeight);
00221
00222 if(minViol > viol)
00223 {
00224 minViol = viol;
00225 itNode node;
00226 unsigned nodeId=0;
00227 for(node = newNodes->nodesBegin(); node != newNodes->nodesEnd(); ++node)
00228 {
00229 bestSolnPl[nodeId].x = node->getX();
00230 bestSolnPl[nodeId].y = node->getY();
00231 bestSolnOrient[nodeId] = node->getOrient();
00232 bestSolnWidth[nodeId] = node->getWidth();
00233 bestSolnHeight[nodeId] = node->getHeight();
00234 ++nodeId;
00235 }
00236 }
00237
00238 maxIter++;
00239 if(maxIter == _params->maxIterHier)
00240 {
00241 if(_params->verb.forMajStats > 0)
00242 cout<<"FAILED to satisfy fixed outline constraints" <<
00243 "for clustered hypergraph" <<endl;
00244 satisfied = false;
00245 break;
00246 }
00247
00248
00249 if(maxIter == 2 && _params->FPrep == "SeqPair")
00250 {
00251 if(_params->verb.forMajStats > 0)
00252 cout<<"Failed 1st iteration. Changing annealer to B*Tree"<<endl;
00253 delete annealer;
00254 _params->FPrep == "BTree";
00255 annealer = new BTreeAreaWireAnnealer(_params, _newDB);
00256 }
00257 }
00258 while(1);
00259
00260 annealTime += annealer->annealTime;
00261
00262 delete annealer;
00263
00264 if(!satisfied)
00265 {
00266 itNode node;
00267 unsigned nodeId=0;
00268 for(node = newNodes->nodesBegin(); node != newNodes->nodesEnd(); ++node)
00269 {
00270 node->putX(bestSolnPl[nodeId].x);
00271 node->putY(bestSolnPl[nodeId].y);
00272 node->changeOrient(bestSolnOrient[nodeId], *(_newDB->getNets()));
00273 node->putWidth(bestSolnWidth[nodeId]);
00274 node->putHeight(bestSolnHeight[nodeId]);
00275 ++nodeId;
00276 }
00277 }
00278
00279 updatePlaceUnCluster(_newDB);
00280
00281 if(!_params->solveTop)
00282 placeSubBlocks();
00283
00284 _params->maxWS = oldMaxWS;
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 }
00298
00299 void SolveMulti::placeSubBlocks(void)
00300 {
00301 Nodes* nodes = _newDB->getNodes();
00302 Nodes* origNodes = _db->getNodes();
00303
00304
00305
00306 Command_Line* params = new Command_Line(*_params);
00307 params->budgetTime = 0;
00308
00309
00310 for(itNode node=nodes->nodesBegin(); node!=nodes->nodesEnd(); ++node)
00311 {
00312 Point dbLoc;
00313 dbLoc.x = node->getX();
00314 dbLoc.y = node->getY();
00315 params->reqdAR = node->getWidth()/node->getHeight();
00316
00317 DB *tempDB = new DB(_db,
00318 node->getSubBlocks(),
00319 dbLoc,
00320 params->reqdAR);
00321
00322 if(_params->verb.forMajStats > 0)
00323 cout << node->getName() << " numSubBlks : " << node->numSubBlocks()
00324 << "reqdAR " << params->reqdAR << endl;
00325
00326 BaseAnnealer *annealer = NULL;
00327 if (params->FPrep == "BTree")
00328 {
00329 annealer =
00330 new BTreeAreaWireAnnealer(params, tempDB);
00331 }
00332 else if (params->FPrep == "SeqPair")
00333 {
00334 annealer = new Annealer(params, tempDB);
00335 }
00336 else
00337 {
00338 abkfatal(false, "Invalid floorplan representation specified");
00339 exit(1);
00340 }
00341
00342 double currXSize, currYSize;
00343 double reqdWidth = node->getWidth();
00344 double reqdHeight = node->getHeight();
00345
00346 int maxIter = 0;
00347 if(node->numSubBlocks() > 1)
00348 {
00349 unsigned numNodes = tempDB->getNumNodes();
00350 Point dummy;
00351 dummy.x=0;
00352 dummy.y=0;
00353
00354 vector<Point> bestSolnPl(numNodes, dummy);
00355 vector<ORIENT> bestSolnOrient(numNodes, N);
00356 vector<double> bestSolnWidth(numNodes, 0);
00357 vector<double> bestSolnHeight(numNodes, 0);
00358 Nodes *tempNodes = tempDB->getNodes();
00359
00360 double minViol = 1e100;
00361 bool satisfied=true;
00362 do
00363 {
00364 annealer->go();
00365
00366
00367
00368
00369
00370 currXSize = tempDB->getXSize();
00371 currYSize = tempDB->getYSize();
00372 if(currXSize<=reqdWidth && currYSize<=reqdHeight)
00373 break;
00374
00375
00376 double viol = 0;
00377 if(currXSize > reqdWidth)
00378 viol += (currXSize - reqdWidth);
00379 if(currYSize > reqdHeight)
00380 viol += (currYSize - reqdHeight);
00381
00382 if(minViol > viol)
00383 {
00384 minViol = viol;
00385 unsigned nodeId=0;
00386
00387 for(itNode tempNode = tempNodes->nodesBegin();
00388 tempNode != tempNodes->nodesEnd(); ++tempNode)
00389 {
00390 bestSolnPl[nodeId].x = tempNode->getX();
00391 bestSolnPl[nodeId].y = tempNode->getY();
00392 bestSolnOrient[nodeId] = tempNode->getOrient();
00393 bestSolnWidth[nodeId] = tempNode->getWidth();
00394 bestSolnHeight[nodeId] = tempNode->getHeight();
00395 ++nodeId;
00396 }
00397 }
00398
00399 maxIter++;
00400 if(maxIter == _params->maxIterHier)
00401 {
00402 if(_params->verb.forMajStats > 0)
00403 cout<<"FAILED to satisfy fixed outline constraints for "
00404 <<node->getName()<<endl;
00405 satisfied=false;
00406 break;
00407 }
00408 }
00409 while(1);
00410
00411 delete annealer;
00412
00413 if(!satisfied)
00414 {
00415 unsigned nodeId=0;
00416 for(itNode tempNode = tempNodes->nodesBegin(); tempNode != tempNodes->nodesEnd(); ++tempNode)
00417 {
00418 tempNode->putX(bestSolnPl[nodeId].x);
00419 tempNode->putY(bestSolnPl[nodeId].y);
00420 tempNode->changeOrient(bestSolnOrient[nodeId], *(tempDB->getNets()));
00421
00422 tempNode->putWidth(bestSolnWidth[nodeId]);
00423 tempNode->putHeight(bestSolnHeight[nodeId]);
00424 ++nodeId;
00425 }
00426 }
00427 }
00428 else
00429 {
00430 Point loc;
00431 loc.x = 0.0;
00432 loc.y = 0.0;
00433 tempDB->initPlacement(loc);
00434 }
00435
00436 Point offset;
00437 offset.x = node->getX();
00438 offset.y = node->getY();
00439
00440 tempDB->shiftDesign(offset);
00441
00442 Nodes * tempNodes = tempDB->getNodes();
00443
00444 if(node->numSubBlocks() > 1)
00445 {
00446 for(itNode tempNode = tempNodes->nodesBegin();
00447 tempNode != tempNodes->nodesEnd(); ++tempNode)
00448 {
00449 for(vector<int>::iterator tempIdx = tempNode->subBlocksBegin();
00450 tempIdx != tempNode->subBlocksEnd(); ++tempIdx)
00451 {
00452 Node& origNode = origNodes->getNode(*tempIdx);
00453 origNode.putX(tempNode->getX());
00454 origNode.putY(tempNode->getY());
00455 origNode.changeOrient(tempNode->getOrient(), *(_db->getNets()));
00456 origNode.putHeight(tempNode->getHeight());
00457 origNode.putWidth(tempNode->getWidth());
00458 }
00459 }
00460 }
00461 else if(node->numSubBlocks() == 1)
00462 {
00463 vector<int>::iterator tempIdx = node->subBlocksBegin();
00464 Node& origNode = origNodes->getNode(*tempIdx);
00465 origNode.putX(node->getX());
00466 origNode.putY(node->getY());
00467 origNode.changeOrient(node->getOrient(), *(_db->getNets()));
00468 origNode.putHeight(node->getHeight());
00469 origNode.putWidth(node->getWidth());
00470 }
00471 delete tempDB;
00472 }
00473 }
00474
00475 void SolveMulti::updatePlaceUnCluster(DB * clusterDB)
00476 {
00477 Nodes* nodes = _db->getNodes();
00478 Nodes* newNodes = clusterDB->getNodes();
00479
00480 itNode node;
00481
00482 const unsigned numNew = 6;
00483 double layOutXSize = _db->getXSize();
00484 double layOutYSize = _db->getYSize();
00485 double xStep = layOutXSize/numNew;
00486 double yStep = layOutYSize/numNew;
00487
00488 for(node = newNodes->nodesBegin(); node != newNodes->nodesEnd(); ++node)
00489 {
00490 if(node->numSubBlocks() > 1)
00491 {
00492 for(vector<int>::iterator subBlockIdx = node->subBlocksBegin();
00493 subBlockIdx != node->subBlocksEnd(); ++subBlockIdx)
00494 {
00495 Node& tempNode = nodes->getNode(*subBlockIdx);
00496 if(!_params->usePhyLocHier || node->numSubBlocks() == 1)
00497 {
00498 tempNode.putX(node->getX());
00499 tempNode.putY(node->getY());
00500 tempNode.changeOrient(node->getOrient(), *(_db->getNets()));
00501 }
00502 else
00503 {
00504 double xloc = tempNode.getX();
00505 double yloc = tempNode.getY();
00506 unsigned xIdx = unsigned(floor(xloc/xStep));
00507 unsigned yIdx = unsigned(floor(yloc/yStep));
00508 xloc -= xIdx*xStep;
00509 yloc -= yIdx*yStep;
00510
00511 tempNode.putX(xloc+node->getX());
00512 tempNode.putY(yloc+node->getY());
00513 }
00514
00515 }
00516 }
00517 else if(node->numSubBlocks() == 1)
00518 {
00519 vector<int>::iterator subBlockIdx = node->subBlocksBegin();
00520 Node& tempNode = nodes->getNode(*subBlockIdx);
00521 tempNode.putX(node->getX());
00522 tempNode.putY(node->getY());
00523 tempNode.changeOrient(node->getOrient(), *(_db->getNets()));
00524 tempNode.putHeight(node->getHeight());
00525 tempNode.putWidth(node->getWidth());
00526 }
00527 }
00528 }