#include <SolveMulti.h>
Collaboration diagram for parquetfp::SolveMulti:
Public Member Functions | |
SolveMulti (DB *db, Command_Line *params) | |
~SolveMulti () | |
void | go (void) |
DB * | clusterOnly () const |
void | placeSubBlocks (void) |
void | updatePlaceUnCluster (DB *clusterDB) |
Public Attributes | |
double | clusterTime |
double | annealTime |
Private Attributes | |
DB * | _db |
Command_Line * | _params |
DB * | _newDB |
|
Definition at line 48 of file SolveMulti.cxx. References _db, _newDB, _params, annealTime, and clusterTime.
00049 { 00050 _db = db; 00051 _params = params; 00052 _newDB = new DB(); 00053 clusterTime = 0.0; 00054 annealTime = 0.0; 00055 } |
|
Definition at line 57 of file SolveMulti.cxx. References _newDB.
|
|
Definition at line 62 of file SolveMulti.cxx. References _db, _params, parquetfp::ClusterDB::clusterMulti(), parquetfp::ClusterDB::clusterMultiPhysical(), parquetfp::Command_Line::clusterPhysical, clusterTime, Timer::getUserTime(), Timer::stop(), and MaxMem::update().
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; // return a brand-new DB, to be deleted 00078 } |
Here is the call graph for this function:
|
Definition at line 80 of file SolveMulti.cxx. References _db, _newDB, _params, abkfatal, BaseAnnealer::annealTime, annealTime, parquetfp::ClusterDB::clusterMulti(), parquetfp::ClusterDB::clusterMultiPhysical(), parquetfp::Command_Line::clusterPhysical, clusterTime, parquetfp::Command_Line::compact, BaseAnnealer::compactSoln(), parquetfp::Command_Line::dontClusterMacros, Verbosity::forMajStats, Verbosity::forSysRes, parquetfp::Command_Line::FPrep, parquetfp::DB::getNets(), parquetfp::DB::getNodes(), parquetfp::DB::getNodesArea(), parquetfp::Nets::getNumNets(), parquetfp::DB::getNumNodes(), parquetfp::Nets::getNumPins(), Timer::getUserTime(), parquetfp::DB::getXSize(), parquetfp::DB::getXSizeWMacroOnly(), parquetfp::DB::getYSize(), parquetfp::DB::getYSizeWMacroOnly(), BaseAnnealer::go(), parquetfp::Command_Line::initCompact, parquetfp::Command_Line::initQP, parquetfp::itNode, parquetfp::Command_Line::maxIterHier, parquetfp::Command_Line::maxWS, parquetfp::N, parquetfp::Nodes::nodesBegin(), parquetfp::Nodes::nodesEnd(), placeSubBlocks(), parquetfp::Command_Line::reqdAR, BaseAnnealer::solveQP(), parquetfp::Command_Line::solveTop, Timer::stop(), parquetfp::Command_Line::takePl, BaseAnnealer::takePlfromDB(), MaxMem::update(), updatePlaceUnCluster(), parquetfp::Command_Line::verb, parquetfp::Point::x, and parquetfp::Point::y.
00081 { 00082 ClusterDB multiCluster(_db, _params); 00083 00084 // double totalTime=0.0; 00085 Timer T; 00086 // T.stop(); 00087 // T.start(0.0); 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 // totalTime += T.getUserTime(); 00099 // cout<<"Clustering took "<<totalTime<<" seconds "<<endl; 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 /* _newDB->plot("cluster.plt", _newDB->evalArea(), 00109 100*(_newDB->evalArea()-_newDB->getNodesArea())/_newDB->getNodesArea(), 00110 _newDB->getXSize()/_newDB->getYSize(), 0, _newDB->evalHPWL(), 00111 0, 1, 0); 00112 */ 00113 double reqdWidth = 1e100; 00114 double reqdHeight = 1e100; 00115 double oldDBArea = _db->getNodesArea(); 00116 double newDBArea = _newDB->getNodesArea(); 00117 // double maxArea = (1+_params->maxWS/100)*_newDB->getNodesArea(); 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 //convert placement to sequence pair 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 //_newDB->plot("out.plt", currArea, 0, 0, 0, 0, 0, 0, 0); 00166 } 00167 00168 //annealer->eval(); 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 //_newDB->save("temp"); 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 // do the shifting HPWL optimization at the very end 00195 // if (_params->minWL) 00196 // annealer->postHPWLOpt(); 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 //if not satisfied. then save best solution 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 //change the annealer to BTree if 1'st 2 iterations fail 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)//failed to satisfy constraints. save best soln 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 _newDB->plot("main.plt", _newDB->evalArea(), 00288 100*(_newDB->evalArea()-_newDB->getNodesArea())/_newDB->getNodesArea(), 00289 _newDB->getXSize()/_newDB->getYSize(), 0, _newDB->evalHPWL(), 00290 0, 0, 1); 00291 00292 _db->plot("final.plt", _db->evalArea(), 00293 100*(_db->evalArea()-_db->getNodesArea())/_db->getNodesArea(), 00294 _db->getXSize()/_db->getYSize(), 0, _db->evalHPWL(), 00295 0, 0, 0); 00296 */ 00297 } |
Here is the call graph for this function:
|
Definition at line 299 of file SolveMulti.cxx. References _db, _newDB, _params, abkfatal, parquetfp::Command_Line::budgetTime, parquetfp::Node::changeOrient(), Verbosity::forMajStats, parquetfp::Command_Line::FPrep, parquetfp::DB::getNets(), parquetfp::Nodes::getNode(), parquetfp::DB::getNodes(), parquetfp::DB::getNumNodes(), parquetfp::DB::getXSize(), parquetfp::DB::getYSize(), BaseAnnealer::go(), parquetfp::DB::initPlacement(), parquetfp::itNode, parquetfp::Command_Line::maxIterHier, parquetfp::N, parquetfp::Nodes::nodesBegin(), parquetfp::Nodes::nodesEnd(), parquetfp::Node::putHeight(), parquetfp::Node::putWidth(), parquetfp::Node::putX(), parquetfp::Node::putY(), parquetfp::Command_Line::reqdAR, parquetfp::DB::shiftDesign(), parquetfp::Command_Line::verb, parquetfp::Point::x, and parquetfp::Point::y. Referenced by go().
00300 { 00301 Nodes* nodes = _newDB->getNodes(); 00302 Nodes* origNodes = _db->getNodes(); 00303 00304 //itNode node; 00305 00306 Command_Line* params = new Command_Line(*_params); 00307 params->budgetTime = 0; // (false) 00308 00309 // for each node at top-level 00310 for(itNode node=nodes->nodesBegin(); node!=nodes->nodesEnd(); ++node) 00311 { 00312 Point dbLoc; // location of a top-level block 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 // do the shifting HPWL optimization after packing 00367 // if (_params->minWL) 00368 // annealer->postHPWLOpt(); 00369 00370 currXSize = tempDB->getXSize(); 00371 currYSize = tempDB->getYSize(); 00372 if(currXSize<=reqdWidth && currYSize<=reqdHeight) 00373 break; 00374 00375 //if not satisfied. then save best solution 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)//failed to satisfy constraints. save best soln 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 // *(_newDB->getNets())); 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 } // end for each node 00473 } |
Here is the call graph for this function:
|
Definition at line 475 of file SolveMulti.cxx. References _db, _params, parquetfp::Node::changeOrient(), parquetfp::DB::getNets(), parquetfp::Nodes::getNode(), parquetfp::DB::getNodes(), parquetfp::Node::getX(), parquetfp::DB::getXSize(), parquetfp::Node::getY(), parquetfp::DB::getYSize(), parquetfp::itNode, parquetfp::Nodes::nodesBegin(), parquetfp::Nodes::nodesEnd(), parquetfp::Node::putHeight(), parquetfp::Node::putWidth(), parquetfp::Node::putX(), parquetfp::Node::putY(), and parquetfp::Command_Line::usePhyLocHier. Referenced by go().
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 //tempNode.changeOrient(node->getOrient(), *(_db->getNets())); 00515 } 00516 } 00517 else if(node->numSubBlocks() == 1) //the only block 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 } |
Here is the call graph for this function:
|
Definition at line 55 of file SolveMulti.h. Referenced by clusterOnly(), go(), placeSubBlocks(), SolveMulti(), and updatePlaceUnCluster(). |
|
Definition at line 57 of file SolveMulti.h. Referenced by go(), placeSubBlocks(), SolveMulti(), and ~SolveMulti(). |
|
Definition at line 56 of file SolveMulti.h. Referenced by clusterOnly(), go(), placeSubBlocks(), SolveMulti(), and updatePlaceUnCluster(). |
|
Definition at line 69 of file SolveMulti.h. Referenced by go(), and SolveMulti(). |
|
Definition at line 68 of file SolveMulti.h. Referenced by clusterOnly(), go(), and SolveMulti(). |