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

SolveMulti.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 #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; // return a brand-new DB, to be deleted
00078 }
00079 
00080 void SolveMulti::go(void)
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 }
00298 
00299 void SolveMulti::placeSubBlocks(void)
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 }
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             //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 }

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