34 std::vector<DesignInfo::DesignCellType> ¯oTypesToLegalize,
35 std::map<std::string, std::string> &JSONCfg)
36 : legalizerName(legalizerName), placementInfo(placementInfo), deviceInfo(deviceInfo),
37 compatiblePlacementTable(placementInfo->getCompatiblePlacementTable()),
38 macroTypesToLegalize(macroTypesToLegalize), cellLoc(placementInfo->getCellId2location()), JSONCfg(JSONCfg)
80 if (!directLegalization)
88 if (exactLegalization)
167 float tmpAverageDisplacement = 0.0;
176 "] Done finalLegalizeBasedOnDP: Macro Cell Average Final Legalization Displacement = " +
184 std::vector<std::deque<PlacementInfo::PlacementUnit *>> &Column2PUs)
197 float tmpTotalDisplacement = 0.0;
198 std::map<PlacementInfo::PlacementUnit *, std::vector<DeviceInfo::DeviceSite *>> PU2Sites;
200 for (
auto &PUDeque : Column2PUs)
202 for (
auto tmpPU : PUDeque)
204 assert(PU2Sites.find(tmpPU) == PU2Sites.end());
205 PU2Sites[tmpPU] = std::vector<DeviceInfo::DeviceSite *>();
209 #pragma omp parallel for
210 for (
int c = 0;
c < colNum;
c++)
212 int numPUs = Column2PUs[
c].size();
216 auto &curColSites = Column2Sites[
c];
217 auto &curColPU = Column2PUs[
c];
223 std::vector<std::vector<float>> f(numPUs, std::vector<float>(curColSites.size(), 1000000000.0));
224 std::vector<std::vector<bool>> fChoice(
225 numPUs, std::vector<bool>(curColSites.size(), 0));
227 int minLastPUTop = -1;
229 int totalMacroCellNum = 0;
231 totalMacroCellNum += heightPURow;
232 float minHPWLChange = 1100000000.0;
233 for (
unsigned int j = totalMacroCellNum - 1; j < curColSites.size(); j++)
235 float curHPWLChange =
getHPWLChange(curColPU[0], curColSites[j - heightPURow + 1]);
236 if ((curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1))
239 curHPWLChange = 1100000000.0;
244 curColSites[j]->getClockRegionY() != curColSites[j - heightPURow + 1]->getClockRegionY())
247 curHPWLChange = 1100000000.0;
252 if (curMacro->getCells().size() > 1 && curColSites[j - heightPURow + 1]->getSiteY() % 2 != 0)
254 curHPWLChange = 1100000000.0;
258 if (curHPWLChange < minHPWLChange)
260 minHPWLChange = curHPWLChange;
267 f[0][j] = minHPWLChange;
271 for (
int i = 1;
i < numPUs;
i++)
273 float minVal = 100000000.0;
275 totalMacroCellNum += heightPURow;
276 for (
unsigned int j = totalMacroCellNum - 1; j < curColSites.size();
279 float curHPWLChange =
getHPWLChange(curColPU[
i], curColSites[j - heightPURow + 1]);
280 if ((curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1))
283 curHPWLChange = 1100000000.0;
288 curColSites[j]->getClockRegionY() != curColSites[j - heightPURow + 1]->getClockRegionY())
291 curHPWLChange = 1100000000.0;
296 if (curMacro->getCells().size() > 1 && curColSites[j - heightPURow + 1]->getSiteY() % 2 != 0)
298 curHPWLChange = 1100000000.0;
302 if (f[
i][j - 1] > f[
i - 1][j - heightPURow] + curHPWLChange)
307 if (f[
i - 1][j - heightPURow] + curHPWLChange < minVal)
309 minVal = f[
i - 1][j - heightPURow] + curHPWLChange;
315 f[
i][j] = std::min(f[
i][j - 1], f[
i - 1][j - heightPURow] + curHPWLChange);
319 if (minLastPUTop < 0)
322 for (
int i = 0;
i < numPUs;
i++)
324 std::cout << curColPU[
i] <<
"\n";
327 std::cout <<
"total PU Cnt=" << PUCnt <<
"\n";
328 for (
int i = 0;
i < numPUs;
i++)
329 for (
int j = 0; j < curColSites.size(); j++)
333 std::cout <<
"PU#" <<
i <<
" (" <<
getMarcroCellNum(curColPU[
i]) <<
"): " << j <<
"\n";
340 assert(minLastPUTop >= 0);
342 std::vector<DeviceInfo::DeviceSite *> PUBottom2Site_reverse(0);
344 for (
int i = numPUs - 1;
i >= 0;
i--)
346 assert(minLastPUTop >= 0);
348 while (!fChoice[
i][minLastPUTop])
351 assert(minLastPUTop >= 0);
353 auto curSite = curColSites[minLastPUTop - heightPURow + 1];
354 assert(PU2Sites[curColPU[
i]].size() == 0);
356 for (
int curColSiteId = minLastPUTop - heightPURow + 1; curColSiteId <= minLastPUTop; curColSiteId++)
358 PU2Sites[curColPU[
i]].push_back(curColSites[curColSiteId]);
360 minLastPUTop -= heightPURow;
370 for (
auto &PUDeque : Column2PUs)
372 for (
auto tmpPU : PUDeque)
374 assert(PU2Sites.find(tmpPU) != PU2Sites.end());
375 auto &curSites = PU2Sites[tmpPU];
376 assert(curSites.size());
377 assert(
PU2X.find(tmpPU) ==
PU2X.end());
378 auto curSite = curSites[0];
380 PU2X[tmpPU] = curSite->X();
381 PU2Y[tmpPU] = curSite->Y();
383 tmpTotalDisplacement += std::fabs(tmpPU->X() - curSite->X()) + std::fabs(tmpPU->Y() - curSite->Y());
387 return tmpTotalDisplacement;
391 std::deque<PlacementInfo::PlacementUnit *> Column2PUs)
395 int numPUs = Column2PUs.size();
399 auto &curColSites = Column2Sites[
c];
400 auto &curColPU = Column2PUs;
407 std::vector<std::vector<float>> f(numPUs, std::vector<float>(curColSites.size(), 1000000000.0));
408 std::vector<std::vector<bool>> fChoice(
409 numPUs, std::vector<bool>(curColSites.size(), 0));
411 int minLastPUTop = -1;
413 int totalMacroCellNum = 0;
415 totalMacroCellNum += heightPURow;
416 float minHPWLChange = 1100000000.0;
417 for (
unsigned int j = totalMacroCellNum - 1; j < curColSites.size(); j++)
419 float curHPWLChange = 1;
420 if ((curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1))
423 curHPWLChange = 1100000000.0;
428 curColSites[j]->getClockRegionY() != curColSites[j - heightPURow + 1]->getClockRegionY())
431 curHPWLChange = 1100000000.0;
436 if (curMacro->getCells().size() > 1 && curColSites[j - heightPURow + 1]->getSiteY() % 2 != 0)
438 curHPWLChange = 1100000000.0;
442 if (curHPWLChange < minHPWLChange)
444 minHPWLChange = curHPWLChange;
451 f[0][j] = minHPWLChange;
455 for (
int i = 1;
i < numPUs;
i++)
457 float minVal = 100000000.0;
459 totalMacroCellNum += heightPURow;
460 for (
unsigned int j = totalMacroCellNum - 1; j < curColSites.size();
463 float curHPWLChange = 1;
464 if ((curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1))
467 curHPWLChange = 1100000000.0;
472 curColSites[j]->getClockRegionY() != curColSites[j - heightPURow + 1]->getClockRegionY())
475 curHPWLChange = 1100000000.0;
480 if (curMacro->getCells().size() > 1 && curColSites[j - heightPURow + 1]->getSiteY() % 2 != 0)
482 curHPWLChange = 1100000000.0;
486 if (f[
i][j - 1] > f[
i - 1][j - heightPURow] + curHPWLChange)
491 if (f[
i - 1][j - heightPURow] + curHPWLChange < minVal)
493 minVal = f[
i - 1][j - heightPURow] + curHPWLChange;
499 f[
i][j] = std::min(f[
i][j - 1], f[
i - 1][j - heightPURow] + curHPWLChange);
503 if (minLastPUTop < 0)
506 for (
int i = 0;
i < numPUs;
i++)
508 std::cout << curColPU[
i] <<
"\n";
511 std::cout <<
"total PU Cnt=" << PUCnt <<
"\n";
512 for (
int i = 0;
i < numPUs;
i++)
513 for (
int j = 0; j < curColSites.size(); j++)
517 std::cout <<
"PU#" <<
i <<
" (" <<
getMarcroCellNum(curColPU[
i]) <<
"): " << j <<
"\n";
524 return (minLastPUTop >= 0);
538 if (curCell->getCellType() == curType)
541 if (!curPU->isLocked())
545 if (curCell->isBRAM())
549 if (curCell->isDSP())
553 if (curCell->isCarry())
569 macroType2Sites[curCellType] = std::vector<DeviceInfo::DeviceSite *>(0);
572 std::string targetSiteType =
576 for (
auto curSite : sitesInType)
578 if (!curSite->isOccupied() && !curSite->isMapped())
705 macro2Sites[curCell] = std::vector<DeviceInfo::DeviceSite *>(0);
712 print_status(
"searching sites for " + std::to_string(numMacroCells) +
" macroCells with displacement<" +
715 #pragma omp parallel for
716 for (
int i = 0;
i < numMacroCells;
i++)
719 auto curCellType = curCell->getCellType();
720 int macroLength = -1;
728 macroLength = cellOffset = 1;
733 for (cellOffset = 0; cellOffset < (int)(tmpMacro->getCells().size()); cellOffset++)
735 if (tmpMacro->getCell(cellOffset) == curCell)
737 macroLength = tmpMacro->getCells().size();
746 std::vector<DeviceInfo::DeviceSite *> *candidateSite =
nullptr;
749 int targetSiteX = -1;
750 if (curCell->isDSP())
755 if (curCell->isCarry())
760 if (curCell->isBRAM())
765 assert(targetSiteX >= 0);
767 std::vector<std::vector<DeviceInfo::DeviceSite *>> *column2Sites;
782 assert(
false &&
"undefine type");
784 for (
auto &tmpCol : *column2Sites)
786 if (tmpCol.size() == 0)
788 if (tmpCol[0]->getSiteX() == targetSiteX)
790 candidateSite = &tmpCol;
799 assert(candidateSite);
801 for (
auto curSite : *candidateSite)
817 curSite->getSiteY() % 2 != 0)
821 curCell->isVirtualCell() && curSite->getSiteY() % 2 != 1)
826 int headLocation = curSite->getSiteY() - cellOffset;
827 int tailLocation = headLocation + macroLength - 1;
840 cellLoc[curCell->getCellId()]);
855 float minCost = 10000000;
871 if (tmpCost < minCost)
880 if (minCost < 0.0001)
882 float compensation = 10 - minCost;
885 for (
unsigned int tmpId = 0; tmpId <
adjList[leftCellId].size(); tmpId++)
887 adjList[leftCellId][tmpId].second += compensation;
909 std::vector<DesignInfo::DesignCell *> newMacrosToLegalize;
910 newMacrosToLegalize.clear();
916 newMacrosToLegalize.push_back(curCell);
924 if (
JSONCfg.find(
"DumpMacroLegalization") !=
JSONCfg.end() || enforce)
926 std::string dumpFile =
"";
934 print_status(
"MacroLegalizer: dumping MacroLegalization archieve to: " + dumpFile);
938 std::stringstream outfile0;
943 auto matchedSite = matchedPair.second;
944 auto curCell = matchedPair.first;
946 outfile0 <<
"CellLevelMatching name: " << curCell->
getName() <<
" CellId: " << curCell->getCellId()
947 <<
" PUID: " << curPU->getId() <<
"\n locX:" <<
cellLoc[curCell->getCellId()].X
948 <<
"\n locY:" <<
cellLoc[curCell->getCellId()].Y <<
"\n";
949 outfile0 <<
" macthed with: " << matchedSite->getName() <<
"\n locX:" << matchedSite->X()
950 <<
"\n locY:" << matchedSite->Y()
952 <<
"\n HPWLIncrease:" <<
getHPWLChange(curCell, matchedSite) <<
"\n";
960 auto matchedSite = matchedPair.second;
961 auto curPU = matchedPair.first;
962 outfile0 <<
"PULevelMatching name: " << curPU->getName() <<
" PUID: " << curPU->getId()
963 <<
"\n locX:" << curPU->X() <<
"\n locY:" << curPU->Y()
964 <<
"\n PU2X:" <<
PU2X[curPU] <<
"\n PU2Y:" <<
PU2Y[curPU] <<
"\n";
965 assert(std::fabs(matchedSite->X() -
PU2X[curPU]) + std::fabs(matchedSite->Y() -
PU2Y[curPU]) < 0.1);
969 outfile0 <<
" macthed with: " << matchedSite->getName() <<
"\n locX:" << matchedSite->X()
970 <<
"\n locY:" << matchedSite->Y()
972 <<
"\n HPWLIncrease:" <<
getHPWLChange(curPU, matchedSite) <<
"\n";
981 for (
int j = 0; j < numPUs; j++)
984 outfile0 <<
"BRAM col#" <<
i <<
": " << PU->getName() <<
" PUY:" <<
PU2Y[PU]
985 <<
" numPUs:" <<
getMarcroCellNum(PU) <<
" netNum:" << PU->getNetsSetPtr()->size()
992 for (
int j = 0; j < numPUs; j++)
995 outfile0 <<
"DSP col#" <<
i <<
": " << PU->getName() <<
" PUY:" <<
PU2Y[PU]
996 <<
" numPUs:" <<
getMarcroCellNum(PU) <<
" netNum:" << PU->getNetsSetPtr()->size()
1003 for (
int j = 0; j < numPUs; j++)
1006 outfile0 <<
"CARRY col#" <<
i <<
": " << PU->getName() <<
" PUY:" <<
PU2Y[PU]
1007 <<
" numPUs:" <<
getMarcroCellNum(PU) <<
" netNum:" << PU->getNetsSetPtr()->size()
1014 print_status(
"MacroLegalizer: dumped MacroLegalization archieve to: " + dumpFile);
1027 if (macroPU->checkHasBRAM())
1028 return macroPU->getBRAMNum();
1029 else if (macroPU->checkHasDSP())
1030 return macroPU->getDSPNum();
1031 else if (macroPU->checkHasCARRY())
1032 return macroPU->getCARRYNum();
1035 assert(
false &&
"undefined legaliation macro");
1045 int numPUs = PUs.size();
1046 for (
int i = 0;
i < numPUs;
i++)
1047 for (
int j =
i + 1; j < numPUs; j++)
1054 int numSites =
sites.size();
1055 bool ordered =
true;
1056 for (
int i = 1;
i < numSites;
i++)
1066 for (
int i = 0;
i < numSites;
i++)
1067 for (
int j =
i + 1; j < numSites; j++)
1096 float tmpAverageDisplacement = 0.0;
1100 auto matchedSite = matchedPair.second;
1101 auto curCell = matchedPair.first;
1105 if (
PU2Y.find(curPU) ==
PU2Y.end())
1109 if (curCell->isBRAM())
1113 if (curCell->isDSP())
1117 if (curCell->isCarry())
1123 float actualPUX = 0;
1124 float actualPUY = 0;
1129 tmpAverageDisplacement += std::fabs(
cellLoc[curCell->getCellId()].X - matchedSite->X()) +
1130 std::fabs(
cellLoc[curCell->getCellId()].Y - matchedSite->Y());
1131 assert(isRoughLegalization ||
PU2SiteX[curPU] == -1 ||
PU2SiteX[curPU] == matchedSite->getSiteX());
1132 PU2SiteX[curPU] = matchedSite->getSiteX();
1133 PU2X[curPU] += actualPUX;
1134 PU2Y[curPU] += actualPUY;
1139 PU2Columns[curPU].push_back(matchedSite->getSiteX());
1146 "] Macro Cell Average Displacement = " + std::to_string(tmpAverageDisplacement));
1148 if (updateDisplacement)
1150 if (isRoughLegalization)
1156 for (
auto pairPU2X :
PU2X)
1159 PU2X[pairPU2X.first] /= numCells;
1160 PU2Y[pairPU2X.first] /= numCells;
1163 #pragma omp parallel for
1167 #pragma omp parallel for
1171 #pragma omp parallel for
1179 std::vector<std::vector<DeviceInfo::DeviceSite *>> &column2Sites,
1180 std::vector<std::deque<PlacementInfo::PlacementUnit *>> &column2PUs,
1181 std::map<DesignInfo::DesignCell *, int> &cell2Column,
float globalBudgeRatio)
1183 std::vector<float> budgetRatios(columnNum, globalBudgeRatio);
1186 int overflowColId = -1;
1187 std::vector<int> accumulationUtil(columnNum, 0), accumulationCapacity(columnNum, 0);
1188 accumulationUtil[0] = columnUntilization[0];
1189 accumulationCapacity[0] = column2Sites[0].size() * budgetRatios[0];
1190 for (
int colId = 1; colId < columnNum; colId++)
1192 accumulationUtil[colId] = accumulationUtil[colId - 1] + columnUntilization[colId];
1193 accumulationCapacity[colId] =
1194 accumulationCapacity[colId - 1] + column2Sites[colId].size() * budgetRatios[colId];
1197 for (
int colId = 0; colId < columnNum; colId++)
1199 if (budgetRatios[colId] == 1)
1201 if (column2Sites[colId].size() < (
unsigned int)columnUntilization[colId])
1203 overflowColId = colId;
1209 if (column2Sites[colId].size() * budgetRatios[colId] < (
unsigned int)columnUntilization[colId])
1211 overflowColId = colId;
1218 assert(budgetRatios[colId] - 0.05 > 0);
1219 budgetRatios[colId] -= 0.05;
1220 overflowColId = colId;
1224 if (overflowColId < 0)
1230 print_warning(
"column overflow resolving col:" + std::to_string(overflowColId));
1231 for (
int colId = 0; colId < columnNum; colId++)
1233 std::cout <<
" colId#" << colId <<
" columnUntilization:" << columnUntilization[colId] <<
" "
1234 <<
" siteCap:" << column2Sites[colId].size()
1235 <<
" actualSiteCap:" << column2Sites[colId].size() * budgetRatios[colId] <<
"\n";
1237 int leftAvaliableCapacity = 0;
1238 int rightAvaliableCapacity = 0;
1242 if (overflowColId > 0)
1244 leftAvaliableCapacity += accumulationCapacity[overflowColId - 1];
1245 leftUtil += accumulationUtil[overflowColId - 1];
1247 if (overflowColId < columnNum - 1)
1249 rightAvaliableCapacity += accumulationCapacity[columnNum - 1] - accumulationCapacity[overflowColId];
1250 rightUtil += accumulationUtil[columnNum - 1] - accumulationUtil[overflowColId];
1254 (
unsigned int)columnUntilization[overflowColId] -
1255 column2Sites[overflowColId].size() * budgetRatios[overflowColId];
1258 std::cout <<
" overflowNum=" << overflowNum <<
"\n";
1260 int totalAvailableCapacity = rightAvaliableCapacity + leftAvaliableCapacity - leftUtil - rightUtil;
1261 assert(totalAvailableCapacity > 0);
1262 float toLeftRatio = (float)(leftAvaliableCapacity - leftUtil) / totalAvailableCapacity;
1263 int toLeftNum = int((overflowNum * toLeftRatio) + 0.4999);
1264 int toRightNum = overflowNum - toLeft;
1266 if (leftAvaliableCapacity - leftUtil > 0)
1268 while (toLeftNum > 0 && column2PUs[overflowColId].size() > 0)
1270 column2PUs[overflowColId - 1].push_back(column2PUs[overflowColId][0]);
1272 columnUntilization[overflowColId - 1] += macroSize;
1273 columnUntilization[overflowColId] -= macroSize;
1274 toLeftNum -= macroSize;
1275 column2PUs[overflowColId].pop_front();
1278 if (rightAvaliableCapacity - rightUtil > 0)
1280 while (toRightNum > 0 && column2PUs[overflowColId].size() > 0)
1282 column2PUs[overflowColId + 1].push_front(
1283 column2PUs[overflowColId][column2PUs[overflowColId].size() - 1]);
1284 int macroSize =
getMarcroCellNum(column2PUs[overflowColId][column2PUs[overflowColId].size() - 1]);
1285 columnUntilization[overflowColId + 1] += macroSize;
1286 columnUntilization[overflowColId] -= macroSize;
1287 toRightNum -= macroSize;
1288 column2PUs[overflowColId].pop_back();
1293 cell2Column.clear();
1294 for (
unsigned int colId = 0; colId < column2PUs.size(); colId++)
1296 auto PUs = column2PUs[colId];
1297 for (
auto curPU : PUs)
1301 auto curCell = unpackedCell->getCell();
1302 cell2Column[curCell] = colId;
1306 for (
auto curCell : macroPU->getCells())
1308 cell2Column[curCell] = colId;
1335 int maxRecurence = 0;
1336 assert(ids.size() > 0);
1337 for (
int i = minId;
i <= maxId;
i++)
1345 if (
cnt > maxRecurence)
1358 float closeDiff = 100000000;
1360 for (
unsigned int i = 0;
i < Xs.size();
i++)
1362 if (std::fabs(curX - Xs[
i]) < closeDiff)
1364 closeDiff = std::fabs(curX - Xs[
i]);
1382 if (directLegalization)
1384 for (
auto &tmpMacroUnit :
BRAMPUs)
1398 auto tmpMacroUnit = PUCol_pair.first;
1417 if (directLegalization)
1419 for (
auto tmpMacroUnit :
DSPPUs)
1434 auto tmpMacroUnit = PUCol_pair.first;
1452 if (directLegalization)
1469 auto tmpMacroUnit = PUCol_pair.first;
1488 auto matchedSite = matchedPair.second;
1489 assert(!matchedSite->isMapped());
1490 matchedSite->setMapped();
1497 auto targetPU = matchedPair.first;
1500 assert(!curSite->isMapped());
1501 curSite->setMapped();
1513 auto matchedSite = matchedPair.second;
1514 assert(matchedSite->isMapped());
1515 matchedSite->resetMapped();
1522 auto targetPU = matchedPair.first;
1525 assert(curSite->isMapped());
1526 curSite->resetMapped();