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 #include "Parquet.h"
00042 #include "ABKCommon/paramproc.h"
00043
00044 #include "mixedpacking.h"
00045 #include "baseannealer.h"
00046 #include "btreeanneal.h"
00047
00048 #include <iostream>
00049 #include <iomanip>
00050 #include <cfloat>
00051 #include <algorithm>
00052 using namespace std;
00053 using namespace parquetfp;
00054
00055
00056 int main(int argc, char *argv[])
00057 {
00058 Parquet engine(argc, const_cast<const char**>(argv));
00059 return engine.go();
00060 }
00061
00062 Parquet::Parquet(int argc,
00063 const char *argv[])
00064 : params(argc, argv)
00065 {
00066 BoolParam help1 ("h", argc, argv);
00067 BoolParam help2 ("help", argc, argv);
00068 NoParams noParams(argc,argv);
00069 params.printAnnealerParams();
00070
00071 if (noParams.found() || help1.found() || help2.found())
00072 {
00073 params.printHelp(argc, argv);
00074 exit (0);
00075 }
00076 }
00077
00078 int Parquet::go()
00079 {
00080 Timer T;
00081 T.stop();
00082
00083 double totalTime = 0;
00084 double successTime = 0;
00085 double successAvgWL = 0;
00086 double successAvgWLnoWts = 0;
00087 double successAvgArea = 0;
00088 double successMinWL = DBL_MAX;
00089 double successMinWLnoWts = DBL_MAX;
00090 double successMinArea = DBL_MAX;
00091 double successMaxWL = 0;
00092 double successMaxWLnoWts = 0;
00093 double successMaxArea = 0;
00094 double successAR = 0;
00095
00096 double minArea = DBL_MAX;
00097 double minWS = DBL_MAX;
00098 double minWL = DBL_MAX;
00099 double minWLnoWts = DBL_MAX;
00100
00101 double aveArea = 0;
00102 double aveWS = 0;
00103 double aveWL = 0;
00104 double aveWLnoWts = 0;
00105
00106 double maxArea = 0;
00107 double maxWS = 0;
00108 double maxWL = 0;
00109 double maxWLnoWts = 0;
00110
00111 double currArea = DBL_MAX;
00112 double currWS = DBL_MAX;
00113 double currWL = DBL_MAX;
00114 double currXSize = DBL_MAX;
00115 double currYSize = DBL_MAX;
00116 double currWLnoWts = DBL_MAX;
00117
00118
00119 for (int i = 0; i < params.iterations; i++)
00120 {
00121 cout << endl << "***** START: round " << (i+1) << " / "
00122 << params.iterations << " *****" << endl;
00123
00124 string blocksname(params.inFileName);
00125 blocksname += ".blocks";
00126 MixedBlockInfoType blockinfo(blocksname, "blocks");
00127 DB db(const_cast<char*>(params.inFileName));
00128
00129
00130 double blocksArea = db.getNodesArea();
00131 const double reqdArea = blocksArea * (1 + (params.maxWS/100.0));
00132 const double reqdWidth = sqrt(reqdArea * params.reqdAR);
00133 const double reqdHeight = reqdWidth / params.reqdAR;
00134 bool gotBetterSol = false;
00135
00136 T.start(0.0);
00137
00138 if (!params.solveMulti)
00139 {
00140 BaseAnnealer *annealer = NULL;
00141 if (params.FPrep == "BTree")
00142 {
00143 annealer =
00144 new BTreeAreaWireAnnealer(blockinfo,
00145 const_cast<Command_Line*>(¶ms),
00146 &db);
00147 }
00148 else if (params.FPrep == "SeqPair")
00149 {
00150 annealer = new Annealer(¶ms, &db);
00151 }
00152 else
00153 {
00154 abkfatal(false, "Invalid floorplan representation specified");
00155 exit(1);
00156 }
00157
00158
00159 if (params.takePl)
00160 {
00161 cout << endl;
00162 cout << "----- Converting placement to initial solution -----"
00163 << endl;
00164 annealer->takePlfromDB();
00165 cout << "----- done converting -----" << endl;
00166 }
00167
00168 if (params.initQP)
00169 {
00170 cout << endl;
00171 cout << "----- Computing quadratic-minimum WL solution -----"
00172 << endl;
00173 annealer->BaseAnnealer::solveQP();
00174 cout << "----- done computing -----" << endl;
00175
00176 cout << "----- Converting placement to initial solution -----"
00177 << endl;
00178 annealer->takePlfromDB();
00179 cout << "----- done converting -----" << endl;
00180 }
00181
00182 if (params.initCompact)
00183 {
00184
00185 cout << endl;
00186 cout << "----- Compacting initial solution -----"
00187 << endl;
00188 annealer->compactSoln();
00189 cout << "----- done compacting -----" << endl;
00190 }
00191
00192 cout << endl;
00193 cout << "----- Annealing with " << params.FPrep
00194 << " -----" << endl;
00195 annealer->go();
00196 cout << "----- Annealing with " << params.FPrep
00197 << " -----" << endl;
00198
00199 if(params.compact)
00200 {
00201
00202 cout << endl;
00203 cout << "----- Compacting the final solution -----"
00204 << endl;
00205 annealer->compactSoln();
00206 cout << "----- done compacting -----" << endl;
00207 }
00208
00209 if (params.minWL &&
00210 params.reqdAR != BaseAnnealer::FREE_OUTLINE)
00211 {
00212
00213 cout << endl;
00214 cout << "----- Try Shifting the design for better HPWL -----"
00215 << endl;
00216 annealer->postHPWLOpt();
00217 cout << "----- done trying -----" << endl;
00218 }
00219
00220
00221
00222 delete annealer;
00223 }
00224 else
00225 {
00226
00227 SolveMulti solveMulti(const_cast<DB*>(&db),
00228 const_cast<Command_Line*>(¶ms));
00229 solveMulti.go();
00230
00231 if (params.compact)
00232 {
00233
00234 Annealer annealer(¶ms, &db);
00235 annealer.takePlfromDB();
00236 annealer.compactSoln();
00237 }
00238 }
00239
00240 db.cornerOptimizeDesign();
00241 T.stop();
00242
00243
00244 totalTime += T.getUserTime();
00245 currXSize = db.getXSize();
00246 currYSize = db.getYSize();
00247
00248 currArea = currXSize * currYSize;
00249 currWS = 100*(currArea - blocksArea)/blocksArea;
00250 currWL = db.evalHPWL();
00251 currWLnoWts = db.evalHPWL(false);
00252
00253 gotBetterSol = false;
00254 if (params.reqdAR != BaseAnnealer::FREE_OUTLINE)
00255 {
00256 gotBetterSol = (currXSize <= reqdWidth && currYSize <= reqdHeight);
00257
00258 if (params.minWL)
00259 gotBetterSol = gotBetterSol && (currWL < successMinWL);
00260 else
00261 gotBetterSol = gotBetterSol && (currArea < successMinArea);
00262 }
00263 else if (params.minWL)
00264 gotBetterSol = (currWL < minWL);
00265 else
00266 gotBetterSol = (currArea < minArea);
00267
00268 aveArea += currArea;
00269 aveWS += currWS;
00270 aveWL += currWL;
00271 aveWLnoWts += currWLnoWts;
00272
00273 minArea = min(minArea, currArea);
00274 minWS = min(minWS, currWS);
00275 minWL = min(minWL, currWL);
00276 minWLnoWts = min(minWLnoWts, currWLnoWts);
00277
00278 maxArea = max(maxArea, currArea);
00279 maxWS = max(maxWS, currWS);
00280 maxWL = max(maxWL, currWL);
00281 maxWLnoWts = max(maxWLnoWts, currWLnoWts);
00282
00283
00284 if(params.reqdAR != BaseAnnealer::FREE_OUTLINE &&
00285 ((currArea <= reqdArea &&
00286 currXSize <= reqdWidth &&
00287 currYSize <= reqdHeight) || db.successAR))
00288 {
00289 ++successAR;
00290 successTime += T.getUserTime();
00291
00292 successAvgWL += currWL;
00293 successAvgArea += currArea;
00294 successAvgWLnoWts += currWLnoWts;
00295
00296 successMinWL = min(successMinWL, currWL);
00297 successMinArea = min(successMinArea, currArea);
00298 successMinWLnoWts = min(successMinWLnoWts, currWLnoWts);
00299
00300 successMaxWL = max(successMaxWL, currWL);
00301 successMaxArea = max(successMaxArea, currArea);
00302 successMaxWLnoWts = max(successMaxWLnoWts, currWLnoWts);
00303 }
00304
00305
00306 if(gotBetterSol)
00307 {
00308 if(params.plot)
00309 {
00310 double currAR = currXSize/currYSize;
00311 bool plotSlacks = !params.plotNoSlacks;
00312 bool plotNets = !params.plotNoNets;
00313 bool plotNames = !params.plotNoNames;
00314 db.plot("out.plt", currArea, currWS, currAR, T.getUserTime(),
00315 currWL, plotSlacks, plotNets, plotNames);
00316 }
00317
00318 if(params.savePl)
00319 db.getNodes()->savePl(const_cast<char*>(params.outPlFile));
00320
00321 if(params.saveCapoPl)
00322 db.getNodes()->saveCapoPl(const_cast<char*>(params.capoPlFile));
00323
00324 if(params.saveCapo)
00325 db.saveCapo(const_cast<char*>(params.capoBaseFile),
00326 params.reqdAR);
00327
00328 if(params.save)
00329 db.save(const_cast<char*>(params.baseFile));
00330
00331
00332
00333 }
00334
00335 BaseAnnealer::SolutionInfo curr;
00336 curr.area = currArea;
00337 curr.width = currXSize;
00338 curr.height = currYSize;
00339 curr.HPWL = currWL;
00340
00341
00342
00343
00344 cout << "***** DONE: round " << (i+1) << " / "
00345 << params.iterations << " *****" << endl;
00346
00347 }
00348
00349 aveArea /= params.iterations;
00350 aveWS /= params.iterations;
00351 aveWL /= params.iterations;
00352 aveWLnoWts /= params.iterations;
00353 totalTime /= params.iterations;
00354 successTime /= successAR;
00355 successAvgWL /= successAR;
00356 successAvgWLnoWts /= successAR;
00357 successAvgArea /= successAR;
00358 successAR /= params.iterations;
00359
00360 cout << endl;
00361 cout << "***** SUMMARY of all rounds *****" << endl;
00362 cout << setw(15) << "Area: " << "Min: " << minArea << " Average: "
00363 << aveArea << " Max: " << maxArea << endl;
00364 cout << setw(15) << "HPWL: "<< "Min: " << minWL << " Average: "
00365 << aveWL << " Max: " << maxWL << endl;
00366 cout << setw(15) << "Unweighted HPWL: "<< "Min: " <<minWLnoWts<<" Average: "
00367 << aveWLnoWts << " Max: " << maxWLnoWts << endl;
00368 cout << setw(15) << "WhiteSpace: " << "Min: " << minWS << "% Average: "
00369 << aveWS << "%" << " Max: " << maxWS << "%" << endl;
00370 cout << "Average Time: " << totalTime << endl;
00371
00372 if (params.reqdAR != BaseAnnealer::FREE_OUTLINE)
00373 {
00374 cout << endl;
00375 cout << "Success Rate of satisfying fixed outline: "
00376 << (100*successAR) << " %" << endl;
00377
00378 if (successAR > 0)
00379 {
00380 cout << setw(15) << "Area: " << "Min: " << successMinArea
00381 << " Average: "
00382 << successAvgArea << " Max: " << successMaxArea << endl;
00383 cout << setw(15) << "HPWL: "<< "Min: " << successMinWL << " Average: "
00384 << successAvgWL << " Max: " << successMaxWL << endl;
00385 cout << setw(15) << "Unweighted HPWL: "<< "Min: " << successMinWLnoWts
00386 << " Average: "<< successAvgWLnoWts << " Max: "
00387 << successMaxWLnoWts << endl;
00388 cout << "Average Time: " << successTime << endl;
00389 }
00390 }
00391 return 0;
00392 }