34 float connectionToFixedFactor)
35 : placementInfo(placementInfo), JSONCfg(JSONCfg), connectionToFixedFactor(connectionToFixedFactor)
71 if (
JSONCfg[
"drawClusters"] ==
"true")
84 if (!curPU->isFixed())
89 curPU->setAnchorLocation(fX, fY);
115 int minClusterCellNum =
121 int eachClusterDSPNum = 96;
122 int eachClusterBRAMNum = 24;
123 int gridH = std::stoi(
JSONCfg[
"clockRegionYNum"]);
124 int gridW = std::stoi(
JSONCfg[
"clockRegionXNum"]);
128 eachClusterDSPNum = std::stoi(
JSONCfg[
"clockRegionDSPNum"]);
132 eachClusterBRAMNum = std::stoi(
JSONCfg[
"clockRegionBRAMNum"]);
150 std::set<int> extractedCellIds;
151 extractedCellIds.clear();
153 print_status(
"ClusterPlacer:: create long path cluster units (pathLengthThr=" + std::to_string(pathLengthThr) +
155 unsigned int maxSize = 0;
156 for (
auto timingNode : timingNodes)
158 if (timingNode->getLongestPathLength() > pathLengthThr && timingNode->getForwardLevel() > pathLengthThr * 0.333)
160 auto curCell = timingNode->getDesignNode();
164 std::vector<int> candidateCellIds;
166 candidateCellIds.clear();
168 if (timingNode->getOutEdges().size() >= 16)
171 for (
auto outEdge : timingNode->getOutEdges())
173 if (extractedCellIds.find(outEdge->getSink()->getId()) == extractedCellIds.end())
174 candidateCellIds.push_back(outEdge->getSink()->getId());
185 std::set<PlacementInfo::PlacementUnit *> PUsInLongPaths;
186 PUsInLongPaths.clear();
187 for (
auto &candidateCellId : candidateCellIds)
189 extractedCellIds.insert(candidateCellId);
193 PUsInLongPaths.insert(PUInPath);
196 if (PUsInLongPaths.size() == 0)
200 for (
auto PUInPath : PUsInLongPaths)
206 if (!PUInPath->isFixed())
210 int cellId = unpackedCell->getCell()->getCellId();
211 extractedCellIds.insert(cellId);
215 for (
auto tmpCell : curMacro->getCells())
217 int cellId = tmpCell->getCellId();
218 extractedCellIds.insert(cellId);
224 if (PUsInLongPaths.size() > maxSize)
225 maxSize = PUsInLongPaths.size();
232 print_info(
"ClusterPlacer: largest long-path cluster size=" + std::to_string(maxSize));
243 if (cellSet.size() > 5000 || cellSet.size() < 20)
246 std::set<PlacementInfo::PlacementUnit *> PUsInuserDefinedClusterCluster;
247 PUsInuserDefinedClusterCluster.clear();
248 for (
auto &curCell : cellSet)
253 PUsInuserDefinedClusterCluster.insert(tmpPU);
257 for (
auto tmpPU : PUsInuserDefinedClusterCluster)
263 print_info(
"build a cluster (size=" + std::to_string(curClusterUnit->
getUnits().size()) +
") for clock [" +
264 curClock->getName() +
"].");
271 std::vector<std::vector<DesignInfo::DesignCell *>> &predefinedCellClusters =
279 for (
auto &clusterCellSet : predefinedCellClusters)
282 bool noOverlap =
true;
283 std::set<PlacementInfo::PlacementUnit *> PUsInuserDefinedClusterCluster;
284 PUsInuserDefinedClusterCluster.clear();
285 for (
auto tmpCell : clusterCellSet)
294 PUsInuserDefinedClusterCluster.insert(tmpPU);
299 for (
auto tmpPU : PUsInuserDefinedClusterCluster)
313 print_info(
"There are " + std::to_string(predefinedCellClusters.size()) +
" predefined userDefinedClusters and " +
314 std::to_string(overlapCnt) +
" overlapped clusters and totally " + std::to_string(
clusterUnits.size()) +
315 " userDefinedCluster clusters are identified.");
353 for (
int placementUnitId : cluster)
362 int eachClusterBRAMNum)
377 std::vector<std::set<int>> newClusters(0);
380 std::set<int> curCluster;
382 for (
int clusterUnitId : cluster)
384 for (
auto tmpPU :
clusterUnits[clusterUnitId]->getUnits())
388 curCluster.insert(tmpPU->getId());
389 tmpWeight += tmpPU->getWeight();
392 newClusters.push_back(curCluster);
406 " global clocks and totally " + std::to_string(
clusterUnits.size()) +
" clock clusters are identified.");
411 " long-path clusters are identified.");
416 " Single-PU clusters are identified.");
433 std::vector<std::set<int>> newClusters(0);
434 unsigned int PUCnt = 0;
437 std::set<int> curCluster;
439 for (
int clusterUnitId : cluster)
441 for (
auto tmpPU :
clusterUnits[clusterUnitId]->getUnits())
445 curCluster.insert(tmpPU->getId());
446 tmpWeight += tmpPU->getWeight();
450 newClusters.push_back(curCluster);
459 std::vector<std::vector<DesignInfo::DesignCell *>> &predefinedCellClusters =
462 std::set<PlacementInfo::PlacementUnit *> reallocatedPUs;
464 int reallocateCnt = 0;
465 for (
auto &clusterCellSet : predefinedCellClusters)
467 std::vector<int> cluster2overlappedCellNum(
clusters.size(), 0);
468 int maxOverlappedClusterId = 0;
469 int maxOverlapCnt = 0;
473 for (
auto tmpCell : clusterCellSet)
475 DSPCnt += tmpCell->isDSP();
476 BRAMCnt += tmpCell->isBRAM();
479 if (DSPCnt >= 8 || BRAMCnt >= 8)
483 for (
auto tmpCell : clusterCellSet)
486 auto tmpPUId = tmpPU->
getId();
492 cluster2overlappedCellNum[
i]++;
493 if (cluster2overlappedCellNum[
i] > maxOverlapCnt)
495 cluster2overlappedCellNum[
i] = cluster2overlappedCellNum[
i];
496 maxOverlappedClusterId =
i;
504 for (
auto tmpCell : clusterCellSet)
507 auto tmpPUId = tmpPU->
getId();
510 if (reallocatedPUs.find(tmpPU) != reallocatedPUs.end())
512 reallocatedPUs.insert(tmpPU);
517 clusters[maxOverlappedClusterId].insert(tmpPUId);
524 print_info(
"reallocate " + std::to_string(reallocateCnt) +
" PU(s)");
529 std::string infoStr =
"Recursive partitioning generates " + std::to_string(
clusters.size()) +
530 " clusters and the numbers of the placement units for them are: ";
534 int totalCellsinCluster = 0;
539 int cellsinCluster = 0;
540 for (
int PUId : cluster)
544 for (
auto tmpCell : curMacro->getCells())
546 DSPNum += tmpCell->isDSP();
547 BRAMNum += tmpCell->isBRAM();
552 DSPNum += curUnpackedCell->getCell()->isDSP();
553 BRAMNum += curUnpackedCell->getCell()->isBRAM();
556 cellsinCluster += PUs[PUId]->getWeight();
557 totalCellsinCluster += PUs[PUId]->getWeight();
559 infoStr += std::to_string(cluster.size()) +
"-" + std::to_string(cellsinCluster) +
560 "(DSP:" + std::to_string(DSPNum) +
",BRAM:" + std::to_string(BRAMNum) +
"), ";
567 print_warning(
"Average cluster size is too large = " + std::to_string((totalCellsinCluster /
clusters.size())));
577 return unpackedCell->getCell()->isIO();
581 for (
auto tmpCell : curMacro->getCells())
607 std::map<PlacementInfo::PlacementUnit *, int> fixedPlacementUnit2LocId;
608 fixedPlacementUnit2LocId.clear();
612 int ignoredConnectCnt = 0;
616 for (
auto driveU : net->getDriverUnits())
618 if (driveU->isFixed())
620 if (fixedPlacementUnit2LocId.find(driveU) == fixedPlacementUnit2LocId.end())
622 int amo = fixedPlacementUnit2LocId.size();
623 fixedPlacementUnit2LocId[driveU] = amo;
626 fixedX.push_back(driveU->X() + clockRegionW / 2.0);
627 fixedY.push_back(driveU->Y());
631 fixedX.push_back(driveU->X());
632 fixedY.push_back(driveU->Y());
637 for (
auto UBeDriven : net->getUnitsBeDriven())
639 int A = driveU->getId();
640 int B = UBeDriven->getId();
643 if (maxLength > 0 && maxLength < 3 && net->getUnitsBeDriven().size() < 8 && cutShortPathNets)
648 assert(clusterA >= 0 && clusterB >= 0);
651 if (UBeDriven->isFixed())
653 if (fixedPlacementUnit2LocId.find(UBeDriven) == fixedPlacementUnit2LocId.end())
655 int amo = fixedPlacementUnit2LocId.size();
656 fixedPlacementUnit2LocId[UBeDriven] = amo;
659 fixedX.push_back(UBeDriven->X() + clockRegionW / 2.0);
660 fixedY.push_back(UBeDriven->Y());
664 fixedX.push_back(UBeDriven->X());
665 fixedY.push_back(UBeDriven->Y());
670 if (net->getPinOffsetsInUnit().size() > 1)
672 if (UBeDriven->isFixed() && !driveU->isFixed())
674 assert(fixedPlacementUnit2LocId.find(UBeDriven) != fixedPlacementUnit2LocId.end());
675 assert((
unsigned int)fixedPlacementUnit2LocId[UBeDriven] <
678 net->getDesignNet()->getOverallEnhanceRatio() / (net->getPinOffsetsInUnit().size() - 1);
680 else if (!UBeDriven->isFixed() && driveU->isFixed())
682 assert(fixedPlacementUnit2LocId.find(driveU) != fixedPlacementUnit2LocId.end());
685 net->getDesignNet()->getOverallEnhanceRatio() / (net->getPinOffsetsInUnit().size() - 1);
687 else if (!UBeDriven->isFixed() && !driveU->isFixed())
690 net->getDesignNet()->getOverallEnhanceRatio() / (net->getPinOffsetsInUnit().size() - 1);
692 net->getDesignNet()->getOverallEnhanceRatio() / (net->getPinOffsetsInUnit().size() - 1);
701 int PUId = curPU->getId();
715 int gridH = std::stoi(
JSONCfg[
"clockRegionYNum"]);
716 int gridW = std::stoi(
JSONCfg[
"clockRegionXNum"]);
717 int SAIterNum = 100000;
721 SAIterNum = std::stoi(
JSONCfg[
"Simulated Annealing IterNum"]);
722 if (
JSONCfg.find(
"Simulated Annealing restartNum") !=
JSONCfg.end())
723 restartNum = std::stoi(
JSONCfg[
"Simulated Annealing restartNum"]);
742 int gridH = std::stoi(
JSONCfg[
"clockRegionYNum"]);
743 int gridW = std::stoi(
JSONCfg[
"clockRegionXNum"]);
748 float regionW = deviceW / gridW;
749 float regionH = deviceH / gridH;
754 float fX = intXY.first * regionW + regionW / 2;
755 float fY = intXY.second * regionH + regionH / 2;
763 if (!curPU->isFixed())
772 curPU->setAnchorLocation(fX, fY);
779 std::string dumpClustersFile =
JSONCfg[
"Dump Cluster file"];
780 if (dumpClustersFile !=
"")
782 print_status(
"dumping cluster information to " + dumpClustersFile);
783 std::ofstream outfile0((dumpClustersFile +
".tcl").c_str());
784 assert(outfile0.is_open() && outfile0.good() &&
785 "The path for cluster result dumping does not exist and please check your path settings");
786 for (
unsigned int cluster_id = 0; cluster_id <
clusters.size(); cluster_id++)
788 outfile0 <<
"# placed at region coordinate: X " <<
cluster2XY[cluster_id].first <<
" Y "
790 outfile0 <<
"highlight -color_index " << (cluster_id) % 20 + 1 <<
" [get_cells {";
796 for (
auto cell : tmpMacro->getCells())
798 outfile0 << cell->getName() <<
" ";
804 outfile0 << tmpUnpacked->getName() <<
" ";
814 outfile0 = std::ofstream(dumpClustersFile.c_str());
815 for (
unsigned int cluster_id = 0; cluster_id <
clusters.size(); cluster_id++)
822 for (
auto cell : tmpMacro->getCells())
824 outfile0 << cell->getName() <<
" ";
830 outfile0 << tmpUnpacked->getName() <<
" ";
845 std::vector<std::pair<int, int>>
lines;
847 for (
unsigned int clusterA = 1; clusterA <
clusterAdjMat.size(); clusterA++)
848 for (
unsigned int clusterB = 0; clusterB < clusterA; clusterB++)
852 lines.push_back(std::pair<int, int>(clusterA, clusterB));