Skip to content

Commit 6ff8cb4

Browse files
authored
Merge pull request #7958 from The-OpenROAD-Project-staging/dpl-site-intervals
dpl: remove sites from Pixel and store as an interval
2 parents 5479639 + e06ec1e commit 6ff8cb4

File tree

10 files changed

+108
-40
lines changed

10 files changed

+108
-40
lines changed

src/dpl/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ cc_library(
8686
"//src/utl",
8787
"@boost.format",
8888
"@boost.geometry",
89+
"@boost.icl",
8990
"@boost.polygon",
9091
"@boost.property_tree",
9192
"@boost.random",
@@ -126,6 +127,7 @@ cc_library(
126127
"//src/odb",
127128
"//src/utl",
128129
"@boost.geometry",
130+
"@boost.icl",
129131
"@boost.polygon",
130132
"@boost.stacktrace",
131133
"@boost.utility",

src/dpl/include/dpl/Opendp.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ class Opendp
284284
void placeRowFillers(GridY row,
285285
const std::string& prefix,
286286
const MasterByImplant& filler_masters);
287-
std::pair<odb::dbSite*, odb::dbOrientType> fillSite(Pixel* pixel);
288287
static bool isFiller(odb::dbInst* db_inst);
289288
bool isOneSiteCell(odb::dbMaster* db_master) const;
290289
const char* gridInstName(GridY row, GridX col);

src/dpl/src/CheckPlacement.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,7 @@ bool Opendp::checkInRows(const Node& cell) const
344344
if (pixel == nullptr || !pixel->is_valid) {
345345
return false;
346346
}
347-
if (first_row
348-
&& pixel->sites.find(cell.getSite()) == pixel->sites.end()) {
347+
if (first_row && !grid_->getSiteOrientation(x, y, cell.getSite())) {
349348
return false;
350349
}
351350
}

src/dpl/src/DecapPlacement.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ void Opendp::insertDecapInPos(dbMaster* master,
208208
/* physical_only */ true);
209209
const GridX grid_x = grid_->gridX(pos_x - core_.xMin());
210210
const GridY grid_y = grid_->gridSnapDownY(pos_y - core_.yMin());
211-
const Pixel* pixel = grid_->gridPixel(grid_x, grid_y);
212-
const dbOrientType orient = pixel->sites.at(master->getSite());
211+
const dbOrientType orient
212+
= grid_->getSiteOrientation(grid_x, grid_y, master->getSite()).value();
213213
inst->setOrient(orient);
214214
inst->setLocation(pos_x.v, pos_y.v);
215215
inst->setPlacementStatus(dbPlacementStatus::PLACED);

src/dpl/src/FillerPlacement.cpp

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -112,24 +112,6 @@ void Opendp::setGridCells()
112112
}
113113
}
114114

115-
// Select the site and orientation to fill this row with. Use the shortest
116-
// site.
117-
std::pair<dbSite*, dbOrientType> Opendp::fillSite(Pixel* pixel)
118-
{
119-
dbSite* selected_site = nullptr;
120-
dbOrientType selected_orient;
121-
DbuY min_height{std::numeric_limits<int>::max()};
122-
for (const auto& [site, orient] : pixel->sites) {
123-
DbuY site_height{site->getHeight()};
124-
if (site_height < min_height) {
125-
min_height = site_height;
126-
selected_site = site;
127-
selected_orient = orient;
128-
}
129-
}
130-
return {selected_site, selected_orient};
131-
}
132-
133115
void Opendp::placeRowFillers(GridY row,
134116
const std::string& prefix,
135117
const MasterByImplant& filler_masters_by_implant)
@@ -145,7 +127,9 @@ void Opendp::placeRowFillers(GridY row,
145127
++j;
146128
continue;
147129
}
148-
auto [site, orient] = fillSite(pixel);
130+
// Select the site and orientation to fill this row with. Use the shortest
131+
// site.
132+
auto [site, orient] = grid_->getShortestSite(j, row);
149133
GridX k = j;
150134
while (k < row_site_count && grid_->gridPixel(k, row)->cell == nullptr
151135
&& grid_->gridPixel(k, row)->is_valid) {

src/dpl/src/Place.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ bool Opendp::checkPixels(const Node* cell,
872872
if (pixel == nullptr || pixel->cell || !pixel->is_valid
873873
|| (cell->inGroup() && pixel->group != cell->getGroup())
874874
|| (!cell->inGroup() && pixel->group)
875-
|| (first_row && pixel->sites.find(site) == pixel->sites.end())) {
875+
|| (first_row && !grid_->getSiteOrientation(x1, y1, site))) {
876876
return false;
877877
}
878878
}
@@ -908,8 +908,8 @@ bool Opendp::checkPixels(const Node* cell,
908908
}
909909
}
910910
}
911-
const auto& orient = grid_->gridPixel(x, y)->sites.at(
912-
cell->getDbInst()->getMaster()->getSite());
911+
dbSite* site = cell->getDbInst()->getMaster()->getSite();
912+
const auto orient = grid_->getSiteOrientation(x, y, site).value();
913913
return drc_engine_->checkDRC(cell, x, y, orient);
914914
}
915915

