Skip to content

Commit

Permalink
Merge pull request The-OpenROAD-Project#4790 from gadfort/pdn-rtree
Browse files Browse the repository at this point in the history
pdn: switch initial building of rtrees to vectors and use bulk loading
  • Loading branch information
maliberty authored Mar 15, 2024
2 parents f1a4087 + 5674cb7 commit 1609be4
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 88 deletions.
47 changes: 28 additions & 19 deletions src/pdn/src/PdnGen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,34 @@ void PdnGen::buildGrids(bool trim)
insts_in_grids.insert(insts_in_grid.begin(), insts_in_grid.end());
}

ShapeTreeMap block_obs;
Grid::makeInitialObstructions(block, block_obs, insts_in_grids, logger_);
ShapeVectorMap block_obs_vec;
Grid::makeInitialObstructions(block, block_obs_vec, insts_in_grids, logger_);
for (auto* grid : grids) {
grid->getGridLevelObstructions(block_obs);
grid->getGridLevelObstructions(block_obs_vec);
}
ShapeTreeMap all_shapes;
ShapeVectorMap all_shapes_vec;

// get special shapes
Grid::makeInitialShapes(block, all_shapes, logger_);
for (const auto& [layer, layer_shapes] : all_shapes) {
auto& layer_obs = block_obs[layer];
Grid::makeInitialShapes(block, all_shapes_vec, logger_);
for (const auto& [layer, layer_shapes] : all_shapes_vec) {
auto& layer_obs = block_obs_vec[layer];
for (const auto& [box, shape] : layer_shapes) {
layer_obs.insert({shape->getObstructionBox(), shape});
layer_obs.emplace_back(shape->getObstructionBox(), shape);
}
}

ShapeTreeMap block_obs;
for (const auto& [layer, shapes] : block_obs_vec) {
block_obs[layer] = ShapeTree(shapes.begin(), shapes.end());
}
block_obs_vec.clear();

ShapeTreeMap all_shapes;
for (const auto& [layer, shapes] : all_shapes_vec) {
all_shapes[layer] = ShapeTree(shapes.begin(), shapes.end());
}
all_shapes_vec.clear();

for (auto* grid : grids) {
debugPrint(
logger_, utl::PDN, "Make", 2, "Build start grid - {}", grid->getName());
Expand Down Expand Up @@ -754,17 +766,12 @@ void PdnGen::writeToDb(bool add_pins, const std::string& report_file) const

// collect all the SWires from the block
auto* block = db_->getChip()->getBlock();
ShapeTreeMap obstructions;
ShapeVectorMap net_shapes_vec;
for (auto* net : block->getNets()) {
ShapeTreeMap net_shapes;
Shape::populateMapFromDb(net, net_shapes);
for (const auto& [layer, net_obs_layer] : net_shapes) {
auto& obs_layer = obstructions[layer];
for (const auto& [box, shape] : net_obs_layer) {
obs_layer.insert({shape->getObstructionBox(), shape});
}
}
Shape::populateMapFromDb(net, net_shapes_vec);
}
const ShapeTreeMap obstructions(net_shapes_vec.begin(), net_shapes_vec.end());
net_shapes_vec.clear();

for (auto* domain : domains) {
for (const auto& grid : domain->getGrids()) {
Expand Down Expand Up @@ -812,8 +819,10 @@ void PdnGen::ripUp(odb::dbNet* net)
return;
}

ShapeTreeMap net_shapes;
Shape::populateMapFromDb(net, net_shapes);
ShapeVectorMap net_shapes_vec;
Shape::populateMapFromDb(net, net_shapes_vec);
ShapeTreeMap net_shapes = Shape::convertVectorToTree(net_shapes_vec);

// remove bterms that connect to swires
std::set<odb::dbBTerm*> terms;
for (auto* bterm : net->getBTerms()) {
Expand Down
68 changes: 37 additions & 31 deletions src/pdn/src/grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,17 @@ bool Grid::repairVias(const ShapeTreeMap& global_shapes,

ShapeTreeMap Grid::getShapes() const
{
ShapeTreeMap shapes;
ShapeVectorMap shapes;

for (auto* component : getGridComponents()) {
for (const auto& [layer, component_shapes] : component->getShapes()) {
auto& layer_shapes = shapes[layer];
for (const auto& shape : component_shapes) {
layer_shapes.insert(shape);
}
shapes[layer].insert(shapes[layer].end(),
component_shapes.begin(),
component_shapes.end());
}
}

return shapes;
return Shape::convertVectorToTree(shapes);
}

odb::Rect Grid::getDomainArea() const
Expand Down Expand Up @@ -903,7 +902,7 @@ void Grid::writeToDb(const std::map<odb::dbNet*, odb::dbSWire*>& net_map,
}
}

void Grid::getGridLevelObstructions(ShapeTreeMap& obstructions) const
void Grid::getGridLevelObstructions(ShapeVectorMap& obstructions) const
{
debugPrint(getLogger(),
utl::PDN,
Expand Down Expand Up @@ -934,7 +933,7 @@ void Grid::getGridLevelObstructions(ShapeTreeMap& obstructions) const
"Adding obstruction on layer {} covering {}",
layer->getName(),
Shape::getRectText(core, getBlock()->getDbUnitsPerMicron()));
obstructions[layer].insert({obs->getObstructionBox(), obs});
obstructions[layer].emplace_back(obs->getObstructionBox(), obs);
}

for (const auto& ring : rings_) {
Expand All @@ -957,13 +956,13 @@ void Grid::getGridLevelObstructions(ShapeTreeMap& obstructions) const
"Adding obstruction on layer {} covering {}",
layer->getName(),
Shape::getRectText(ring_rect, getBlock()->getDbUnitsPerMicron()));
obstructions[layer].insert({obs->getObstructionBox(), obs});
obstructions[layer].emplace_back(obs->getObstructionBox(), obs);
}
}
}

void Grid::makeInitialObstructions(odb::dbBlock* block,
ShapeTreeMap& obs,
ShapeVectorMap& obs,
const std::set<odb::dbInst*>& skip_insts,
utl::Logger* logger)
{
Expand All @@ -983,13 +982,13 @@ void Grid::makeInitialObstructions(odb::dbBlock* block,
if (box->getTechLayer() == nullptr) {
for (auto* layer : block->getDb()->getTech()->getLayers()) {
auto shape = std::make_shared<Shape>(layer, obs_rect, Shape::BLOCK_OBS);
obs[shape->getLayer()].insert({shape->getObstructionBox(), shape});
obs[shape->getLayer()].emplace_back(shape->getObstructionBox(), shape);
}
} else {
auto shape = std::make_shared<Shape>(
box->getTechLayer(), obs_rect, Shape::BLOCK_OBS);

obs[shape->getLayer()].insert({shape->getObstructionBox(), shape});
obs[shape->getLayer()].emplace_back(shape->getObstructionBox(), shape);
}
}

Expand Down Expand Up @@ -1030,14 +1029,14 @@ void Grid::makeInitialObstructions(odb::dbBlock* block,

for (const auto& [layer, shapes] :
InstanceGrid::getInstanceObstructions(inst)) {
obs[layer].insert(shapes.begin(), shapes.end());
obs[layer].insert(obs[layer].end(), shapes.begin(), shapes.end());
}
}
debugPrint(logger, utl::PDN, "Make", 2, "Get initial obstructions - end");
}

void Grid::makeInitialShapes(odb::dbBlock* block,
ShapeTreeMap& shapes,
ShapeVectorMap& shapes,
utl::Logger* logger)
{
debugPrint(logger, utl::PDN, "Make", 2, "Get initial shapes - start");
Expand Down Expand Up @@ -1185,7 +1184,7 @@ void CoreGrid::setupDirectConnect(
}
}

void CoreGrid::getGridLevelObstructions(ShapeTreeMap& obstructions) const
void CoreGrid::getGridLevelObstructions(ShapeVectorMap& obstructions) const
{
if (getDomain()->hasRegion()) {
// core grids only have grid level obstructions if they have a region
Expand Down Expand Up @@ -1345,11 +1344,11 @@ odb::Rect InstanceGrid::getGridBoundary() const
return getDomainBoundary();
}

ShapeTreeMap InstanceGrid::getInstanceObstructions(
ShapeVectorMap InstanceGrid::getInstanceObstructions(
odb::dbInst* inst,
const InstanceGrid::Halo& halo)
{
ShapeTreeMap obs;
ShapeVectorMap obs;

const odb::dbTransform transform = inst->getTransform();

Expand All @@ -1368,7 +1367,7 @@ ShapeTreeMap InstanceGrid::getInstanceObstructions(
transform.apply(obs_rect);
auto shape = std::make_shared<Shape>(layer, obs_rect, Shape::BLOCK_OBS);

obs[layer].insert({shape->getObstructionBox(), shape});
obs[layer].emplace_back(shape->getObstructionBox(), shape);
}

// generate obstructions based on pins
Expand All @@ -1383,41 +1382,42 @@ ShapeTreeMap InstanceGrid::getInstanceObstructions(
pin_shape->setRect(applyHalo(
pin_shape->getObstruction(), halo, true, is_horizontal, is_vertical));
pin_shape->setObstruction(pin_shape->getRect());
obs[layer].insert({pin_shape->getObstructionBox(), pin_shape});
obs[layer].emplace_back(pin_shape->getObstructionBox(), pin_shape);
}
}

return obs;
}

void InstanceGrid::getGridLevelObstructions(ShapeTreeMap& obstructions) const
void InstanceGrid::getGridLevelObstructions(ShapeVectorMap& obstructions) const
{
ShapeTreeMap local_obs;
ShapeVectorMap local_obs;
Grid::getGridLevelObstructions(local_obs);

const odb::Rect inst_box = getGridArea();

// copy layer obs
for (const auto& [layer, shapes] : local_obs) {
auto obs = std::make_shared<GridObsShape>(layer, inst_box, this);
local_obs[layer].insert({obs->getObstructionBox(), obs});
local_obs[layer].emplace_back(obs->getObstructionBox(), obs);
}

// copy instance obstructions
for (const auto& [layer, shapes] : getInstanceObstructions(inst_, halos_)) {
for (const auto& [box, shape] : shapes) {
auto obs = std::make_shared<GridObsShape>(layer, shape->getRect(), this);
local_obs[layer].insert({box, obs});
local_obs[layer].emplace_back(box, obs);
}
}

// merge local and global obs
for (const auto& [layer, obs] : local_obs) {
obstructions[layer].insert(obs.begin(), obs.end());
obstructions[layer].insert(
obstructions[layer].end(), obs.begin(), obs.end());
}
}

ShapeTreeMap InstanceGrid::getInstancePins(odb::dbInst* inst)
ShapeVectorMap InstanceGrid::getInstancePins(odb::dbInst* inst)
{
// add instance pins
std::vector<ShapePtr> pins;
Expand Down Expand Up @@ -1454,9 +1454,9 @@ ShapeTreeMap InstanceGrid::getInstancePins(odb::dbInst* inst)
}
}

ShapeTreeMap shapes;
ShapeVectorMap shapes;
for (auto& pin : pins) {
shapes[pin->getLayer()].insert({pin->getRectBox(), pin});
shapes[pin->getLayer()].emplace_back(pin->getRectBox(), pin);
}

return shapes;
Expand Down Expand Up @@ -1562,7 +1562,8 @@ bool BumpGrid::isRouted() const
{
odb::dbNet* net = *getNets(startsWithPower()).begin();

const auto pins = InstanceGrid::getInstancePins(getInstance());
auto inst_pins = InstanceGrid::getInstancePins(getInstance());
const auto pins = Shape::convertVectorToTree(inst_pins);

for (auto* swire : net->getSWires()) {
for (auto* sbox : swire->getWires()) {
Expand Down Expand Up @@ -1660,15 +1661,20 @@ ExistingGrid::ExistingGrid(

void ExistingGrid::populate()
{
Grid::makeInitialShapes(domain_->getBlock(), shapes_, getLogger());
ShapeVectorMap shapes;
Grid::makeInitialShapes(domain_->getBlock(), shapes, getLogger());

for (auto* inst : getBlock()->getInsts()) {
if (inst->getPlacementStatus().isFixed()) {
for (const auto& [layer, shapes] : InstanceGrid::getInstancePins(inst)) {
shapes_[layer].insert(shapes.begin(), shapes.end());
for (const auto& [layer, inst_shapes] :
InstanceGrid::getInstancePins(inst)) {
shapes[layer].insert(
shapes[layer].end(), inst_shapes.begin(), inst_shapes.end());
}
}
}

shapes_ = Shape::convertVectorToTree(shapes);
}

void ExistingGrid::addRing(std::unique_ptr<Rings> ring)
Expand Down
17 changes: 9 additions & 8 deletions src/pdn/src/grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class Grid

// returns the obstructions the other grids should be aware of,
// such as the outline of an instance or layers in use
virtual void getGridLevelObstructions(ShapeTreeMap& obstructions) const;
virtual void getGridLevelObstructions(ShapeVectorMap& obstructions) const;
void getObstructions(ShapeTreeMap& obstructions) const;

void resetShapes();
Expand All @@ -180,11 +180,11 @@ class Grid
void makeRoutingObstructions(odb::dbBlock* block) const;

static void makeInitialObstructions(odb::dbBlock* block,
ShapeTreeMap& obs,
ShapeVectorMap& obs,
const std::set<odb::dbInst*>& skip_insts,
utl::Logger* logger);
static void makeInitialShapes(odb::dbBlock* block,
ShapeTreeMap& shapes,
ShapeVectorMap& shapes,
utl::Logger* logger);

virtual bool isReplaceable() const { return false; }
Expand Down Expand Up @@ -246,7 +246,7 @@ class CoreGrid : public Grid
void setupDirectConnect(
const std::vector<odb::dbTechLayer*>& connect_pad_layers);

void getGridLevelObstructions(ShapeTreeMap& obstructions) const override;
void getGridLevelObstructions(ShapeVectorMap& obstructions) const override;

protected:
void cleanupShapes() override;
Expand Down Expand Up @@ -280,16 +280,17 @@ class InstanceGrid : public Grid
odb::Rect getDomainBoundary() const override;
odb::Rect getGridBoundary() const override;

void getGridLevelObstructions(ShapeTreeMap& obstructions) const override;
void getGridLevelObstructions(ShapeVectorMap& obstructions) const override;

void setReplaceable(bool replaceable) { replaceable_ = replaceable; }
bool isReplaceable() const override { return replaceable_; }

virtual bool isValid() const;

static ShapeTreeMap getInstanceObstructions(odb::dbInst* inst,
const Halo& halo = {0, 0, 0, 0});
static ShapeTreeMap getInstancePins(odb::dbInst* inst);
static ShapeVectorMap getInstanceObstructions(odb::dbInst* inst,
const Halo& halo
= {0, 0, 0, 0});
static ShapeVectorMap getInstancePins(odb::dbInst* inst);

protected:
// find all intersections that also overlap with the power/ground pins based
Expand Down
Loading

0 comments on commit 1609be4

Please sign in to comment.