AMF-Placer  2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
WirelengthOptimizer.cc
Go to the documentation of this file.
1 
26 #include "WirelengthOptimizer.h"
27 
28 #include <cmath>
29 #include <omp.h>
30 
31 WirelengthOptimizer::WirelengthOptimizer(PlacementInfo *placementInfo, std::map<std::string, std::string> &JSONCfg,
32  bool verbose)
33  : placementInfo(placementInfo), JSONCfg(JSONCfg), verbose(verbose)
34 {
35  if (JSONCfg.find("MKL") != JSONCfg.end())
36  {
37  MKLorNot = JSONCfg["MKL"] == "true";
38  }
39  if (JSONCfg.find("useUnconstrainedCG") != JSONCfg.end())
40  {
41  useUnconstrainedCG = JSONCfg["useUnconstrainedCG"] == "true";
42  }
43  if (JSONCfg.find("pin2pinEnhance") != JSONCfg.end())
44  {
45  pin2pinEnhance = std::stof(JSONCfg["pin2pinEnhance"]);
46  }
47  if (JSONCfg.find("DSPCritical") != JSONCfg.end())
48  DSPCritical = JSONCfg["DSPCritical"] == "true";
49  if (JSONCfg.find("y2xRatio") != JSONCfg.end())
50  y2xRatio = std::stof(JSONCfg["y2xRatio"]);
51  float leftBound = placementInfo->getGlobalMinX() - 0.5;
52  float rightBound = placementInfo->getGlobalMaxX() + 0.5;
53  float bottomBound = placementInfo->getGlobalMinY() - 0.5;
54  float topBound = placementInfo->getGlobalMaxY() + 0.5;
55  xSolver = new QPSolverWrapper(useUnconstrainedCG, MKLorNot, leftBound, rightBound,
57  ySolver = new QPSolverWrapper(useUnconstrainedCG, MKLorNot, bottomBound, topBound,
59  if (JSONCfg.find("DirectMacroLegalize") != JSONCfg.end())
60  {
61  directMacroLegalize = JSONCfg["DirectMacroLegalize"] == "true";
63  {
64  print_warning("Direct Macro Legalization is enbaled. It might undermine the HPWL.");
65  }
66  }
67 }
68 
70 {
71  if (xSolver)
72  delete xSolver;
73  if (ySolver)
74  delete ySolver;
75  float leftBound = placementInfo->getGlobalMinX() - 0.5;
76  float rightBound = placementInfo->getGlobalMaxX() + 0.5;
77  float bottomBound = placementInfo->getGlobalMinY() - 0.5;
78  float topBound = placementInfo->getGlobalMaxY() + 0.5;
79  xSolver = new QPSolverWrapper(useUnconstrainedCG, MKLorNot, leftBound, rightBound,
81  ySolver = new QPSolverWrapper(useUnconstrainedCG, MKLorNot, bottomBound, topBound,
83 
84  netPinEnhanceRate.clear();
85  for (auto pNet : placementInfo->getPlacementNets())
86  {
87  auto designNet = pNet->getDesignNet();
88  if (!designNet->checkIsPowerNet() && !designNet->checkIsGlobalClock())
89  {
90  netPinEnhanceRate[designNet] = std::vector<float>(designNet->getPins().size(), -1);
91  }
92  }
93 
96  else
97  targetCellId = -1;
98 }
99 
100 void WirelengthOptimizer::GlobalPlacementQPSolve(float pesudoNetWeight, bool firstIteration,
101  bool forwardSolutionToNextIteration, bool enableMacroPseudoNet2Site,
102  bool considerNetNum, bool enableUserDefinedClusterOpt,
103  float displacementLimit, PlacementTimingOptimizer *timingOptimizer)
104 {
105  if (verbose)
106  print_status("A QP Iteration Started.");
107 
108  if (firstIteration)
109  {
110  if (timingOptimizer)
111  {
112  slackThr = timingOptimizer->getSlackThr();
114  slackPowerFactor, timingOptimizer, true);
115  }
116  }
117 
118  updateB2BNetWeight(pesudoNetWeight, enableMacroPseudoNet2Site, considerNetNum, enableUserDefinedClusterOpt,
119  timingOptimizer);
120  if (firstIteration)
121  solverLoadData();
122 
123  xSolver->solverSettings.solutionForward = forwardSolutionToNextIteration;
124  ySolver->solverSettings.solutionForward = forwardSolutionToNextIteration;
125 
126  if (verbose)
127  print_status("Solver Running.");
128  std::thread t1(QPSolverWrapper::QPSolve, std::ref(xSolver));
129  std::thread t2(QPSolverWrapper::QPSolve, std::ref(ySolver));
130  t1.join();
131  t2.join();
132  if (verbose)
133  print_status("Solver Done.");
134 
135  // solverLoadFixedData();
136  solverWriteBackData(displacementLimit);
137 
138  if (verbose)
139  print_status("A QP Iteration Started.");
140 }
141 
143 {
144  for (unsigned int tmpPUId = 0; tmpPUId < placementInfo->getPlacementUnits().size(); tmpPUId++)
145  {
146  auto tmpPU = placementInfo->getPlacementUnits()[tmpPUId];
147  xSolver->solverData.oriSolution[tmpPUId] = tmpPU->X();
148  ySolver->solverData.oriSolution[tmpPUId] = tmpPU->Y();
149  }
150 }
151 
153 {
156  {
157  for (unsigned int tmpPUId = 0; tmpPUId < placementInfo->getPlacementUnits().size(); tmpPUId++)
158  {
159  auto tmpPU = placementInfo->getPlacementUnits()[tmpPUId];
160  if (tmpPU->isFixed())
161  {
162  xSolver->solverData.oriSolution[tmpPUId] = tmpPU->X();
163  ySolver->solverData.oriSolution[tmpPUId] = tmpPU->Y();
164  }
165  }
166  }
167  else
168  {
169  for (unsigned int tmpPUId = 0; tmpPUId < placementInfo->getPlacementUnits().size(); tmpPUId++)
170  {
171  auto tmpPU = placementInfo->getPlacementUnits()[tmpPUId];
172  if (tmpPU->isFixed())
173  {
174  xSolver->solverData.solution[tmpPUId] = tmpPU->X();
175  ySolver->solverData.solution[tmpPUId] = tmpPU->Y();
176  }
177  }
178  }
179 }
180 
181 void WirelengthOptimizer::solverWriteBackData(float displacementLimit)
182 {
183  bool displacementLimitEnable = displacementLimit > 0;
185  unsigned int numPUs = placementInfo->getPlacementUnits().size();
186  if (displacementLimitEnable)
187  {
189  {
190 #pragma omp parallel for
191  for (unsigned int tmpPUId = 0; tmpPUId < numPUs; tmpPUId++)
192  {
193  auto tmpPU = placementInfo->getPlacementUnits()[tmpPUId];
194  if (tmpPU->isFixed())
195  continue;
196  float fX = xSolver->solverData.oriSolution[tmpPUId];
197  float fY = ySolver->solverData.oriSolution[tmpPUId];
198  float disX = std::fabs(fX - tmpPU->X());
199  float disY = std::fabs(fY - tmpPU->Y());
200  float dis = std::sqrt(disX * disX + disY * disY);
201  float disRatio = displacementLimit / dis;
202  if (disRatio < 1)
203  {
204  fX = tmpPU->X() + (fX - tmpPU->X()) * disRatio;
205  fY = tmpPU->Y() + (fY - tmpPU->Y()) * disRatio;
206  }
207  placementInfo->legalizeXYInArea(tmpPU, fX, fY);
208  tmpPU->setAnchorLocation(fX, fY);
209  }
210  }
211  else
212  {
213 #pragma omp parallel for
214  for (unsigned int tmpPUId = 0; tmpPUId < numPUs; tmpPUId++)
215  {
216  auto tmpPU = placementInfo->getPlacementUnits()[tmpPUId];
217  if (tmpPU->isFixed())
218  continue;
219  float fX = xSolver->solverData.solution[tmpPUId];
220  float fY = ySolver->solverData.solution[tmpPUId];
221  float disX = std::fabs(fX - tmpPU->X());
222  float disY = std::fabs(fY - tmpPU->Y());
223  float dis = std::sqrt(disX * disX + disY * disY);
224  float disRatio = displacementLimit / dis;
225  if (disRatio < 1)
226  {
227  fX = tmpPU->X() + (fX - tmpPU->X()) * disRatio;
228  fY = tmpPU->Y() + (fY - tmpPU->Y()) * disRatio;
229  }
230  placementInfo->legalizeXYInArea(tmpPU, fX, fY);
231  tmpPU->setAnchorLocation(fX, fY);
232  }
233  }
234  }
235  else
236  {
238  {
239 #pragma omp parallel for
240  for (unsigned int tmpPUId = 0; tmpPUId < numPUs; tmpPUId++)
241  {
242  auto tmpPU = placementInfo->getPlacementUnits()[tmpPUId];
243  if (tmpPU->isFixed())
244  continue;
245  float fX = xSolver->solverData.oriSolution[tmpPUId];
246  float fY = ySolver->solverData.oriSolution[tmpPUId];
247  placementInfo->legalizeXYInArea(tmpPU, fX, fY);
248  tmpPU->setAnchorLocation(fX, fY);
249  }
250  }
251  else
252  {
253 #pragma omp parallel for
254  for (unsigned int tmpPUId = 0; tmpPUId < numPUs; tmpPUId++)
255  {
256  auto tmpPU = placementInfo->getPlacementUnits()[tmpPUId];
257  if (tmpPU->isFixed())
258  continue;
259  float fX = xSolver->solverData.solution[tmpPUId];
260  float fY = ySolver->solverData.solution[tmpPUId];
261  placementInfo->legalizeXYInArea(tmpPU, fX, fY);
262  tmpPU->setAnchorLocation(fX, fY);
263  }
264  }
265  }
266 }
267 
268 void WirelengthOptimizer::updateB2BNetWeight(float pesudoNetWeight, bool enableMacroPseudoNet2Site, bool considerNetNum,
269  bool enableUserDefinedClusterOpt,
270  PlacementTimingOptimizer *timingOptimizer)
271 {
272  if (verbose)
273  print_status("update B2B Net Weight Start.");
274 
275  bool updateTrue = true, updateFalse = false;
276  std::thread t1(updateB2BNetWeightWorker, std::ref(placementInfo),
279  std::ref(generalNetWeight), std::ref(y2xRatio), std::ref(updateTrue), std::ref(updateFalse));
280  std::thread t2(updateB2BNetWeightWorker, std::ref(placementInfo),
283  std::ref(generalNetWeight), std::ref(y2xRatio), std::ref(updateFalse), std::ref(updateTrue));
284  t1.join();
285  t2.join();
286 
287  if (enableMacroPseudoNet2Site && !directMacroLegalize)
288  {
289  addPseudoNetForMacros(pesudoNetWeight, considerNetNum);
290  }
291  else
292  {
293  print_warning("addPseudoNetForMacros is disabled according to placer configuration.");
294  }
295 
296  if (timingOptimizer)
297  {
299  timingOptimizer);
300  if (timingOptimizer->getEffectFactor() > 0.5)
302  pin2pinEnhance, timingOptimizer);
303  }
304 
305  if (enableUserDefinedClusterOpt)
306  {
307  updatePseudoNetForUserDefinedClusters(pesudoNetWeight);
308  }
309 
310  addPseudoNet2LoctionForAllPUs(pesudoNetWeight, considerNetNum);
311  updatePseudoNetForClockRegion(0.2 * pesudoNetWeight);
312 
313  if (verbose)
314  print_status("update B2B Net Weight Done.");
315 
316  if (JSONCfg.find("DrawNetAfterEachIteration") != JSONCfg.end())
317  {
318  if (JSONCfg["DrawNetAfterEachIteration"] == "true")
319  {
320  int netId;
321  std::cout << "please input the ID of net you want to show (-1 for stopping):\n";
322  std::cin >> netId;
323  while (netId >= 0)
324  {
325  auto net = placementInfo->getPlacementNets()[netId];
326  net->drawNet();
327  std::cout << "please input the ID of net you want to show (-1 for stopping):\n";
328  std::cin >> netId;
329  }
330  }
331  }
332 }
333 
335  std::vector<Eigen::Triplet<float>> &objectiveMatrixTripletList,
336  std::vector<float> &objectiveMatrixDiag,
337  Eigen::VectorXd &objectiveVector, float generalNetWeight,
338  float y2xRatio, bool updateX, bool updateY)
339 {
340  objectiveMatrixTripletList.clear();
341  objectiveMatrixDiag.clear();
342  objectiveMatrixDiag.resize(placementInfo->getPlacementUnits().size(), 0);
343  objectiveVector = Eigen::VectorXd::Zero(placementInfo->getPlacementUnits().size());
344  for (auto net : placementInfo->getPlacementNets())
345  {
346  if (net->getDesignNet()->checkIsPowerNet()) // Power nets are on the entrie device. Ignore them.
347  continue;
348 
349  if (net->updateNetBounds(updateX, updateY))
350  {
351  net->updateBound2BoundNetWeight(objectiveMatrixTripletList, objectiveMatrixDiag, objectiveVector,
352  generalNetWeight, y2xRatio, updateX, updateY);
353  }
354  }
355 }
356 void WirelengthOptimizer::addPseudoNetForMacros(float pesudoNetWeight, bool considerNetNum)
357 {
358  std::map<PlacementInfo::PlacementUnit *, float> &PUX = placementInfo->getPULegalXY().first;
359  std::map<PlacementInfo::PlacementUnit *, float> &PUY = placementInfo->getPULegalXY().second;
361 
362  if (placementInfo->getProgress() > 0.8)
364  if (placementInfo->getProgress() > 0.90)
366  if (macroPseudoNetCnt > 40)
368  float macroPseudoNetFactor = (float)macroPseudoNetCnt / 20 * oriMacroLegalizationWeight;
369  print_info("WLOptimizer macroLegalizePseudoNet=" + std::to_string(macroPseudoNetFactor * pesudoNetWeight));
370  if (considerNetNum)
371  {
372  for (auto pairPUX : PUX)
373  {
374  if (!pairPUX.first->checkHasBRAM() && !pairPUX.first->checkHasDSP() && !pairPUX.first->checkHasCARRY())
377  xSolver->solverData.objectiveVector, pairPUX.first, pairPUX.second,
378  macroPseudoNetFactor * pesudoNetWeight * pairPUX.first->getNetsSetPtr()->size() / 3, y2xRatio, true,
379  false); // CLB-like element
380  else if (pairPUX.first->checkHasCARRY())
383  xSolver->solverData.objectiveVector, pairPUX.first, pairPUX.second,
384  macroPseudoNetFactor * pesudoNetWeight * pairPUX.first->getNetsSetPtr()->size() / 5, y2xRatio, true,
385  false); // CARRY-CHAIN-like element
386  else
389  xSolver->solverData.objectiveVector, pairPUX.first, pairPUX.second,
390  macroPseudoNetFactor * pesudoNetWeight * pairPUX.first->getNetsSetPtr()->size(), y2xRatio, true,
391  false); // DSP-BRAM-like element
392  }
393  for (auto pairPUY : PUY)
394  {
395  if (!pairPUY.first->checkHasBRAM() && !pairPUY.first->checkHasDSP() && !pairPUY.first->checkHasCARRY())
398  ySolver->solverData.objectiveVector, pairPUY.first, pairPUY.second,
399  macroPseudoNetFactor * pesudoNetWeight * pairPUY.first->getNetsSetPtr()->size() / 3, y2xRatio,
400  false, true); // CLB-like element
401  else if (pairPUY.first->checkHasCARRY())
404  ySolver->solverData.objectiveVector, pairPUY.first, pairPUY.second,
405  macroPseudoNetFactor * pesudoNetWeight * pairPUY.first->getNetsSetPtr()->size() / 5, y2xRatio,
406  false, true); // CARRY-CHAIN-like element
407  else
410  ySolver->solverData.objectiveVector, pairPUY.first, pairPUY.second,
411  macroPseudoNetFactor * pesudoNetWeight * pairPUY.first->getNetsSetPtr()->size(), y2xRatio, false,
412  true); // DSP-BRAM-like element
413  }
414  }
415  else
416  {
417  for (auto pairPUX : PUX)
418  {
421  xSolver->solverData.objectiveVector, pairPUX.first, pairPUX.second,
422  macroPseudoNetFactor * pesudoNetWeight, y2xRatio, true, false);
423  }
424  for (auto pairPUY : PUY)
425  {
428  ySolver->solverData.objectiveVector, pairPUY.first, pairPUY.second,
429  macroPseudoNetFactor * pesudoNetWeight, y2xRatio, false, true);
430  }
431  }
432 }
433 
434 void WirelengthOptimizer::addPseudoNet_SlackBased(float timingWeight, double slackPowFactor,
435  PlacementTimingOptimizer *timingOptimizer, bool calculate)
436 {
437  if (calculate)
438  {
439  for (auto list : PNetId2SlackEnhanceTuples)
440  {
441  if (list)
442  delete list;
443  }
445  PNetId2SlackEnhanceTuples.resize(placementInfo->getPlacementNets().size(), nullptr);
446 
447  assert(placementInfo->getTimingInfo());
448  if (slackPowFactor < 0 || timingWeight < 0)
449  return;
450 
451  // float maxEnhanceRatio = 0;
453  // float clockPeriod = placementInfo->getTimingInfo()->getSimplePlacementTimingGraph()->getClockPeriod();
454  auto &cellLoc = placementInfo->getCellId2location();
455  assert(cellLoc.size() == timingNodes.size());
456  auto &netActualSlackPinNum = timingOptimizer->getNetActualSlackPinNum();
457 
458  int enhanceNetCnt = 0;
459  unsigned int highFanoutThr = 10000;
460 
462  {
463  highFanoutThr = 1000;
464  print_warning("highFanoutThr is set to 1000");
465  }
466 
467  // int targetCellId = placementInfo->getDesignInfo()->getCell(targetCellName)->getCellId();
468 
469  int netNum = placementInfo->getPlacementNets().size();
470 
471 #pragma omp parallel for
472  for (int PNetId = 0; PNetId < netNum; PNetId++)
473  {
474  PNetId2SlackEnhanceTuples[PNetId] = new std::vector<slackEnhanceTuple>();
475  auto curNet = placementInfo->getPlacementNets()[PNetId];
476  assert(curNet);
477  auto designNet = curNet->getDesignNet();
478  assert(designNet);
479  assert(curNet->getId() < PNetId2SlackEnhanceTuples.size());
480  assert(curNet->getId() == PNetId);
481  if (designNet->checkIsPowerNet() || designNet->checkIsGlobalClock())
482  continue;
483 
484  if (curNet->getDriverUnits().size() != 1 || curNet->getUnits().size() <= 1 ||
485  curNet->getUnits().size() >= highFanoutThr)
486  continue;
487  auto &PUs = curNet->getUnits();
488  auto &pins = designNet->getPins();
489  int pinNum = pins.size();
490 
491  assert(curNet->getUnits().size() == (unsigned int)pinNum);
492 
493  int driverPinInNet = -1;
494 
495  for (int i = 0; i < pinNum; i++)
496  {
497  if (pins[i]->isOutputPort())
498  {
499  driverPinInNet = i;
500  break;
501  }
502  }
503 
504  assert(driverPinInNet >= 0);
505 
506  // get the srcPin information
507  auto srcCell = pins[driverPinInNet]->getCell();
508  unsigned int srcCellId = srcCell->getCellId();
509  auto srcNode = timingNodes[srcCellId];
510  auto srcLoc = cellLoc[srcCellId];
511  int driverPathLen = timingNodes[srcCellId]->getLongestPathLength();
512 
513  if (netActualSlackPinNum[curNet] == 0)
514  continue;
515 
516  float w = 2 * timingWeight / std::pow((float)(netActualSlackPinNum[curNet]), 0.5);
517 
518  if (srcCell->getCellId() == targetCellId)
519  {
520  std::cout << "driver: " << targetCellName << " x: " << srcLoc.X << " y: " << srcLoc.Y << "\n";
521  }
522  auto &pinEnhanceRate = netPinEnhanceRate[designNet];
523  // iterate the sinkPin for evaluation and enhancement
524  float timingEffect = timingOptimizer->getEffectFactor();
525  for (int pinBeDriven = 0; pinBeDriven < pinNum; pinBeDriven++)
526  {
527  if (pinBeDriven == driverPinInNet)
528  continue;
529 
530  // get the sinkPin information
531  auto sinkCell = pins[pinBeDriven]->getCell();
532  unsigned int sinkCellId = sinkCell->getCellId();
533  auto sinkNode = timingNodes[sinkCellId];
534  auto sinkLoc = cellLoc[sinkCellId];
535  int succPathLen = sinkNode->getLongestPathLength();
536  float netDelay =
537  timingOptimizer->getDelayByModel(sinkNode, srcNode, sinkLoc.X, sinkLoc.Y, srcLoc.X, srcLoc.Y);
538  float slack = sinkNode->getRequiredArrivalTime() - srcNode->getLatestOutputArrival() - netDelay;
539  float clockPeriod = sinkNode->getClockPeriod();
540  if (clockPeriod < 0)
541  {
543  std::cout << sinkCell << " has no clock setting!!\n";
544  }
545  if (slack > 0)
546  continue;
547  enhanceNetCnt++;
548  // enhance the net based on the slack
549  float enhanceRatio = std::pow(1 - slack / clockPeriod, slackPowFactor);
550  if (slack < slackThr)
551  {
552  enhanceRatio = std::pow(enhanceRatio, slack / slackThr * 3);
553  }
554  // * std::pow(netDelay / expectedAvgDelay_driver, 0.6);
555 
556  if (timingOptimizer->getEffectFactor() < 0.5)
557  {
558  if (srcNode->checkIsRegister())
559  {
560  if (succPathLen > 0)
561  {
562  float expectedAvgDelay_succ = clockPeriod / succPathLen;
563  if (netDelay > expectedAvgDelay_succ)
564  enhanceRatio =
565  std::max(enhanceRatio, (float)std::pow((netDelay / expectedAvgDelay_succ), 0.66));
566  }
567  }
568  else
569  {
570  if (driverPathLen > 0)
571  {
572  float expectedAvgDelay_driver = clockPeriod / driverPathLen;
573  if (netDelay > expectedAvgDelay_driver)
574  enhanceRatio =
575  std::max(enhanceRatio, (float)std::pow((netDelay / expectedAvgDelay_driver), 0.66));
576  }
577  }
578  }
579 
580  if (pinEnhanceRate[pinBeDriven] < 0)
581  {
582  pinEnhanceRate[pinBeDriven] = enhanceRatio;
583  }
584  else
585  {
586  if (enhanceRatio > 0)
587  {
588  float shrinkRatio = pinEnhanceRate[pinBeDriven] / enhanceRatio;
589  if (timingOptimizer->getEffectFactor() >= 1)
590  {
591  if (shrinkRatio > 300)
592  {
593  enhanceRatio = std::pow(enhanceRatio, 0.1) * std::pow(pinEnhanceRate[pinBeDriven], 0.9);
594  }
595  else if (shrinkRatio > 200)
596  {
597  enhanceRatio = std::pow(enhanceRatio, 0.2) * std::pow(pinEnhanceRate[pinBeDriven], 0.8);
598  }
599  else if (shrinkRatio > 100)
600  {
601  enhanceRatio =
602  std::pow(enhanceRatio, 0.33) * std::pow(pinEnhanceRate[pinBeDriven], 0.67);
603  }
604  else if (shrinkRatio > 64)
605  {
606  enhanceRatio = std::pow(enhanceRatio, 0.4) * std::pow(pinEnhanceRate[pinBeDriven], 0.6);
607  }
608  }
609  pinEnhanceRate[pinBeDriven] = enhanceRatio;
610  }
611  }
612  if (srcCell->getCellId() == targetCellId)
613  {
614  std::cout << "sink: " << sinkCell->getName() << " x: " << sinkLoc.X << " y: " << sinkLoc.Y
615  << " netDelay: " << netDelay << " slack: " << slack << " w: " << w
616  << " enhanceRatio: " << enhanceRatio << "\n";
617  }
618  if (sinkCell->getCellId() == targetCellId)
619  {
620  std::cout << "src: " << srcCell->getName() << " x: " << srcLoc.X << " y: " << srcLoc.Y
621  << " netDelay: " << netDelay << " slack: " << slack << " w: " << w
622  << " enhanceRatio: " << enhanceRatio << "\n";
623  }
624 
625  PNetId2SlackEnhanceTuples[curNet->getId()]->emplace_back(w * enhanceRatio, PUs[driverPinInNet]->getId(),
626  PUs[pinBeDriven]->getId(), driverPinInNet,
627  pinBeDriven);
628  // curNet->addPseudoNet_enhancePin2Pin(
629  // xSolver->solverData.objectiveMatrixTripletList, xSolver->solverData.objectiveMatrixDiag,
630  // xSolver->solverData.objectiveVector, w * enhanceRatio, y2xRatio, true, false,
631  // PUs[driverPinInNet]->getId(), PUs[pinBeDriven]->getId(), driverPinInNet, pinBeDriven);
632 
633  // curNet->addPseudoNet_enhancePin2Pin(
634  // ySolver->solverData.objectiveMatrixTripletList, ySolver->solverData.objectiveMatrixDiag,
635  // ySolver->solverData.objectiveVector, w * enhanceRatio, y2xRatio, false, true,
636  // PUs[driverPinInNet]->getId(), PUs[pinBeDriven]->getId(), driverPinInNet, pinBeDriven);
637  }
638  }
639  }
640  else
641  {
642 
643  int netNum = placementInfo->getPlacementNets().size();
644  for (int PNetId = 0; PNetId < netNum; PNetId++)
645  {
646  auto curNet = placementInfo->getPlacementNets()[PNetId];
647  for (auto enhanceTuple : *PNetId2SlackEnhanceTuples[PNetId])
648  {
649  curNet->addPseudoNet_enhancePin2Pin(
651  xSolver->solverData.objectiveVector, enhanceTuple.weight, y2xRatio, true, false, enhanceTuple.PUAId,
652  enhanceTuple.PUBId, enhanceTuple.PinAId, enhanceTuple.PinBId);
653 
654  curNet->addPseudoNet_enhancePin2Pin(
656  ySolver->solverData.objectiveVector, enhanceTuple.weight, y2xRatio, false, true, enhanceTuple.PUAId,
657  enhanceTuple.PUBId, enhanceTuple.PinAId, enhanceTuple.PinBId);
658  }
659  }
660  }
661 
662  print_status("WirelengthOptimizer: addPseudoNet_SlackBased done");
663  // outfile0.close();
664 }
665 
666 void WirelengthOptimizer::LUTLUTPairing_TimingDriven(float timingWeight, float disThreshold,
667  PlacementTimingOptimizer *timingOptimizer)
668 {
669  float w = 2 * timingWeight / std::pow(2, 0.5);
670  if (disThreshold < 0)
671  return;
672  print_status("WirelengthOptimizer: Timing Driven Pairing LUTs.");
673  std::vector<PlacementInfo::Location> &cellLoc = placementInfo->getCellId2location();
674 
675  assert(placementInfo->getTimingInfo());
676 
677  // float maxEnhanceRatio = 0;
679  // float clockPeriod = placementInfo->getTimingInfo()->getSimplePlacementTimingGraph()->getClockPeriod();
680  assert(cellLoc.size() == timingNodes.size());
681 
682  int LUTLUTPairCnt = 0;
683  int longLenThr = placementInfo->getLongPathThresholdLevel();
684 
685  // std::sort(LUTsToEnhanceNet.begin(), LUTsToEnhanceNet.end(),
686  // [](const CellWithScore &a, const CellWithScore &b) -> bool { return a.score < b.score; });
687  // int targetCellId = placementInfo->getDesignInfo()->getCell(targetCellName)->getCellId();
688  for (auto curCell : placementInfo->getDesignInfo()->getCells())
689  {
690  auto predLUTPU =
691  dynamic_cast<PlacementInfo::PlacementUnit *>(placementInfo->getPlacementUnitByCellId(curCell->getCellId()));
692  if ((curCell->isLUT() || curCell->isMux() || curCell->isCarry()) && !curCell->isVirtualCell())
693  {
694  assert(curCell->getOutputPins().size() > 0);
695  if (curCell->getOutputPins().size() >= 1 && curCell->getOutputPins().size() <= 8)
696  {
697  auto srcCell = curCell;
698  unsigned int srcCellId = srcCell->getCellId();
699  auto srcNode = timingNodes[srcCellId];
700  auto srcLoc = cellLoc[srcCellId];
701  int driverPathLen = timingNodes[srcCellId]->getLongestPathLength();
702 
703  if (driverPathLen < longLenThr)
704  continue;
705  for (auto curOutputPin : curCell->getOutputPins())
706  {
707  if (curOutputPin
708  ->isUnconnected()) // interestingly, some LUTs generated by Vivado might have no output
709  continue;
710  assert(curOutputPin->getNet());
711 
712  auto curNet = curOutputPin->getNet();
713  auto curPNet = placementInfo->getPlacementNetByDesignNetId(curNet->getElementIdInType());
714 
715  if (!curPNet)
716  continue;
717 
718  float worstSlack = 0.0;
719  DesignInfo::DesignCell *targetSinkCell = nullptr;
720  int pinBeDriven = -1;
721  int pinOffsetId = -1;
722  if (curNet->getPins().size() > 16)
723  continue;
724 
725  for (auto curPin : curNet->getPins())
726  {
727  pinOffsetId++;
728  auto sinkCell = curPin->getCell();
729  if (sinkCell == curCell)
730  continue;
731 
732  if (sinkCell->isLUT())
733  {
734  unsigned int sinkCellId = sinkCell->getCellId();
735  auto sinkNode = timingNodes[sinkCellId];
736  auto sinkLoc = cellLoc[sinkCellId];
737  int succPathLen = sinkNode->getLongestPathLength();
738  if (succPathLen < longLenThr)
739  continue;
740  float netDelay = timingOptimizer->getDelayByModel(sinkNode, srcNode, sinkLoc.X, sinkLoc.Y,
741  srcLoc.X, srcLoc.Y);
742  float slack =
743  sinkNode->getRequiredArrivalTime() - srcNode->getLatestOutputArrival() - netDelay;
744 
745  float curDis = getCellDistance(srcLoc, sinkLoc);
746 
747  if (curDis < disThreshold && slack < worstSlack)
748  {
749  PlacementInfo::PlacementUnit *tmpSuccPU =
750  placementInfo->getPlacementUnitByCellId(sinkCell->getCellId());
751 
752  worstSlack = slack;
753  targetSinkCell = sinkCell;
754  pinBeDriven = pinOffsetId;
755  }
756  }
757  }
758 
759  if (targetSinkCell)
760  {
761  unsigned int sinkCellId = targetSinkCell->getCellId();
762  auto sinkNode = timingNodes[sinkCellId];
763  auto sinkLoc = cellLoc[sinkCellId];
764  float clockPeriod = sinkNode->getClockPeriod();
765  if (clockPeriod < 0)
766  {
767  clockPeriod =
769  }
770  PlacementInfo::PlacementUnit *succLUTPU =
772  float enhanceRatio = std::pow(1 - worstSlack / clockPeriod, slackPowerFactor);
773 
774  int driverPinInNet = -1;
775  auto &pins = curNet->getPins();
776  for (int i = 0; i < pins.size(); i++)
777  {
778  if (pins[i]->isOutputPort())
779  {
780  driverPinInNet = i;
781  break;
782  }
783  }
784 
785  float netDelay = timingOptimizer->getDelayByModel(sinkNode, srcNode, sinkLoc.X, sinkLoc.Y,
786  srcLoc.X, srcLoc.Y);
787  float slack = sinkNode->getRequiredArrivalTime() - srcNode->getLatestOutputArrival() - netDelay;
788 
789  if (srcCell->getCellId() == targetCellId)
790  {
791  std::cout << "LUTParing sink: " << targetSinkCell->getName() << " x: " << sinkLoc.X
792  << " y: " << sinkLoc.Y << " netDelay: " << netDelay << " slack: " << slack
793  << " w: " << w << " enhanceRatio: " << enhanceRatio << "\n";
794  }
795  if (targetSinkCell->getCellId() == targetCellId)
796  {
797  std::cout << "LUTParing src: " << srcCell->getName() << " x: " << srcLoc.X
798  << " y: " << srcLoc.Y << " netDelay: " << netDelay << " slack: " << slack
799  << " w: " << w << " enhanceRatio: " << enhanceRatio << "\n";
800  }
801  curPNet->addPseudoNet_enhancePin2Pin(
803  xSolver->solverData.objectiveVector, w * enhanceRatio, y2xRatio, true, false,
804  predLUTPU->getId(), succLUTPU->getId(), driverPinInNet, pinBeDriven);
805 
806  curPNet->addPseudoNet_enhancePin2Pin(
808  ySolver->solverData.objectiveVector, w * enhanceRatio, y2xRatio, false, true,
809  predLUTPU->getId(), succLUTPU->getId(), driverPinInNet, pinBeDriven);
810  }
811  }
812  }
813  else
814  {
815  // this is a LUT6_2, has two output pins and we don't pack them temporarily.
816  }
817  }
818  }
819 }
820 
821 void WirelengthOptimizer::addPseudoNet2LoctionForAllPUs(float pesudoNetWeight, bool considerNetNum)
822 {
823  int numPUs = placementInfo->getPlacementUnits().size();
824  float minDist = 0.5;
825  float powFactor = placementInfo->getProgress() * 0.5 + 0.5;
826 
827  std::vector<int> netCnt(101, 0);
828 
829  int netSizeThr = 1;
830  for (int PUId = 0; PUId < numPUs; PUId++)
831  {
832  auto curPU = placementInfo->getPlacementUnits()[PUId];
833 
834  float curX = curPU->X();
835  int size = curPU->getNetsSetPtr()->size() / 5;
836  if (size > 100)
837  size = 100;
838  netCnt[size]++;
839  }
840 
841  int highInterconnectPUCnt = 0;
842  for (int i = 100; i >= 2; i--)
843  {
844  highInterconnectPUCnt += netCnt[i];
845  if (highInterconnectPUCnt > 300)
846  break;
847  netSizeThr = i * 5;
848  }
849 
850  print_info("WirelengthOptimizer: PU net pin cnt distribution (netSizeThr=" + std::to_string(netSizeThr) + "):");
851 
852  for (int i = 0; i <= 100; i++)
853  std::cout << netCnt[i] << " ";
854  std::cout << "\n";
855 
856  if (netSizeThr > 100)
857  netSizeThr = 128;
858  else
859  netSizeThr = 64; //+ placementInfo->getProgress() * 128;
860 
861  if (considerNetNum)
862  {
863 #pragma omp parallel sections
864  {
865 #pragma omp section
866  {
867 #pragma omp parallel for // schedule(dynamic, 16)
868  for (int PUId = 0; PUId < numPUs; PUId++)
869  {
870  auto curPU = placementInfo->getPlacementUnits()[PUId];
871  bool movable = !curPU->isFixed();
872  if (movable)
873  {
874  float curX = curPU->X();
875  float lastX = curPU->lastX();
876  float size = curPU->getNetsSetPtr()->size();
877  if (size > netSizeThr)
878  size = netSizeThr;
881  xSolver->solverData.objectiveVector, curPU, curX,
882  std::pow(size, powFactor) * pesudoNetWeight / std::max(minDist, std::fabs(lastX - curX)),
883  y2xRatio, true, false);
884  }
885  }
886  }
887 #pragma omp section
888  {
889 #pragma omp parallel for // schedule(dynamic, 16)
890  for (int PUId = 0; PUId < numPUs; PUId++)
891  {
892  auto curPU = placementInfo->getPlacementUnits()[PUId];
893  bool movable = !curPU->isFixed();
894  if (movable)
895  {
896  float curY = curPU->Y();
897  float lastY = curPU->lastY();
898  float size = curPU->getNetsSetPtr()->size();
899  if (size > netSizeThr)
900  size = netSizeThr;
903  ySolver->solverData.objectiveVector, curPU, curY,
904  std::pow(size, powFactor) * pesudoNetWeight / std::max(minDist, std::fabs(lastY - curY)),
905  y2xRatio, false, true);
906  }
907  }
908  }
909  }
910  }
911  else
912  {
913 #pragma omp parallel sections
914  {
915 #pragma omp section
916  {
917 #pragma omp parallel for // schedule(dynamic, 16)
918  for (int PUId = 0; PUId < numPUs; PUId++)
919  {
920  auto curPU = placementInfo->getPlacementUnits()[PUId];
921  bool movable = !curPU->isFixed();
922  if (movable)
923  {
924  float curX = curPU->X();
925  float lastX = curPU->lastX();
928  xSolver->solverData.objectiveVector, curPU, curX,
929  pesudoNetWeight / std::max(minDist, std::fabs(lastX - curX)), y2xRatio, true, false);
930  }
931  }
932  }
933 #pragma omp section
934  {
935 #pragma omp parallel for // schedule(dynamic, 16)
936  for (int PUId = 0; PUId < numPUs; PUId++)
937  {
938  auto curPU = placementInfo->getPlacementUnits()[PUId];
939  bool movable = !curPU->isFixed();
940  if (movable)
941  {
942  float curY = curPU->Y();
943  float lastY = curPU->lastY();
946  ySolver->solverData.objectiveVector, curPU, curY,
947  pesudoNetWeight / std::max(minDist, std::fabs(lastY - curY)), y2xRatio, false, true);
948  }
949  }
950  }
951  }
952  }
953 }
954 
956 {
959  return;
960  std::vector<std::vector<DesignInfo::DesignCell *>> &predefinedCellClusters =
962 
963  std::set<PlacementInfo::PlacementUnit *> reallocatedPUs;
964 
965  int reallocateCells = 0;
966  for (auto &clusterCellSet : predefinedCellClusters)
967  {
968  std::set<PlacementInfo::PlacementUnit *> PUsInCurCluster;
969  PUsInCurCluster.clear();
970 
971  double avgX = 0;
972  double avgY = 0;
973  int totalCellNum = clusterCellSet.size();
974  if (totalCellNum < 24)
975  continue;
976  float clusterFactor = (200.0 / totalCellNum);
977  if (clusterFactor > 1)
978  clusterFactor = 1;
979  // if (clusterFactor < 0.5)
980  // clusterFactor = 0.333;
981  int totalNetNum = 0;
982 
983  float x0 = 10000, y0 = 10000, x1 = -10000, y1 = -10000;
984  for (auto tmpCell : clusterCellSet)
985  {
986  auto tmpPU = placementInfo->getPlacementUnitByCell(tmpCell);
987  if (PUsInCurCluster.find(tmpPU) == PUsInCurCluster.end())
988  {
989  PUsInCurCluster.insert(tmpPU);
990  avgX += tmpPU->X() * tmpPU->getNetsSetPtr()->size();
991  avgY += tmpPU->Y() * tmpPU->getNetsSetPtr()->size();
992  totalNetNum += tmpPU->getNetsSetPtr()->size();
993 
994  if (tmpPU->X() < x0)
995  x0 = tmpPU->X();
996  if (tmpPU->X() > x1)
997  x1 = tmpPU->X();
998  if (tmpPU->Y() < y0)
999  y0 = tmpPU->Y();
1000  if (tmpPU->Y() > y1)
1001  y1 = tmpPU->Y();
1002  }
1003  }
1004 
1005  if (PUsInCurCluster.size() > 1)
1006  {
1007  if ((x1 - x0) * (y1 - y0) / PUsInCurCluster.size() < 1 && (x1 - x0) * (y1 - y0) > 1)
1008  {
1009  avgX /= totalNetNum;
1010  avgY /= totalNetNum;
1011 
1012  for (auto tmpPU : PUsInCurCluster)
1013  {
1014  float fX = avgX;
1015  float fY = avgY;
1016  placementInfo->legalizeXYInArea(tmpPU, fX, fY);
1017 
1020  xSolver->solverData.objectiveVector, tmpPU, fX,
1021  userDefinedClusterFadeOutFactor * clusterFactor * pesudoNetWeight, y2xRatio, true, false);
1022 
1025  ySolver->solverData.objectiveVector, tmpPU, fY,
1026  1.0 / y2xRatio * userDefinedClusterFadeOutFactor * clusterFactor * pesudoNetWeight, y2xRatio,
1027  false, true);
1028 
1029  if (reallocatedPUs.find(tmpPU) == reallocatedPUs.end())
1030  {
1031  reallocatedPUs.insert(tmpPU);
1032  reallocateCells += tmpPU->getWeight();
1033  }
1034  }
1035  }
1036  }
1037  }
1038 
1039  print_warning("set user-defined cluster pseudo net for " + std::to_string(reallocatedPUs.size()) + " PU(s) and " +
1040  std::to_string(reallocateCells) + " cell(s).");
1041 }
1042 
1044 {
1045  if (pesudoNetWeight <= 0)
1046  return;
1047  auto &PU2ClockRegionCenter = placementInfo->getPU2ClockRegionCenters();
1048  auto &PU2ClockRegionColumn = placementInfo->getPU2ClockRegionColumn();
1049  auto &clockRegions = placementInfo->getDeviceInfo()->getClockRegions();
1050 
1051  if (PU2ClockRegionCenter.size() <= 0)
1052  return;
1053 
1054  for (auto PUXY : PU2ClockRegionCenter)
1055  {
1056  auto curPU = PUXY.first;
1057  float cX = PUXY.second.first;
1058  if (PU2ClockRegionColumn.find(curPU) != PU2ClockRegionColumn.end())
1059  {
1060  int clockRegionX = PU2ClockRegionColumn[curPU];
1061 
1062  if (clockRegionX == 2)
1063  {
1064  if (std::fabs(curPU->X() - cX) > 6)
1067  xSolver->solverData.objectiveVector, curPU, cX,
1068  pesudoNetWeight * std::pow(curPU->getNetsSetPtr()->size(), 1.1), y2xRatio, true, false);
1069  else if (std::fabs(curPU->X() - cX) > 3 && !DSPCritical)
1072  xSolver->solverData.objectiveVector, curPU, cX,
1073  pesudoNetWeight * curPU->getNetsSetPtr()->size(), y2xRatio, true, false);
1074  else if (!DSPCritical)
1077  xSolver->solverData.objectiveVector, curPU, cX,
1078  std::fabs(curPU->X() - cX) / 3 * pesudoNetWeight * curPU->getNetsSetPtr()->size(), y2xRatio,
1079  true, false);
1080  }
1081  else if (clockRegionX < 2)
1082  {
1083 
1084  float rLeft = clockRegions[0][1]->getLeft();
1085  float rRight = clockRegions[0][1]->getRight();
1086  cX = (rLeft + rRight) / 2;
1087  if ((curPU->X() - cX) > 6)
1090  xSolver->solverData.objectiveVector, curPU, cX,
1091  pesudoNetWeight * std::pow(curPU->getNetsSetPtr()->size(), 1.1), y2xRatio, true, false);
1092  else if ((curPU->X() - cX) > 3 && !DSPCritical)
1095  xSolver->solverData.objectiveVector, curPU, cX,
1096  pesudoNetWeight * curPU->getNetsSetPtr()->size(), y2xRatio, true, false);
1097  else if ((curPU->X() - cX) > 0 && !DSPCritical)
1100  xSolver->solverData.objectiveVector, curPU, cX,
1101  (curPU->X() - cX) / 3 * pesudoNetWeight * curPU->getNetsSetPtr()->size(), y2xRatio, true,
1102  false);
1103  }
1104  else if (clockRegionX > 2)
1105  {
1106  float rLeft = clockRegions[0][3]->getLeft();
1107  float rRight = clockRegions[0][3]->getRight();
1108  cX = (rLeft + rRight) / 2;
1109  if ((curPU->X() - cX) < -6)
1112  xSolver->solverData.objectiveVector, curPU, cX,
1113  pesudoNetWeight * std::pow(curPU->getNetsSetPtr()->size(), 1.1), y2xRatio, true, false);
1114  else if ((curPU->X() - cX) < -3 && !DSPCritical)
1117  xSolver->solverData.objectiveVector, curPU, cX,
1118  pesudoNetWeight * curPU->getNetsSetPtr()->size(), y2xRatio, true, false);
1119  else if ((curPU->X() - cX) < 0 && !DSPCritical)
1122  xSolver->solverData.objectiveVector, curPU, cX,
1123  (cX - curPU->X()) / 3 * pesudoNetWeight * curPU->getNetsSetPtr()->size(), y2xRatio, true,
1124  false);
1125  }
1126  }
1127 
1128  // placementInfo->addPseudoNetsInPlacementInfo(
1129  // ySolver->solverData.objectiveMatrixTripletList, ySolver->solverData.objectiveMatrixDiag,
1130  // ySolver->solverData.objectiveVector, curPU, cY, pesudoNetWeight * curPU->getNetsSetPtr()->size(),
1131  // y2xRatio, false, true);
1132  }
1133 
1134  print_warning("update pseudo net of clockt region for " + std::to_string(PU2ClockRegionCenter.size()) + " PUs");
1135 }
PlacementInfo::getProgress
float getProgress()
Get the Progress ratio of the placement.
Definition: PlacementInfo.h:3969
PlacementTimingOptimizer::getDelayByModel
float getDelayByModel(PlacementTimingInfo::TimingGraph< DesignInfo::DesignCell >::TimingNode *node1, PlacementTimingInfo::TimingGraph< DesignInfo::DesignCell >::TimingNode *node2, float X1, float Y1, float X2, float Y2)
Definition: PlacementTimingOptimizer.h:103
PlacementInfo::getNetDistributionByDensity
int getNetDistributionByDensity(int density)
Definition: PlacementInfo.h:4404
PlacementInfo::getPlacementUnits
std::vector< PlacementUnit * > & getPlacementUnits()
Definition: PlacementInfo.h:2810
QPSolverWrapper::solverSettingsType::solutionForward
bool solutionForward
Definition: QPSolverWrapper.h:64
WirelengthOptimizer::updatePseudoNetForClockRegion
void updatePseudoNetForClockRegion(float pesudoNetWeight)
add pseudo nets for clock region
Definition: WirelengthOptimizer.cc:1043
WirelengthOptimizer.h
This header file contains the definitions of GlobalPlacer class and its internal modules and APIs whi...
WirelengthOptimizer::ySolver
QPSolverWrapper * ySolver
Definition: WirelengthOptimizer.h:332
QPSolverWrapper::solverData
solverDataType solverData
Definition: QPSolverWrapper.h:52
QPSolverWrapper::solverDataType::objectiveMatrixDiag
std::vector< float > objectiveMatrixDiag
Definition: QPSolverWrapper.h:46
DesignInfo::DesignCell
a DesignCell in design netlist, DesignPin objects of which might connect to DesignNet objects
Definition: DesignInfo.h:782
WirelengthOptimizer::netPinEnhanceRate
std::map< DesignInfo::DesignNet *, std::vector< float > > netPinEnhanceRate
Definition: WirelengthOptimizer.h:401
WirelengthOptimizer::placementInfo
PlacementInfo * placementInfo
Definition: WirelengthOptimizer.h:329
WirelengthOptimizer::verbose
bool verbose
Definition: WirelengthOptimizer.h:334
WirelengthOptimizer::addPseudoNet2LoctionForAllPUs
void addPseudoNet2LoctionForAllPUs(float pesudoNetWeight, bool considerNetNum)
as convential QP placers do, we add pseudo nets between anchors and PlacementUnit to constrain the mo...
Definition: WirelengthOptimizer.cc:821
PlacementTimingOptimizer::getNetActualSlackPinNum
std::map< PlacementInfo::PlacementNet *, int > & getNetActualSlackPinNum()
Definition: PlacementTimingOptimizer.h:180
DesignInfo::getCell
DesignCell * getCell(std::string &tmpName)
Definition: DesignInfo.h:1634
WirelengthOptimizer::oriMacroLegalizationWeight
float oriMacroLegalizationWeight
the net weight for macro legalization
Definition: WirelengthOptimizer.h:393
PlacementInfo::getGlobalMinY
float getGlobalMinY()
Get the Global Min Y (bottom boundary of the device)
Definition: PlacementInfo.h:2882
PlacementInfo::getLongPathThresholdLevel
int getLongPathThresholdLevel()
Definition: PlacementInfo.h:4358
WirelengthOptimizer::PNetId2SlackEnhanceTuples
std::vector< std::vector< slackEnhanceTuple > * > PNetId2SlackEnhanceTuples
Definition: WirelengthOptimizer.h:267
WirelengthOptimizer::LUTLUTPairing_TimingDriven
void LUTLUTPairing_TimingDriven(float timingWeight, float disThreshold, PlacementTimingOptimizer *timingOptimizer)
Definition: WirelengthOptimizer.cc:666
PlacementInfo::getCellId2location
std::vector< Location > & getCellId2location()
Definition: PlacementInfo.h:3600
PlacementTimingInfo::TimingGraph::getClockPeriod
float getClockPeriod()
Get the clock period.
Definition: PlacementTimingInfo.h:777
WirelengthOptimizer::pin2pinEnhance
float pin2pinEnhance
Definition: WirelengthOptimizer.h:378
PlacementInfo::getPULegalXY
std::pair< std::map< PlacementInfo::PlacementUnit *, float >, std::map< PlacementInfo::PlacementUnit *, float > > & getPULegalXY()
get the locations (pair of X,Y) of the legalized PlacementUnit objects
Definition: PlacementInfo.h:3693
WirelengthOptimizer::useUnconstrainedCG
bool useUnconstrainedCG
indicate whether wirelength optimizer uses Eigen3, which cannot solve QP problem with constraints....
Definition: WirelengthOptimizer.h:357
PlacementInfo::addPseudoNetsInPlacementInfo
void addPseudoNetsInPlacementInfo(std::vector< Eigen::Triplet< float >> &objectiveMatrixTripletList, std::vector< float > &objectiveMatrixDiag, Eigen::VectorXd &objectiveVector, PlacementUnit *tmpPU, float targetLoc, float pseudoWeight, float y2xRatio, bool updateX, bool updateY)
directly set weight in the quadratic Matrix and vector according to given request.
Definition: PlacementInfo.h:3228
WirelengthOptimizer::targetCellId
int targetCellId
Definition: WirelengthOptimizer.h:407
PlacementTimingOptimizer
Definition: PlacementTimingOptimizer.h:46
PlacementInfo::PlacementUnit::X
float X()
Definition: PlacementInfo.h:1024
WirelengthOptimizer::updatePseudoNetForUserDefinedClusters
void updatePseudoNetForUserDefinedClusters(float pesudoNetWeight)
add pseudo net for user-defined clusters
Definition: WirelengthOptimizer.cc:955
PlacementInfo::getGlobalMaxX
float getGlobalMaxX()
Get the Global Max X (right boundary of the device)
Definition: PlacementInfo.h:2852
PlacementInfo::getDeviceInfo
DeviceInfo * getDeviceInfo()
Definition: PlacementInfo.h:3308
WirelengthOptimizer::WirelengthOptimizer
WirelengthOptimizer(PlacementInfo *placementInfo, std::map< std::string, std::string > &JSONCfg, bool verbose=true)
Construct a new Wirelength Optimizer object.
Definition: WirelengthOptimizer.cc:31
WirelengthOptimizer::generalNetWeight
float generalNetWeight
a common factor indicate the overall strength of the nets in the QP model from external setting
Definition: WirelengthOptimizer.h:341
WirelengthOptimizer::userDefinedClusterFadeOutFactor
float userDefinedClusterFadeOutFactor
the fade-out factor for the user-defined clusters
Definition: WirelengthOptimizer.h:387
WirelengthOptimizer::addPseudoNet_SlackBased
void addPseudoNet_SlackBased(float timingWeight, double slackPowFactor, PlacementTimingOptimizer *timingOptimizer, bool calculate=false)
add pseudo net for timing optimization based on the timing slack of each elements in the design netli...
Definition: WirelengthOptimizer.cc:434
WirelengthOptimizer::solverLoadData
void solverLoadData()
load to placement location from PlacementInfo to the solver
Definition: WirelengthOptimizer.cc:142
WirelengthOptimizer::updateB2BNetWeight
void updateB2BNetWeight(float pesudoNetWeight, bool enableMacroPseudoNet2Site=false, bool considerNetNum=true, bool enableUserDefinedClusterOpt=false, PlacementTimingOptimizer *timingOptimizer=nullptr)
update the net weights in the quadratic model according to B2B net HPWL model.
Definition: WirelengthOptimizer.cc:268
WirelengthOptimizer::reloadPlacementInfo
void reloadPlacementInfo()
re-initialize some parameters and optimizer configuration according to the PlacementInfo
Definition: WirelengthOptimizer.cc:69
PlacementInfo::getPlacementNetByDesignNetId
PlacementNet * getPlacementNetByDesignNetId(int netId)
Definition: PlacementInfo.h:3134
delayVisualization.disY
disY
Definition: delayVisualization.py:52
DesignInfo::getPredefinedClusters
std::vector< std::vector< DesignCell * > > & getPredefinedClusters()
Get the predefined clusters which are defined in design configuration files.
Definition: DesignInfo.h:1659
WirelengthOptimizer::macroPseudoNetCnt
int macroPseudoNetCnt
the number of the conducted macro iterations
Definition: WirelengthOptimizer.h:399
print_status
void print_status(std::string tmp_string)
Definition: strPrint.cc:44
QPSolverWrapper
Definition: QPSolverWrapper.h:41
PlacementInfo::getGlobalMinX
float getGlobalMinX()
Get the Global Min X (left boundary of the device)
Definition: PlacementInfo.h:2872
DesignInfo::DesignElement::getName
const std::string & getName() const
Definition: DesignInfo.h:243
WirelengthOptimizer::y2xRatio
float y2xRatio
a factor to tune the weights of the net spanning in Y-coordinate relative to the net spanning in X-co...
Definition: WirelengthOptimizer.h:350
print_warning
void print_warning(std::string tmp_string)
Definition: strPrint.cc:57
PlacementInfo::getPlacementUnitByCellId
PlacementUnit * getPlacementUnitByCellId(int cellId)
Definition: PlacementInfo.h:3127
QPSolverWrapper::solverDataType::oriSolution
Eigen::VectorXd oriSolution
Definition: QPSolverWrapper.h:49
PlacementInfo::PlacementUnit
a movement unit in placement with information of location and resource demand
Definition: PlacementInfo.h:1010
DesignInfo::DesignCell::getCellId
int getCellId()
Get the Cell Id in the cell list.
Definition: DesignInfo.h:1037
PlacementInfo::PlacementUnit::getId
unsigned int getId()
Definition: PlacementInfo.h:1206
QPSolverWrapper::solverSettings
solverSettingsType solverSettings
Definition: QPSolverWrapper.h:67
PlacementInfo::legalizeXYInArea
void legalizeXYInArea(PlacementUnit *curPU, float &fX, float &fY)
move the PlacementUnit to ensure the cells in it are within the device area.
Definition: PlacementInfo.h:3364
WirelengthOptimizer::generalTimingNetWeight
float generalTimingNetWeight
Definition: WirelengthOptimizer.h:342
WirelengthOptimizer::updateB2BNetWeightWorker
static void updateB2BNetWeightWorker(PlacementInfo *placementInfo, std::vector< Eigen::Triplet< float >> &objectiveMatrixTripletList, std::vector< float > &objectiveMatrixDiag, Eigen::VectorXd &objectiveVector, float generalNetWeight, float y2xRatio, bool updateX, bool updateY)
a worker funtion for multi-threading net weight updating
Definition: WirelengthOptimizer.cc:334
PlacementInfo::getTimingInfo
PlacementTimingInfo * getTimingInfo()
Definition: PlacementInfo.h:3313
PlacementTimingOptimizer::getEffectFactor
float getEffectFactor()
Definition: PlacementTimingOptimizer.h:93
WirelengthOptimizer::JSONCfg
std::map< std::string, std::string > & JSONCfg
Definition: WirelengthOptimizer.h:333
DesignInfo::getCells
std::vector< DesignCell * > & getCells()
Definition: DesignInfo.h:1609
PlacementInfo::getPU2ClockRegionColumn
std::map< PlacementUnit *, int > & getPU2ClockRegionColumn()
get the PlacementUnit Mapping to clock region column for timing optimzation
Definition: PlacementInfo.h:4353
WirelengthOptimizer::slackPowerFactor
double slackPowerFactor
Definition: WirelengthOptimizer.h:343
PlacementTimingInfo::getSimplePlacementTimingInfo
std::vector< TimingGraph< DesignInfo::DesignCell >::TimingNode * > & getSimplePlacementTimingInfo()
Get the Simple Timing Info object which regard design cells as timing nodes.
Definition: PlacementTimingInfo.h:835
QPSolverWrapper::solverDataType::objectiveVector
Eigen::VectorXd objectiveVector
Definition: QPSolverWrapper.h:47
PlacementInfo::getPlacementNets
std::vector< PlacementNet * > & getPlacementNets()
Definition: PlacementInfo.h:2822
PlacementTimingOptimizer::getSlackThr
float getSlackThr()
Definition: PlacementTimingOptimizer.cc:370
WirelengthOptimizer::DSPCritical
bool DSPCritical
Definition: WirelengthOptimizer.h:376
WirelengthOptimizer::GlobalPlacementQPSolve
void GlobalPlacementQPSolve(float pesudoNetWeight, bool firstIteration=true, bool forwardSolutionToNextIteration=false, bool enableMacroPseudoNet2Site=false, bool considerNetNum=true, bool enableUserDefinedClusterOpt=false, float displacementLimit=-10, PlacementTimingOptimizer *timingOptimizer=nullptr)
use quadratic model to estimate the HPWL and some timing/user-defined pseudo nets are involved for sp...
Definition: WirelengthOptimizer.cc:100
WirelengthOptimizer::slackThr
float slackThr
Definition: WirelengthOptimizer.h:403
print_info
void print_info(std::string tmp_string)
Definition: strPrint.cc:39
WirelengthOptimizer::getCellDistance
float getCellDistance(PlacementInfo::Location &A, PlacementInfo::Location &B)
Definition: WirelengthOptimizer.h:305
checkHalfColumn.i
int i
Definition: checkHalfColumn.py:5
PlacementInfo::getDesignInfo
DesignInfo * getDesignInfo()
Definition: PlacementInfo.h:3303
QPSolverWrapper::QPSolve
static void QPSolve(QPSolverWrapper *&curSolver)
Definition: QPSolverWrapper.cc:29
PlacementInfo::getPlacementUnitByCell
PlacementUnit * getPlacementUnitByCell(DesignInfo::DesignCell *curCell)
Definition: PlacementInfo.h:3120
WirelengthOptimizer::solverWriteBackData
void solverWriteBackData(float displacementLimit)
write placement location from the solver to the PlacementInfo
Definition: WirelengthOptimizer.cc:181
WirelengthOptimizer::solverLoadFixedData
void solverLoadFixedData()
load to placement location of fixed PlacementUnits from PlacementInfo to the solver
Definition: WirelengthOptimizer.cc:152
WirelengthOptimizer::addPseudoNetForMacros
void addPseudoNetForMacros(float pesudoNetWeight, bool considerNetNum)
add the legalization pseudo nets to force macros move to the legal sites
Definition: WirelengthOptimizer.cc:356
PlacementInfo::getPU2ClockRegionCenters
std::map< PlacementUnit *, std::pair< float, float > > & getPU2ClockRegionCenters()
get the PlacementUnit Mapping to clock region centers for timing optimzation
Definition: PlacementInfo.h:4343
QPSolverWrapper::solverDataType::solution
Eigen::VectorXd solution
Definition: QPSolverWrapper.h:48
WirelengthOptimizer::MKLorNot
bool MKLorNot
indicate whether wirelength optimizer is based on MKL library when using OSQP placer,...
Definition: WirelengthOptimizer.h:364
WirelengthOptimizer::targetCellName
std::string targetCellName
Definition: WirelengthOptimizer.h:406
WirelengthOptimizer::directMacroLegalize
bool directMacroLegalize
indicate whether we use direct macro legalization instread of the progressive legalization (2-phase l...
Definition: WirelengthOptimizer.h:374
WirelengthOptimizer::xSolver
QPSolverWrapper * xSolver
Definition: WirelengthOptimizer.h:331
delayVisualization.disX
disX
Definition: delayVisualization.py:51
DeviceInfo::getClockRegions
std::vector< std::vector< ClockRegion * > > & getClockRegions()
Get the Clock Regions in an 2D array clockregion[Y][X].
Definition: DeviceInfo.h:1261
QPSolverWrapper::solverDataType::objectiveMatrixTripletList
std::vector< Eigen::Triplet< float > > objectiveMatrixTripletList
Definition: QPSolverWrapper.h:45
PlacementInfo::getGlobalMaxY
float getGlobalMaxY()
Get the Global Max Y (top boundary of the device)
Definition: PlacementInfo.h:2862
PlacementInfo
Information related to FPGA placement (wirelength optimization, cell spreading, legalization,...
Definition: PlacementInfo.h:59
PlacementTimingInfo::getSimplePlacementTimingGraph
TimingGraph< DesignInfo::DesignCell > * getSimplePlacementTimingGraph()
Get the Simple Placement Timing Graph object.
Definition: PlacementTimingInfo.h:850