@@ -1200,8 +1200,8 @@ void Opendp::placeCell(Node* cell, const GridX x, const GridY y)
12001200
setGridLoc(cell, x, y);
12011201
grid_->paintPixel(cell);
12021202
cell->setPlaced(true);
1203-
cell->setOrient(grid_->gridPixel(x, y)->sites.at(
1204-
cell->getDbInst()->getMaster()->getSite()));
1203+
dbSite* site = cell->getDbInst()->getMaster()->getSite();
1204+
cell->setOrient(grid_->getSiteOrientation(x, y, site).value());
12051205
if (journal_) {
12061206
MoveCellAction action(cell,
12071207
original_x,

src/dpl/src/infrastructure/Grid.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ void Grid::allocateGrid()
7676
pixel.blocked_layers = 0;
7777
}
7878
}
79+
80+
row_sites_.clear();
81+
row_sites_.resize(row_count_.v);
7982
}
8083

8184
void Grid::markHopeless(dbBlock* block,
@@ -101,8 +104,9 @@ void Grid::markHopeless(dbBlock* block,
101104
for (GridX x{x_start}; x < x_end; x++) {
102105
Pixel* pixel = gridPixel(x, y_row);
103106
pixel->is_valid = true;
104-
pixel->sites[db_row->getSite()] = db_row->getOrient();
105107
}
108+
row_sites_[y_row.v].add(
109+
{{x_start.v, x_end.v}, {{db_row->getSite(), db_row->getOrient()}}});
106110

107111
// The safety margin is to avoid having only a very few sites
108112
// within the diamond search that may still lead to failures.
@@ -211,6 +215,50 @@ void Grid::initGrid(dbDatabase* db,
211215
markBlocked(block);
212216
}
213217

218+
std::pair<dbSite*, dbOrientType> Grid::getShortestSite(GridX grid_x,
219+
GridY grid_y)
220+
{
221+
dbSite* selected_site = nullptr;
222+
dbOrientType selected_orient;
223+
DbuY min_height{std::numeric_limits<int>::max()};
224+
225+
const RowSitesMap& sites_map = row_sites_[grid_y.v];
226+
auto it = sites_map.find(grid_x.v);
227+
228+
if (it != sites_map.end()) {
229+
for (const auto& [site, orient] : it->second) {
230+
DbuY site_height{site->getHeight()};
231+
if (site_height < min_height) {
232+
min_height = site_height;
233+
selected_site = site;
234+
selected_orient = orient;
235+
}
236+
}
237+
}
238+
239+
return {selected_site, selected_orient};
240+
}
241+
242+
std::optional<dbOrientType> Grid::getSiteOrientation(GridX x,
243+
GridY y,
244+
dbSite* site) const
245+
{
246+
const RowSitesMap& sites_map = row_sites_[y.v];
247+
auto interval_it = sites_map.find(x.v);
248+
249+
if (interval_it == sites_map.end()) {
250+
return {};
251+
}
252+
253+
const SiteToOrientation& sites_orient = interval_it->second;
254+
255+
if (auto it = sites_orient.find(site); it != sites_orient.end()) {
256+
return it->second;
257+
}
258+
259+
return {};
260+
}
261+
214262
Pixel* Grid::gridPixel(GridX grid_x, GridY grid_y) const
215263
{
216264
if (grid_x >= 0 && grid_x < row_site_count_ && grid_y >= 0

src/dpl/src/infrastructure/Grid.h

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#pragma once
55

6+
#include <boost/icl/interval_map.hpp>
67
#include <functional>
78
#include <map>
89
#include <memory>
@@ -39,9 +40,8 @@ struct Pixel
3940
bool is_valid = false; // false for dummy cells
4041
bool is_hopeless = false; // too far from sites for diamond search
4142
uint8_t blocked_layers = 0;
42-
std::map<dbSite*, dbOrientType> sites;
43-
std::unordered_set<Node*>
44-
padding_reserved_by; // Cells that reserved this pixel for padding
43+
// Cells that reserved this pixel for padding
44+
std::unordered_set<Node*> padding_reserved_by;
4545
};
4646

4747
// Return value for grid searches.
@@ -132,6 +132,11 @@ class Grid
132132
Pixel& pixel(GridY y, GridX x) { return pixels_[y.v][x.v]; }
133133
const Pixel& pixel(GridY y, GridX x) const { return pixels_[y.v][x.v]; }
134134

135+
std::optional<dbOrientType> getSiteOrientation(GridX x,
136+
GridY y,
137+
dbSite* site) const;
138+
std::pair<dbSite*, dbOrientType> getShortestSite(GridX grid_x, GridY grid_y);
139+
135140
void resize(int size) { pixels_.resize(size); }
136141
void resize(GridY size) { pixels_.resize(size.v); }
137142
void resize(GridY y, GridX size) { pixels_[y.v].resize(size.v); }
@@ -147,14 +152,40 @@ class Grid
147152
bool isMultiHeight(dbMaster* master) const;
148153

149154
private:
155+
// Maps a site to the right orientation to use in a given row
156+
using SiteToOrientation = std::map<dbSite*, dbOrientType>;
157+
158+
// Used to combine the SiteToOrientation for two intervals when merged
159+
template <typename MapType>
160+
struct SitesCombiner
161+
{
162+
using first_argument_type = MapType&;
163+
using second_argument_type = const MapType&;
164+
165+
static MapType identity_element() { return MapType(); }
166+
167+
void operator()(MapType& target, const MapType& source) const
168+
{
169+
target.insert(source.begin(), source.end());
170+
}
171+
};
172+
173+
// Map intervals in rows to the site/orientation mapping
174+
using RowSitesMap = boost::icl::interval_map<int,
175+
SiteToOrientation,
176+
boost::icl::total_absorber,
177+
std::less,
178+
SitesCombiner>;
179+
180+
using Pixels = std::vector<std::vector<Pixel>>;
181+
150182
void markHopeless(dbBlock* block,
151183
int max_displacement_x,
152184
int max_displacement_y);
153185
void markBlocked(dbBlock* block);
154186
void visitDbRows(dbBlock* block,
155187
const std::function<void(odb::dbRow*)>& func) const;
156188

157-
using Pixels = std::vector<std::vector<Pixel>>;
158189
Logger* logger_ = nullptr;
159190
dbBlock* block_ = nullptr;
160191
std::shared_ptr<Padding> padding_;
@@ -165,6 +196,9 @@ class Grid
165196
std::vector<DbuY> row_index_to_y_dbu_; // index is GridY
166197
std::vector<DbuY> row_index_to_pixel_height_; // index is GridY
167198

199+
// Indexed by row (GridY)
200+
std::vector<RowSitesMap> row_sites_;
201+
168202
bool has_hybrid_rows_ = false;
169203
Rect core_;
170204

src/dpl/src/optimization/detailed_manager.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2985,9 +2985,10 @@ void DetailedMgr::paintInGrid(Node* node)
29852985
{
29862986
const auto grid_x = grid_->gridX(node);
29872987
const auto grid_y = grid_->gridSnapDownY(node);
2988-
auto pixel = grid_->gridPixel(grid_x, grid_y);
2988+
dbSite* site = node->getDbInst()->getMaster()->getSite();
2989+
const auto orientation
2990+
= grid_->getSiteOrientation(grid_x, grid_y, site).value();
29892991
grid_->paintPixel(node, grid_x, grid_y);
2990-
node->adjustCurrOrient(
2991-
pixel->sites.at(node->getDbInst()->getMaster()->getSite()));
2992+
node->adjustCurrOrient(orientation);
29922993
}
29932994
} // namespace dpl

src/dpl/src/util/journal.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ void paintInGrid(Grid* grid, Node* node)
1818
{
1919
const auto grid_x = grid->gridX(DbuX(node->getLeft()));
2020
const auto grid_y = grid->gridRoundY(DbuY(node->getBottom()));
21-
auto pixel = grid->gridPixel(grid_x, grid_y);
21+
dbSite* site = node->getDbInst()->getMaster()->getSite();
22+
const auto orientation
23+
= grid->getSiteOrientation(grid_x, grid_y, site).value();
2224
grid->paintPixel(node, grid_x, grid_y);
23-
node->adjustCurrOrient(
24-
pixel->sites.at(node->getDbInst()->getMaster()->getSite()));
25+
node->adjustCurrOrient(orientation);
2526
}
2627

2728
}; // namespace

0 commit comments

Comments
 (0)