AMF-Placer  2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
CLBLegalizer.cc
Go to the documentation of this file.
1 
26 #include "CLBLegalizer.h"
27 #include <algorithm>
28 #include <cmath>
29 #include <cstdlib>
30 #include <ctime>
31 #include <iostream>
32 
33 CLBLegalizer::CLBLegalizer(std::string legalizerName, PlacementInfo *placementInfo, DeviceInfo *deviceInfo,
34  std::vector<std::string> &siteTypesToLegalize, std::map<std::string, std::string> &JSONCfg)
35  : legalizerName(legalizerName), placementInfo(placementInfo), deviceInfo(deviceInfo),
36  compatiblePlacementTable(placementInfo->getCompatiblePlacementTable()), siteTypesToLegalize(siteTypesToLegalize),
37  cellLoc(placementInfo->getCellId2location()), JSONCfg(JSONCfg)
38 {
39  PUsToLegalize.clear();
40  PU2Site2HPWLIncrease.clear();
41  PU2X.clear();
42  PU2Y.clear();
43  PU2LegalSites.clear();
44 
45  for (auto curSiteType : siteTypesToLegalize)
46  {
47  if (curSiteType == "SLICEM")
48  {
50  }
51  if (curSiteType == "SLICEL")
52  {
54  }
55  }
56 
57  // since LCLB might be allowed to mapped to MCLB but MCLB cannot be mapped to LCLB, we cannot handle them at the
58  // same time
60  assert(siteTypesToLegalize.size() == 1);
61 
62  if (JSONCfg.find("y2xRatio") != JSONCfg.end())
63  {
64  y2xRatio = std::stof(JSONCfg["y2xRatio"]);
65  }
66 
67  if (JSONCfg.find("CLBLegalizationVerbose") != JSONCfg.end())
68  {
69  verbose = JSONCfg["CLBLegalizationVerbose"] == "true";
70  }
71 
72  if (JSONCfg.find("jobs") != JSONCfg.end())
73  {
74  nJobs = std::stoi(JSONCfg["jobs"]);
75  }
76 }
77 
78 void CLBLegalizer::legalize(bool exactLegalization)
79 {
80  if (verbose)
81  print_status("CLBLegalizer Started Legalization.");
82  PU2Site2HPWLIncrease.clear();
83  resetSettings();
86  if (initialPUsToLegalize.size() == 0)
87  {
88  print_warning("CLBLegalizer find no target elements.");
89  noTarget = true;
90  return;
91  }
93 
94  updatePUMatchingLocation(true, !exactLegalization);
95 
96  dumpMatching();
97 
98  if (exactLegalization)
99  {
100  if (verbose)
101  print_status("CLBLegalizer Started Fixed-Column Legalization.");
102  resetSettings();
104  updatePUMatchingLocation(false, true);
106  dumpMatching(exactLegalization);
107  }
108 
109  setSitesMapped();
110  if (verbose)
111  print_status("CLBLegalizer Finished Legalization.");
112 }
113 
115 {
116  while (PUsToLegalize.size())
117  {
121 
125 
128 
130  if ((int)(maxNumCandidate * 2) > maxNumCandidate + 1)
131  maxNumCandidate *= 2;
132  else
133  maxNumCandidate++;
135  minCostBipartiteMatcher = nullptr;
136  }
137 }
138 
140 {
141  mapPUsToColumns();
143 
145 
146  while (PUsToLegalize.size())
147  {
154 
157 
159  if ((int)(maxNumCandidate * 2) > maxNumCandidate + 1)
160  maxNumCandidate *= 2;
161  else
162  maxNumCandidate++;
164  minCostBipartiteMatcher = nullptr;
165  }
166 }
167 
169 {
170  PU2X.clear();
171  PU2Y.clear();
172  resetSettings();
173  PU2LegalSites.clear();
174 
175  float tmpAverageDisplacement = 0.0;
176  tmpAverageDisplacement += DPForMinHPWL(MCLBColumnNum, MCLBColumn2Sites, MCLBColumn2PUs);
177  tmpAverageDisplacement += DPForMinHPWL(LCLBColumnNum, LCLBColumn2Sites, LCLBColumn2PUs);
178  finalAverageDisplacement = tmpAverageDisplacement / PU2X.size();
179 
180  if (verbose)
181  print_info("CLBLegalizer Macro Cell Average Final Legalization Displacement = " +
182  std::to_string(finalAverageDisplacement));
185 }
186 
187 float CLBLegalizer::DPForMinHPWL(int colNum, std::vector<std::vector<DeviceInfo::DeviceSite *>> &Column2Sites,
188  std::vector<std::deque<PlacementInfo::PlacementUnit *>> &Column2PUs)
189 {
190  // final Legalization DP
191  // i th macro (start from 0), j th row (start from 0)
192  // f[i][j] = min(f[i-1][j-row[i]]+HPWLChange[i][j-row[i]+1],f[i][j-1])
193 
194  // std::string dumpFile =
195  // JSONCfg["DumpCLBLegalization"] + "-Exact-" + std::to_string(DumpCLBLegalizationCnt) + ".gz";
196 
197  // print_status("CLBLegalizer: dumping CLBLegalization archieve to: " + dumpFile);
198  // DumpCLBLegalizationCnt++;
199  // std::stringstream outfile0;
200 
201  float tmpTotalDisplacement = 0.0;
202  std::map<PlacementInfo::PlacementUnit *, std::vector<DeviceInfo::DeviceSite *>> PU2Sites;
203  PU2Sites.clear();
204  for (auto &PUDeque : Column2PUs)
205  {
206  for (auto tmpPU : PUDeque)
207  {
208  assert(PU2Sites.find(tmpPU) == PU2Sites.end());
209  PU2Sites[tmpPU] = std::vector<DeviceInfo::DeviceSite *>();
210  }
211  }
212 
213 #pragma omp parallel for
214  for (int c = 0; c < colNum; c++)
215  {
216  int numPUs = Column2PUs[c].size();
217  if (!numPUs)
218  continue;
219 
220  auto &curColSites = Column2Sites[c];
221  auto &curColPU = Column2PUs[c];
222 
223  sortSitesBySiteY(curColSites);
224 
225  // initialize
226 
227  std::vector<std::vector<float>> f(numPUs, std::vector<float>(curColSites.size(), 1000000000.0));
228  std::vector<std::vector<bool>> fChoice(
229  numPUs, std::vector<bool>(curColSites.size(), 0)); // used for tracing back macro-site mapping
230 
231  int minLastPUTop = -1;
232 
233  int totalMacroCellNum = 0;
234  int heightPURow = getPUSiteNum(curColPU[0]);
235  totalMacroCellNum += heightPURow;
236  float minHPWLChange = 1100000000.0;
237  for (unsigned int j = heightPURow - 1; j < curColSites.size(); j++)
238  {
239  float curHPWLChange = getHPWLChange(curColPU[0], curColSites[j - heightPURow + 1]);
240  if (curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1)
241  {
242  // we need to ensure that there is no occpupied sites in this range
243  curHPWLChange = 1100000000.0;
244  }
245  if (curHPWLChange < minHPWLChange)
246  {
247  minHPWLChange = curHPWLChange;
248  fChoice[0][j] = 1;
249  if (numPUs == 1)
250  {
251  minLastPUTop = j;
252  }
253  }
254  f[0][j] = minHPWLChange;
255  }
256 
257  // DP to minimize HPWL
258  for (int i = 1; i < numPUs; i++)
259  {
260  float minVal = 100000000.0;
261  int heightPURow = getPUSiteNum(curColPU[i]);
262  totalMacroCellNum += heightPURow;
263  for (unsigned int j = totalMacroCellNum - 1; j < curColSites.size();
264  j++) // j start from heightPURow because PU0 must occupy 1+ site(s)
265  {
266  float curHPWLChange = getHPWLChange(curColPU[i], curColSites[j - heightPURow + 1]);
267  if (curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1)
268  {
269  // we need to ensure that there is no occpupied sites in this range
270  curHPWLChange = 1100000000.0;
271  }
272  if (f[i][j - 1] > f[i - 1][j - heightPURow] + curHPWLChange)
273  {
274  fChoice[i][j] = 1;
275  if (i == numPUs - 1)
276  {
277  if (f[i - 1][j - heightPURow] + curHPWLChange < minVal)
278  {
279  minVal = f[i - 1][j - heightPURow] + curHPWLChange;
280  minLastPUTop = j;
281  }
282  }
283  }
284 
285  f[i][j] = std::min(f[i][j - 1], f[i - 1][j - heightPURow] + curHPWLChange);
286  }
287  }
288 
289  assert(minLastPUTop >= 0);
290 
291  std::vector<DeviceInfo::DeviceSite *> PUBottom2Site_reverse(0);
292 
293  for (int i = numPUs - 1; i >= 0; i--)
294  {
295  assert(minLastPUTop >= 0);
296  int heightPURow = getPUSiteNum(curColPU[i]);
297  while (!fChoice[i][minLastPUTop])
298  {
299  minLastPUTop--;
300  assert(minLastPUTop >= 0);
301  }
302  auto curSite = curColSites[minLastPUTop - heightPURow + 1];
303  assert(PU2Sites[curColPU[i]].size() == 0);
304  assert(curSite);
305  PU2Sites[curColPU[i]].push_back(curSite); // CLB PU will only occupy one site
306  minLastPUTop -= heightPURow;
307  // outfile0 << "col#" << c << ": " << curColPU[i]->getName() << " PUY:" << PU2Y[curColPU[i]]
308  // << " numPUs:" << getPUSiteNum(curColPU[i])
309  // << " netNum:" << curColPU[i]->getNetsSetPtr()->size() << "\n";
310  // outfile0 << " macthed with: " << curSite->getName() << " locX:" << curSite->X()
311  // << " locY:" << curSite->Y() << " HPWLIncrease:" << getHPWLChange(curColPU[i], curSite) << "\n";
312  }
313  }
314 
315  for (auto &PUDeque : Column2PUs)
316  {
317  for (auto tmpPU : PUDeque)
318  {
319  assert(PU2Sites.find(tmpPU) != PU2Sites.end());
320  auto curSite = PU2Sites[tmpPU][0];
321  assert(curSite);
322  assert(PU2X.find(tmpPU) == PU2X.end());
323  PU2X[tmpPU] = curSite->X();
324  PU2Y[tmpPU] = curSite->Y();
325  PU2LegalSites[tmpPU] = PU2Sites[tmpPU];
326  PULevelMatching.emplace_back(tmpPU, curSite);
327  tmpTotalDisplacement += std::fabs(tmpPU->X() - curSite->X()) + std::fabs(tmpPU->Y() - curSite->Y());
328  }
329  }
330 
331  // writeStrToGZip(dumpFile, outfile0);
332  // print_status("CLBLegalizer: dumped CLBLegalization archieve to: " + dumpFile);
333  return tmpTotalDisplacement;
334 }
335 
337 {
338  PUsToLegalize.clear();
339  PUsToLegalizeSet.clear();
340  MCLBPUs.clear();
341  LCLBPUs.clear();
342  for (auto curPU : placementInfo->getPlacementUnits())
343  {
344  if (!curPU->isLocked())
345  {
347  {
348  if (curPU->isMCLB())
349  {
350  MCLBPUs.insert(curPU);
351  PUsToLegalize.push_back(curPU);
352  PUsToLegalizeSet.insert(curPU);
353  }
354  }
355 
357  {
358  if (curPU->isLCLB())
359  {
360  LCLBPUs.insert(curPU);
361  PUsToLegalize.push_back(curPU);
362  PUsToLegalizeSet.insert(curPU);
363  }
364  }
365  }
366  }
368  for (auto curPU : PUsToLegalize)
369  {
370  PU2Site2HPWLIncrease[curPU] = std::map<DeviceInfo::DeviceSite *, float>();
371  }
372 }
373 
375 {
376  siteType2Sites.clear();
377  for (auto siteTypeToLegalize : siteTypesToLegalize)
378  {
379  siteType2Sites[siteTypeToLegalize] = std::vector<DeviceInfo::DeviceSite *>(0);
380  std::vector<DeviceInfo::DeviceSite *> &sitesInType = deviceInfo->getSitesInType(siteTypeToLegalize);
381  for (auto curSite : sitesInType)
382  {
383  if (!curSite->isOccupied() && !curSite->isMapped())
384  {
385  // if (matchedSites.find(curSite) == matchedSites.end())
386  // {
387  assert(!curSite->isMapped());
388  siteType2Sites[siteTypeToLegalize].push_back(curSite);
389  // }
390  }
391  }
392  if (siteTypeToLegalize == "SLICEL")
393  {
394  // since LCLB might be allowed to mapped to MCLB but MCLB cannot be mapped to LCLB, we cannot handle them
395  // at the same time. We MUST legalize SLICEM and make them occupied before we legalize SLICEL
396  std::string tmpSiteType = "SLICEM";
397  std::vector<DeviceInfo::DeviceSite *> &sitesInType = deviceInfo->getSitesInType(tmpSiteType);
398  for (auto curSite : sitesInType)
399  {
400  if (!curSite->isOccupied() && !curSite->isMapped())
401  {
402  // if (matchedSites.find(curSite) == matchedSites.end())
403  // {
404  siteType2Sites[siteTypeToLegalize].push_back(curSite);
405  // }
406  }
407  }
408  }
409  }
410 
411  for (auto curSiteType : siteTypesToLegalize)
412  {
413  if (curSiteType == "SLICEM")
414  {
415  for (auto curSite : siteType2Sites[curSiteType])
416  {
417  if (curSite->getSiteY() + 1 > MCLBRowNum)
418  MCLBRowNum = curSite->getSiteY() + 1;
419  if (curSite->getSiteX() + 1 > MCLBColumnNum)
420  MCLBColumnNum = curSite->getSiteX() + 1;
421  }
422  }
423  if (curSiteType == "SLICEL")
424  {
425  for (auto curSite : siteType2Sites[curSiteType])
426  {
427  if (curSite->getSiteY() + 1 > LCLBRowNum)
428  LCLBRowNum = curSite->getSiteY() + 1;
429  if (curSite->getSiteX() + 1 > LCLBColumnNum)
430  LCLBColumnNum = curSite->getSiteX() + 1;
431  }
432  }
433  }
434 
435  MCLBColumnXs.clear();
437  {
438  MCLBColumnXs.resize(MCLBColumnNum, -1.0);
439  MCLBColumn2Sites.clear();
440  MCLBColumn2Sites.resize(MCLBColumnNum, std::vector<DeviceInfo::DeviceSite *>(0));
441 
442  for (auto curSite : siteType2Sites["SLICEM"])
443  {
444  if (curSite->getSiteY() + 1 > MCLBRowNum)
445  MCLBRowNum = curSite->getSiteY() + 1;
446  if (curSite->getSiteX() + 1 > MCLBColumnNum)
447  MCLBColumnNum = curSite->getSiteX() + 1;
448  MCLBColumnXs[curSite->getSiteX()] = curSite->X();
449  MCLBColumn2Sites[curSite->getSiteX()].push_back(curSite);
450  }
451  }
452 
453  LCLBColumnXs.clear();
455  {
456  LCLBColumnXs.resize(LCLBColumnNum, -1.0);
457  LCLBColumn2Sites.clear();
458  LCLBColumn2Sites.resize(LCLBColumnNum, std::vector<DeviceInfo::DeviceSite *>(0));
459 
460  for (auto curSite : siteType2Sites["SLICEL"])
461  {
462  if (curSite->getSiteY() + 1 > LCLBRowNum)
463  LCLBRowNum = curSite->getSiteY() + 1;
464  if (curSite->getSiteX() + 1 > LCLBColumnNum)
465  LCLBColumnNum = curSite->getSiteX() + 1;
466  LCLBColumnXs[curSite->getSiteX()] = curSite->X();
467  LCLBColumn2Sites[curSite->getSiteX()].push_back(curSite);
468  }
469  }
470 }
471 
473 {
474  PU2Sites.clear();
475 
476  for (auto curPU : PUsToLegalize)
477  {
478  PU2Sites[curPU] = std::vector<DeviceInfo::DeviceSite *>(0);
479  }
480 
481  int numPUs = PUsToLegalize.size();
482 
483 #pragma omp parallel for
484  for (int i = 0; i < numPUs; i++)
485  {
486  auto curPU = PUsToLegalize[i];
487  std::string curSiteType = "";
488  if (curPU->isLCLB())
489  curSiteType = "SLICEL";
490  else if (curPU->isMCLB())
491  curSiteType = "SLICEM";
492  else
493  assert(false && "should be LogicCLB or RAMCLB");
494 
495  assert(siteType2Sites.find(curSiteType) != siteType2Sites.end());
496  std::vector<DeviceInfo::DeviceSite *> *candidateSite = nullptr;
497  if (fixedColumn)
498  {
499  int targetSiteX = -1;
500  std::vector<std::vector<DeviceInfo::DeviceSite *>> *column2Sites;
501  if (curPU->isLCLB())
502  {
503  assert(LCLB2Column.find(curPU) != LCLB2Column.end());
504  targetSiteX = LCLB2Column[curPU];
505  column2Sites = &LCLBColumn2Sites;
506  }
507  if (curPU->isMCLB())
508  {
509  assert(MCLB2Column.find(curPU) != MCLB2Column.end());
510  targetSiteX = MCLB2Column[curPU];
511  column2Sites = &MCLBColumn2Sites;
512  }
513  assert(targetSiteX >= 0 && "undefine type");
514 
515  for (auto &tmpCol : *column2Sites)
516  {
517  if (tmpCol.size() == 0)
518  continue;
519  if (tmpCol[0]->getSiteX() == targetSiteX)
520  {
521  candidateSite = &tmpCol;
522  }
523  }
524  }
525  else
526  {
527  candidateSite = PU2SitesInDisplacementThreshold[curPU];
528  }
529 
530  assert(candidateSite);
531 
532  for (auto curSite : *candidateSite)
533  {
534  float curDisp = getDisplacement(curPU, curSite);
535  if ((!fixedColumn && curDisp < displacementThreshold) ||
536  (fixedColumn && curDisp < 2 * displacementThreshold))
537  {
538  if (placementInfo->isLegalLocation(curPU, curSite->X(), curSite->Y()))
539  {
540  if (matchedSites.find(curSite) !=
541  matchedSites.end()) // the matched sites should not in the candidate set
542  continue;
543  PU2Sites[curPU].push_back(curSite);
544  }
545  }
546  }
547  if (PU2Sites[curPU].size() > 1)
548  quick_sort_WLChange(curPU, PU2Sites[curPU], 0, PU2Sites[curPU].size() - 1);
549  if (PU2Sites[curPU].size() > (unsigned int)maxNumCandidate)
550  PU2Sites[curPU].resize(maxNumCandidate);
551  }
552  // print_info("#total macro cell = " + std::to_string(PU2Sites.size()));
553  // print_info("#total macro candidate site (might be duplicated) = " + std::to_string(totalSiteNum));
554 }
555 
557 {
558  rightSiteIds.clear();
559  adjList.resize(PUsToLegalize.size());
560  siteList.clear();
561 
562  float minCost = 10000000;
563 
564  for (unsigned int leftCellId = 0; leftCellId < PUsToLegalize.size(); leftCellId++)
565  {
566  auto curPU = PUsToLegalize[leftCellId];
567  adjList[leftCellId].clear();
568  for (auto curSite : PU2Sites[curPU])
569  {
570  if (rightSiteIds.find(curSite) == rightSiteIds.end())
571  {
572  int curSiteCnt = rightSiteIds.size();
573  rightSiteIds[curSite] = curSiteCnt;
574  siteList.push_back(curSite);
575  }
576  float tmpCost = getHPWLChange(curPU, curSite);
577  adjList[leftCellId].emplace_back(rightSiteIds[curSite], tmpCost);
578  if (tmpCost < minCost)
579  {
580  minCost = tmpCost;
581  }
582  // adjList[leftCellId].emplace_back(rightSiteIds[curSite],
583  // getDisplacement(cellLoc[curCell->getCellId()], curSite));
584  }
585  }
586 
587  if (minCost < 0.0001)
588  {
589  float compensation = 10 - minCost;
590  for (unsigned int leftCellId = 0; leftCellId < PUsToLegalize.size(); leftCellId++)
591  {
592  for (unsigned int tmpId = 0; tmpId < adjList[leftCellId].size(); tmpId++)
593  {
594  adjList[leftCellId][tmpId].second += compensation;
595  }
596  }
597  }
598 }
599 
601 {
602  for (unsigned int leftCellId = 0; leftCellId < PUsToLegalize.size(); leftCellId++)
603  {
604  int rightNode = minCostBipartiteMatcher->getMatchedRightNode(leftCellId);
605  auto curPU = PUsToLegalize[leftCellId];
606  if (rightNode >= 0)
607  {
608  assert(matchedPUs.find(curPU) == matchedPUs.end());
609  assert(matchedSites.find(siteList[rightNode]) == matchedSites.end());
610  matchedPUs.insert(curPU);
611  matchedSites.insert(siteList[rightNode]);
612  PULevelMatching.emplace_back(curPU, siteList[rightNode]);
613  }
614  }
615  std::vector<PlacementInfo::PlacementUnit *> newPUsToLegalize;
616  newPUsToLegalize.clear();
617  for (unsigned int leftCellId = 0; leftCellId < PUsToLegalize.size(); leftCellId++)
618  {
619  auto curPU = PUsToLegalize[leftCellId];
620  if (matchedPUs.find(curPU) == matchedPUs.end())
621  {
622  newPUsToLegalize.push_back(curPU);
623  }
624  }
625  PUsToLegalize = newPUsToLegalize;
626 }
627 
628 void CLBLegalizer::dumpMatching(bool fixedColumn, bool enforce)
629 {
630  if (JSONCfg.find("DumpCLBLegalization") != JSONCfg.end() || enforce)
631  {
632  std::string dumpFile = "";
633  if (enforce)
634  dumpFile =
635  JSONCfg["dumpDirectory"] + "DumpCLBLegalization-" + std::to_string(DumpCLBLegalizationCnt) + ".gz";
636  else
637  dumpFile = JSONCfg["DumpCLBLegalization"] + "-" + std::to_string(DumpCLBLegalizationCnt) + ".gz";
638 
639  print_status("CLBLegalizer: dumping CLBLegalization archieve to: " + dumpFile);
641  if (dumpFile != "")
642  {
643  std::stringstream outfile0;
644  for (auto matchedPair : PULevelMatching)
645  {
646  auto matchedSite = matchedPair.second;
647  auto curPU = matchedPair.first;
648  outfile0 << "name: " << curPU->getName() << " locX:" << curPU->X() << " locY:" << curPU->Y() << "\n";
649  outfile0 << " macthed with: " << matchedSite->getName() << " locX:" << matchedSite->X()
650  << "\n locY:" << matchedSite->Y()
651  << "\n dis:" << getDisplacement(curPU, matchedSite)
652  << "\n HPWLIncrease:" << getHPWLChange(curPU, matchedSite) << "\n";
653  }
654 
655  if (fixedColumn)
656  {
657  for (int i = 0; i < MCLBColumnNum; i++)
658  {
659  int numPUs = MCLBColumn2PUs[i].size();
660  for (int j = 0; j < numPUs; j++)
661  {
662  auto PU = MCLBColumn2PUs[i][j];
663  outfile0 << "MCLB col#" << i << ": " << PU->getName() << " PUY:" << PU2Y[PU]
664  << " numPUs:" << getPUSiteNum(PU) << " netNum:" << PU->getNetsSetPtr()->size() << "\n";
665  }
666  }
667  for (int i = 0; i < LCLBColumnNum; i++)
668  {
669  int numPUs = LCLBColumn2PUs[i].size();
670  for (int j = 0; j < numPUs; j++)
671  {
672  auto PU = LCLBColumn2PUs[i][j];
673  outfile0 << "LCLB col#" << i << ": " << PU->getName() << " PUY:" << PU2Y[PU]
674  << " numPUs:" << getPUSiteNum(PU) << " netNum:" << PU->getNetsSetPtr()->size() << "\n";
675  }
676  }
677  }
678 
679  writeStrToGZip(dumpFile, outfile0);
680  print_status("CLBLegalizer: dumped CLBLegalization archieve to: " + dumpFile);
681  }
682  }
683 }
684 
686 {
687  return 1; // currently all CLB should occupy only one site
688 }
689 
690 void CLBLegalizer::sortPUsByPU2Y(std::deque<PlacementInfo::PlacementUnit *> &PUs)
691 {
692  int numPUs = PUs.size();
693  for (int i = 0; i < numPUs; i++)
694  for (int j = i + 1; j < numPUs; j++)
695  if (PU2Y[PUs[i]] > PU2Y[PUs[j]])
696  swapPU(&PUs[i], &PUs[j]);
697 }
698 
699 void CLBLegalizer::sortSitesBySiteY(std::vector<DeviceInfo::DeviceSite *> &sites)
700 {
701  int numSites = sites.size();
702  bool ordered = true;
703  for (int i = 1; i < numSites; i++)
704  {
705  if (sites[i - 1]->getSiteY() > sites[i]->getSiteY())
706  {
707  ordered = false;
708  break;
709  }
710  }
711  if (ordered)
712  return;
713  for (int i = 0; i < numSites; i++)
714  for (int j = i + 1; j < numSites; j++)
715  if (sites[i]->getSiteY() > sites[j]->getSiteY())
716  swapSitePtr(&sites[i], &sites[j]);
717 }
718 
719 void CLBLegalizer::updatePUMatchingLocation(bool isRoughLegalization, bool updateDisplacement)
720 {
721  PU2X.clear();
722  PU2Y.clear();
723  PU2Columns.clear();
724  PU2SiteX.clear();
725 
726  PU2LegalSites.clear();
727  MCLBColumn2PUs.clear();
728  if (MCLBColumnNum > 0)
729  {
730  MCLBColumn2PUs.resize(MCLBColumnNum, std::deque<PlacementInfo::PlacementUnit *>(0));
731  }
732  LCLBColumn2PUs.clear();
733  if (LCLBColumnNum > 0)
734  {
735  LCLBColumn2PUs.resize(LCLBColumnNum, std::deque<PlacementInfo::PlacementUnit *>(0));
736  }
737 
738  float tmpAverageDisplacement = 0.0;
739 
740  for (auto matchedPair : PULevelMatching)
741  {
742  auto matchedSite = matchedPair.second;
743  auto curPU = matchedPair.first;
744 
745  if (PU2Y.find(curPU) == PU2Y.end())
746  {
747  PU2SiteX[curPU] = -1;
748  PU2Y[curPU] = 0.0;
749  if (curPU->isMCLB())
750  {
751  MCLBColumn2PUs[matchedSite->getSiteX()].push_back(curPU);
752  }
753  if (curPU->isLCLB())
754  {
755  LCLBColumn2PUs[matchedSite->getSiteX()].push_back(curPU);
756  }
757  }
758 
759  float actualPUX = 0;
760  float actualPUY = 0;
761  // since the matched site is for a single DSP/BRAM cell, we need to find its corresponding placement macro
762  // (with multiple DSPs/BRAMs)
763  actualPUX = matchedSite->X();
764  actualPUY = matchedSite->Y();
765 
766  tmpAverageDisplacement += std::fabs(curPU->X() - matchedSite->X()) + std::fabs(curPU->Y() - matchedSite->Y());
767  assert(isRoughLegalization || PU2SiteX[curPU] == -1 || PU2SiteX[curPU] == matchedSite->getSiteX());
768  PU2SiteX[curPU] = matchedSite->getSiteX();
769  PU2X[curPU] += actualPUX;
770  PU2Y[curPU] += actualPUY;
771  if (PU2Columns.find(curPU) == PU2Columns.end())
772  {
773  PU2Columns[curPU] = std::vector<int>(0);
774  }
775  PU2Columns[curPU].push_back(matchedSite->getSiteX());
776  }
777 
778  tmpAverageDisplacement /= PULevelMatching.size();
779 
780  if (verbose)
781  print_info("CLBLegalizer Macro Cell Average Displacement = " + std::to_string(tmpAverageDisplacement));
782 
783  if (updateDisplacement)
784  {
785  if (isRoughLegalization)
786  roughAverageDisplacement = tmpAverageDisplacement;
787  else
788  fixedColumnAverageDisplacement = tmpAverageDisplacement;
789  }
790 
791  for (auto pairPU2X : PU2X)
792  {
793  int numCells = getPUSiteNum(pairPU2X.first);
794  assert(numCells == 1); // currentlt CLB should only cover one site.
795  PU2X[pairPU2X.first] /= numCells;
796  PU2Y[pairPU2X.first] /= numCells;
797  }
798 
799 #pragma omp parallel for
800  for (int i = 0; i < MCLBColumnNum; i++)
802 
803 #pragma omp parallel for
804  for (int i = 0; i < LCLBColumnNum; i++)
806 
808 }
809 
810 void CLBLegalizer::spreadPUs(int columnNum, std::vector<int> &columnUntilization,
811  std::vector<std::vector<DeviceInfo::DeviceSite *>> &column2Sites,
812  std::vector<std::deque<PlacementInfo::PlacementUnit *>> &column2PUs,
813  std::map<PlacementInfo::PlacementUnit *, int> &cell2Column)
814 {
815  while (true)
816  {
817  int overflowColId = -1;
818  std::vector<int> accumulationUtil(columnNum, 0), accumulationCapacity(columnNum, 0);
819  accumulationUtil[0] = columnUntilization[0];
820  accumulationCapacity[0] = column2Sites[0].size();
821  for (int colId = 1; colId < columnNum; colId++)
822  {
823  accumulationUtil[colId] = accumulationUtil[colId - 1] + columnUntilization[colId];
824  accumulationCapacity[colId] = accumulationCapacity[colId - 1] + column2Sites[colId].size();
825  }
826 
827  for (int colId = 0; colId < columnNum; colId++)
828  {
829  if (column2Sites[colId].size() < (unsigned int)columnUntilization[colId])
830  {
831  overflowColId = colId;
832  break;
833  }
834  }
835  if (overflowColId < 0)
836  {
837  break;
838  }
839  else
840  {
841  int leftAvaliableCapacity = 0;
842  int rightAvaliableCapacity = 0;
843  int leftUtil = 0;
844  int rightUtil = 0;
845 
846  if (overflowColId > 0)
847  {
848  leftAvaliableCapacity += accumulationCapacity[overflowColId - 1];
849  leftUtil += accumulationUtil[overflowColId - 1];
850  }
851  if (overflowColId < columnNum - 1)
852  {
853  rightAvaliableCapacity += accumulationCapacity[columnNum - 1] - accumulationCapacity[overflowColId];
854  rightUtil += accumulationUtil[columnNum - 1] - accumulationUtil[overflowColId];
855  }
856 
857  int overflowNum = (unsigned int)columnUntilization[overflowColId] - column2Sites[overflowColId].size();
858  int toLeft = 0;
859 
860  int totalAvailableCapacity = rightAvaliableCapacity + leftAvaliableCapacity - leftUtil - rightUtil;
861  assert(totalAvailableCapacity > 0);
862  float toLeftRatio = (float)(leftAvaliableCapacity - leftUtil) / totalAvailableCapacity;
863  int toLeftNum = int((overflowNum * toLeftRatio) + 0.4999);
864  int toRightNum = overflowNum - toLeft;
865 
866  if (leftAvaliableCapacity - leftUtil > 0)
867  {
868  while (toLeftNum > 0 && column2PUs[overflowColId].size() > 0)
869  {
870  column2PUs[overflowColId - 1].push_back(column2PUs[overflowColId][0]);
871  int macroSize = getPUSiteNum(column2PUs[overflowColId][0]);
872  columnUntilization[overflowColId - 1] += macroSize;
873  columnUntilization[overflowColId] -= macroSize;
874  toLeftNum -= macroSize;
875  column2PUs[overflowColId].pop_front();
876  }
877  }
878  if (rightAvaliableCapacity - rightUtil > 0)
879  {
880  while (toRightNum > 0 && column2PUs[overflowColId].size() > 0)
881  {
882  column2PUs[overflowColId + 1].push_front(
883  column2PUs[overflowColId][column2PUs[overflowColId].size() - 1]);
884  int macroSize = getPUSiteNum(column2PUs[overflowColId][column2PUs[overflowColId].size() - 1]);
885  columnUntilization[overflowColId + 1] += macroSize;
886  columnUntilization[overflowColId] -= macroSize;
887  toRightNum -= macroSize;
888  column2PUs[overflowColId].pop_back();
889  }
890  }
891  }
892  }
893  cell2Column.clear();
894  for (unsigned int colId = 0; colId < column2PUs.size(); colId++)
895  {
896  auto PUs = column2PUs[colId];
897  for (auto curPU : PUs)
898  {
899  cell2Column[curPU] = colId;
900  }
901  }
902 }
903 
905 {
907  {
909  }
911  {
913  }
914 }
915 
916 int CLBLegalizer::findIdMaxWithRecurence(int minId, int maxId, std::vector<int> &ids)
917 {
918  int resId = -1;
919  int maxRecurence = 0;
920  assert(ids.size() > 0);
921  for (int i = minId; i <= maxId; i++)
922  {
923  int cnt = 0;
924  for (auto id : ids)
925  {
926  if (id == i)
927  cnt++;
928  }
929  if (cnt > maxRecurence)
930  {
931  resId = i;
932  maxRecurence = cnt;
933  }
934  }
935  assert(resId >= 0);
936  return resId;
937 }
938 
940 {
941 
942  MCLBColumn2PUs.clear();
943  MCLBColumnUntilization.clear();
945  {
946  if (MCLBColumnNum > 0)
947  {
948  MCLBColumn2PUs.resize(MCLBColumnNum, std::deque<PlacementInfo::PlacementUnit *>(0));
950 
951  for (auto &PUCol_pair : PU2Columns)
952  {
953  auto tmpMacroUnit = PUCol_pair.first;
954  if (MCLBPUs.find(tmpMacroUnit) != MCLBPUs.end())
955  {
956  int colId = findIdMaxWithRecurence(0, MCLBColumnNum - 1, PUCol_pair.second);
957 
958  MCLBColumn2PUs[colId].push_back(tmpMacroUnit);
959  MCLBColumnUntilization[colId] += getPUSiteNum(tmpMacroUnit);
960  }
961  }
962  }
963  }
964 
965  LCLBColumn2PUs.clear();
966  LCLBColumnUntilization.clear();
968  {
969  if (LCLBColumnNum > 0)
970  {
971  LCLBColumn2PUs.resize(LCLBColumnNum, std::deque<PlacementInfo::PlacementUnit *>(0));
973 
974  for (auto &PUCol_pair : PU2Columns)
975  {
976  auto tmpMacroUnit = PUCol_pair.first;
977  if (LCLBPUs.find(tmpMacroUnit) != LCLBPUs.end())
978  {
979  int colId = findIdMaxWithRecurence(0, LCLBColumnNum - 1, PUCol_pair.second);
980 
981  LCLBColumn2PUs[colId].push_back(tmpMacroUnit);
982  LCLBColumnUntilization[colId] += getPUSiteNum(tmpMacroUnit);
983  }
984  }
985  }
986  }
987 }
988 
990 {
991  for (auto matchedPair : PULevelMatching)
992  {
993  auto targetPU = matchedPair.first;
994  for (auto curSite : PU2LegalSites[targetPU])
995  {
996  assert(!curSite->isMapped());
997  curSite->setMapped();
998  }
999  }
1000 }
1001 
1003 {
1004 
1005  for (auto matchedPair : PULevelMatching)
1006  {
1007  auto targetPU = matchedPair.first;
1008  for (auto curSite : PU2LegalSites[targetPU])
1009  {
1010  assert(curSite->isMapped());
1011  curSite->resetMapped();
1012  }
1013  }
1014  PULevelMatching.clear();
1015 }
CLBLegalizer::updateMatchingAndUnmatchedPUs
void updateMatchingAndUnmatchedPUs()
record the matching in private list and update the list of PlacementUnits which are not matched by th...
Definition: CLBLegalizer.cc:600
MinCostBipartiteMatcher
Definition: MinCostBipartiteMatcher.h:44
CLBLegalizer::getHPWLChange
float getHPWLChange(PlacementInfo::PlacementUnit *curPU, DeviceInfo::DeviceSite *curSite)
get the HPWL change when the given PlacementUnit moves to the given DeviceSite
Definition: CLBLegalizer.h:682
CLBLegalizer::LCLBColumnUntilization
std::vector< int > LCLBColumnUntilization
record the number of cells (Macro contains multiple cells) in each column of SLICEL
Definition: CLBLegalizer.h:356
CLBLegalizer::MCLBRowNum
int MCLBRowNum
the number of SLICEM rows ocolumnsn the target device
Definition: CLBLegalizer.h:302
CLBLegalizer::enableLCLBLegalization
bool enableLCLBLegalization
Definition: CLBLegalizer.h:423
CLBLegalizer::PU2X
std::map< PlacementInfo::PlacementUnit *, float > PU2X
record the mapping from PlacementUnits to exact DeviceSite location X
Definition: CLBLegalizer.h:380
CLBLegalizer::sortSitesBySiteY
void sortSitesBySiteY(std::vector< DeviceInfo::DeviceSite * > &sites)
Definition: CLBLegalizer.cc:699
paintPlacement.cnt
int cnt
Definition: paintPlacement.py:155
exportDeviceLocation.sites
list sites
Definition: exportDeviceLocation.py:216
CLBLegalizer::MCLB2Column
std::map< PlacementInfo::PlacementUnit *, int > MCLB2Column
record the mapping from SLICEM CLB PlacementUnits to corresponding columns
Definition: CLBLegalizer.h:362
PlacementInfo::getPlacementUnits
std::vector< PlacementUnit * > & getPlacementUnits()
Definition: PlacementInfo.h:2810
PlacementInfo::isLegalLocation
bool isLegalLocation(DesignInfo::DesignCell *curCell, float targetX, float targetY)
check whether the PlacementUnit is legalized in the device area when a cell in it is placed at target...
Definition: PlacementInfo.h:3452
CLBLegalizer::PULevelMatching
std::vector< std::pair< PlacementInfo::PlacementUnit *, DeviceInfo::DeviceSite * > > PULevelMatching
record the binding between PlacementUnits and DeviceSites as a vector of pairs
Definition: CLBLegalizer.h:257
CLBLegalizer::PU2Sites
std::map< PlacementInfo::PlacementUnit *, std::vector< DeviceInfo::DeviceSite * > > PU2Sites
record the mapping from PlacementUnits to the candidate sites which are NOT binded to PUs
Definition: CLBLegalizer.h:215
CLBLegalizer::siteType2Sites
std::map< std::string, std::vector< DeviceInfo::DeviceSite * > > siteType2Sites
a map record the potential sites of different site types
Definition: CLBLegalizer.h:207
CLBLegalizer::PU2Columns
std::map< PlacementInfo::PlacementUnit *, std::vector< int > > PU2Columns
record the column id for the binded cells in involved PlacementUnits
Definition: CLBLegalizer.h:402
CLBLegalizer::minCostBipartiteMatcher
MinCostBipartiteMatcher * minCostBipartiteMatcher
min-cost bipartite matching solver for the legalization
Definition: CLBLegalizer.h:183
CLBLegalizer::getPUSiteNum
int getPUSiteNum(PlacementInfo::PlacementUnit *tmpPUUnit)
check how many sites are required by the given PlacementUnit
Definition: CLBLegalizer.cc:685
CLBLegalizer::MCLBColumn2Sites
std::vector< std::vector< DeviceInfo::DeviceSite * > > MCLBColumn2Sites
record the sites in each column of SLICEM
Definition: CLBLegalizer.h:326
CLBLegalizer::DumpCLBLegalizationCnt
int DumpCLBLegalizationCnt
Definition: CLBLegalizer.h:259
CLBLegalizer::LCLBColumnXs
std::vector< float > LCLBColumnXs
the floating-point X location of the SLICEL columns on the device
Definition: CLBLegalizer.h:320
CLBLegalizer::resetPU2SitesInDistance
void resetPU2SitesInDistance()
clear the information of candidate sites for the PlacementUnits left to be matched
Definition: CLBLegalizer.h:636
CLBLegalizer::siteTypesToLegalize
std::vector< std::string > siteTypesToLegalize
a vector of Cell Type string indicating the target types handled by this CLBLegalizer
Definition: CLBLegalizer.h:169
CLBLegalizer::matchedPUs
std::set< PlacementInfo::PlacementUnit * > matchedPUs
a set of PlacementUnits binded to corresponding DeviceSites
Definition: CLBLegalizer.h:245
DeviceInfo::getSitesInType
std::vector< DeviceSite * > & getSitesInType(std::string &siteType)
Get sites of a specfic type.
Definition: DeviceInfo.h:1043
CLBLegalizer::spreadPUs
void spreadPUs(int columnNum, std::vector< int > &columnUntilization, std::vector< std::vector< DeviceInfo::DeviceSite * >> &column2Sites, std::vector< std::deque< PlacementInfo::PlacementUnit * >> &column2PUs, std::map< PlacementInfo::PlacementUnit *, int > &cell2Column)
spread PlacementUnits accross columns to resolve resource overflow
Definition: CLBLegalizer.cc:810
CLBLegalizer::finalLegalizeBasedOnDP
void finalLegalizeBasedOnDP()
finally dynamic programming to legalize the PlacementUnits which have been mapped to the columns.
Definition: CLBLegalizer.cc:168
CLBLegalizer::matchedSites
std::set< DeviceInfo::DeviceSite * > matchedSites
a set of DeviceSites binded to corresponding PlacementUnits
Definition: CLBLegalizer.h:251
CLBLegalizer::LCLBColumn2Sites
std::vector< std::vector< DeviceInfo::DeviceSite * > > LCLBColumn2Sites
record the sites in each column of SLICEL
Definition: CLBLegalizer.h:332
CLBLegalizer::rightSiteIds
std::map< DeviceInfo::DeviceSite *, int > rightSiteIds
map sites to temperary indexes for bipartite matching
Definition: CLBLegalizer.h:221
CLBLegalizer::LCLBColumnNum
int LCLBColumnNum
the number of SLICEL columns on the target device
Definition: CLBLegalizer.h:296
CLBLegalizer::adjList
std::vector< std::vector< std::pair< int, float > > > adjList
the adjacent list of the bipartite graph
Definition: CLBLegalizer.h:233
CLBLegalizer::dumpMatching
void dumpMatching(bool fixedColumn=false, bool enforce=false)
Definition: CLBLegalizer.cc:628
CLBLegalizer::mapPUsToColumns
void mapPUsToColumns()
map PlacementUnit to the columns according to the locations of the cells in it
Definition: CLBLegalizer.cc:939
CLBLegalizer::initialPUsToLegalize
std::vector< PlacementInfo::PlacementUnit * > initialPUsToLegalize
a vector storing the PlacementUnits which SHOULD be legalized
Definition: CLBLegalizer.h:195
MinCostBipartiteMatcher::solve
void solve()
Definition: MinCostBipartiteMatcher.cc:28
CLBLegalizer::MCLBPUs
std::set< PlacementInfo::PlacementUnit * > MCLBPUs
the PlacementUnits which shoudl be mapped to SLICEM
Definition: CLBLegalizer.h:408
CLBLegalizer::noTarget
bool noTarget
Definition: CLBLegalizer.h:448
CLBLegalizer::createBipartiteGraph
void createBipartiteGraph()
Create a bipartite graph between PlacementUnit and potential DeviceSites.
Definition: CLBLegalizer.cc:556
CLBLegalizer::swapSitePtr
void swapSitePtr(DeviceInfo::DeviceSite **siteA, DeviceInfo::DeviceSite **siteB)
Definition: CLBLegalizer.h:733
CLBLegalizer::sortPUsByPU2Y
void sortPUsByPU2Y(std::deque< PlacementInfo::PlacementUnit * > &PUs)
Definition: CLBLegalizer.cc:690
CLBLegalizer::PU2SiteX
std::map< PlacementInfo::PlacementUnit *, int > PU2SiteX
record the exact site X (column id) of involved PlacementUnits
Definition: CLBLegalizer.h:393
CLBLegalizer::displacementThreshold
float displacementThreshold
displacement threshold to detect potential legal sites
Definition: CLBLegalizer.h:265
CLBLegalizer::legalize
void legalize(bool exactLegalization=false)
conduct legalization and map the PlacementUnit of one of the given types to sites
Definition: CLBLegalizer.cc:78
CLBLegalizer::findIdMaxWithRecurence
int findIdMaxWithRecurence(int minId, int maxId, std::vector< int > &ids)
find the column which contains the most of cells in a macro in a specific range of columns
Definition: CLBLegalizer.cc:916
delayVisualization.c
c
Definition: delayVisualization.py:99
CLBLegalizer::LCLB2Column
std::map< PlacementInfo::PlacementUnit *, int > LCLB2Column
record the mapping from SLICEL CLB PlacementUnits to corresponding columns
Definition: CLBLegalizer.h:368
CLBLegalizer::y2xRatio
float y2xRatio
Definition: CLBLegalizer.h:425
CLBLegalizer::swapPU
void swapPU(PlacementInfo::PlacementUnit **A, PlacementInfo::PlacementUnit **B)
Definition: CLBLegalizer.h:654
CLBLegalizer::LCLBPUs
std::set< PlacementInfo::PlacementUnit * > LCLBPUs
the PlacementUnits which shoudl be mapped to SLICEL
Definition: CLBLegalizer.h:414
CLBLegalizer::MCLBColumnNum
int MCLBColumnNum
the number of SLICEM columns on the target device
Definition: CLBLegalizer.h:290
CLBLegalizer::LCLBColumn2PUs
std::vector< std::deque< PlacementInfo::PlacementUnit * > > LCLBColumn2PUs
record the PlacementUnits in each column of SLICEL
Definition: CLBLegalizer.h:344
print_status
void print_status(std::string tmp_string)
Definition: strPrint.cc:44
CLBLegalizer::getDisplacement
float getDisplacement(PlacementInfo::Location &PULoc, DeviceInfo::DeviceSite *curSite)
Definition: CLBLegalizer.h:665
CLBLegalizer::MCLBColumnUntilization
std::vector< int > MCLBColumnUntilization
record the number of cells (Macro contains multiple cells) in each column of SLICEM
Definition: CLBLegalizer.h:350
CLBLegalizer::DPForMinHPWL
float DPForMinHPWL(int colNum, std::vector< std::vector< DeviceInfo::DeviceSite * >> &Column2Sites, std::vector< std::deque< PlacementInfo::PlacementUnit * >> &Column2PUs)
DP function for the legalization of a specific type of PlacementUnits in the same column.
Definition: CLBLegalizer.cc:187
CLBLegalizer::nJobs
int nJobs
the number of the parallel multi-threading workers to handle the legalization problems
Definition: CLBLegalizer.h:284
CLBLegalizer.h
This header file contains the definitions of CLBLegalizer class and its internal modules and APIs whi...
CLBLegalizer::fixedColumnAverageDisplacement
float fixedColumnAverageDisplacement
the average displacement of fixed column (but not exactly consective) legalization for the involved P...
Definition: CLBLegalizer.h:440
print_warning
void print_warning(std::string tmp_string)
Definition: strPrint.cc:57
CLBLegalizer::CLBLegalizer
CLBLegalizer(std::string legalizerName, PlacementInfo *placementInfo, DeviceInfo *deviceInfo, std::vector< std::string > &siteTypesToLegalize, std::map< std::string, std::string > &JSONCfg)
Construct a new CLBLegalizer object.
Definition: CLBLegalizer.cc:33
CLBLegalizer::PUsToLegalizeSet
std::set< PlacementInfo::PlacementUnit * > PUsToLegalizeSet
a set storing the PlacementUnits which have NOT been legalized
Definition: CLBLegalizer.h:201
PlacementInfo::setPULegalSite
void setPULegalSite(std::map< PlacementInfo::PlacementUnit *, std::vector< DeviceInfo::DeviceSite * >> &PU2Sites)
set the sites occupied by the PlacementUnit objects
Definition: PlacementInfo.h:3668
PlacementInfo::setPULegalXY
void setPULegalXY(std::map< PlacementInfo::PlacementUnit *, float > &PU2X, std::map< PlacementInfo::PlacementUnit *, float > &PU2Y)
set the legalization of some PlacementUnit objects
Definition: PlacementInfo.h:3648
CLBLegalizer::findSiteType2AvailableSites
void findSiteType2AvailableSites()
find available sites for each specific type required by the constructor
Definition: CLBLegalizer.cc:374
CLBLegalizer::findPU2SitesInDistance
void findPU2SitesInDistance()
find candidate sites for the PlacementUnits left to be matched
Definition: CLBLegalizer.h:600
PlacementInfo::PlacementUnit
a movement unit in placement with information of location and resource demand
Definition: PlacementInfo.h:1010
CLBLegalizer::siteList
std::vector< DeviceInfo::DeviceSite * > siteList
a vector for the candidate sites for bipartite matching
Definition: CLBLegalizer.h:227
CLBLegalizer::PU2Y
std::map< PlacementInfo::PlacementUnit *, float > PU2Y
record the mapping from PlacementUnits to exact DeviceSite location Y
Definition: CLBLegalizer.h:385
writeStrToGZip
void writeStrToGZip(std::string fileName, std::stringstream &data)
Definition: dumpZip.cc:29
CLBLegalizer::PU2LegalSites
std::map< PlacementInfo::PlacementUnit *, std::vector< DeviceInfo::DeviceSite * > > PU2LegalSites
record the mapping from PlacementUnits to exact DeviceSites
Definition: CLBLegalizer.h:374
CLBLegalizer::JSONCfg
std::map< std::string, std::string > & JSONCfg
Definition: CLBLegalizer.h:177
CLBLegalizer::finalAverageDisplacement
float finalAverageDisplacement
the average displacement of exact legalization for the involved PlacementUnit
Definition: CLBLegalizer.h:431
CLBLegalizer::MCLBColumnXs
std::vector< float > MCLBColumnXs
the floating-point X location of the SLICEM columns on the device
Definition: CLBLegalizer.h:314
CLBLegalizer::resolveOverflowColumns
void resolveOverflowColumns()
resolve the overflow columns during fixed column legalization by spreading "outliers" to neighbor col...
Definition: CLBLegalizer.cc:904
CLBLegalizer::enableMCLBLegalization
bool enableMCLBLegalization
Definition: CLBLegalizer.h:422
CLBLegalizer::updatePUMatchingLocation
void updatePUMatchingLocation(bool isRoughLegalization=true, bool updateDisplacement=true)
update the locations of the legalization anchors for the PlacementUnits.
Definition: CLBLegalizer.cc:719
CLBLegalizer::verbose
bool verbose
Definition: CLBLegalizer.h:424
CLBLegalizer::MCLBColumn2PUs
std::vector< std::deque< PlacementInfo::PlacementUnit * > > MCLBColumn2PUs
record the PlacementUnits in each column of SLICEM
Definition: CLBLegalizer.h:338
CLBLegalizer::fixedColumnLegalize
void fixedColumnLegalize()
conduct fixed-column legalization as a step in exact legalization. During fixed-column legalization,...
Definition: CLBLegalizer.cc:139
CLBLegalizer::getPUsToLegalize
void getPUsToLegalize()
get the PlacementUnits which SHOULD be legalized
Definition: CLBLegalizer.cc:336
CLBLegalizer::resetSettings
void resetSettings()
clear the mapping information and reset the mapping parameters
Definition: CLBLegalizer.h:587
DeviceInfo
Information class related to FPGA device, including the details of BEL/Site/Tile/ClockRegion.
Definition: DeviceInfo.h:43
CLBLegalizer::quick_sort_WLChange
void quick_sort_WLChange(PlacementInfo::PlacementUnit *curPU, std::vector< DeviceInfo::DeviceSite * > &sites, int p, int q)
Definition: CLBLegalizer.h:769
CLBLegalizer::placementInfo
PlacementInfo * placementInfo
Definition: CLBLegalizer.h:155
print_info
void print_info(std::string tmp_string)
Definition: strPrint.cc:39
checkHalfColumn.i
int i
Definition: checkHalfColumn.py:5
CLBLegalizer::roughAverageDisplacement
float roughAverageDisplacement
the average displacement of rough legalization for the involved PlacementUnit
Definition: CLBLegalizer.h:446
MinCostBipartiteMatcher::getMatchedRightNode
int getMatchedRightNode(int x)
Definition: MinCostBipartiteMatcher.h:119
CLBLegalizer::PU2SitesInDisplacementThreshold
std::map< PlacementInfo::PlacementUnit *, std::vector< DeviceInfo::DeviceSite * > * > PU2SitesInDisplacementThreshold
a cache record the candidate sites within a given displacement threshold for each PlacementUnit
Definition: CLBLegalizer.h:420
CLBLegalizer::PUsToLegalize
std::vector< PlacementInfo::PlacementUnit * > PUsToLegalize
a vector storing the PlacementUnits which have NOT been legalized
Definition: CLBLegalizer.h:189
CLBLegalizer::deviceInfo
DeviceInfo * deviceInfo
Definition: CLBLegalizer.h:156
CLBLegalizer::roughlyLegalize
void roughlyLegalize()
conduct rough legalization.
Definition: CLBLegalizer.cc:114
CLBLegalizer::setSitesMapped
void setSitesMapped()
Set the sites which are binded as mapped so they will not be mapped to other elements in the netlist.
Definition: CLBLegalizer.cc:989
CLBLegalizer::maxNumCandidate
int maxNumCandidate
the maximum number of final candidate sites
Definition: CLBLegalizer.h:271
CLBLegalizer::LCLBRowNum
int LCLBRowNum
the number of SLICEL rows on the target device
Definition: CLBLegalizer.h:308
CLBLegalizer::resetSitesMapped
void resetSitesMapped()
reset the mapped flag of the involved sites.
Definition: CLBLegalizer.cc:1002
PlacementInfo
Information related to FPGA placement (wirelength optimization, cell spreading, legalization,...
Definition: PlacementInfo.h:59
CLBLegalizer::PU2Site2HPWLIncrease
std::map< PlacementInfo::PlacementUnit *, std::map< DeviceInfo::DeviceSite *, float > > PU2Site2HPWLIncrease
a map of map recording the HPWL overhead when binding a PlacementUnit to a specific site
Definition: CLBLegalizer.h:239
CLBLegalizer::findPossibleLegalLocation
void findPossibleLegalLocation(bool fixedColumn=false)
find potential sites for each PlacementUnit
Definition: CLBLegalizer.cc:472