From 551f0f7cecbdb424712fd839bd16a1cda983fd68 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Wed, 13 Mar 2024 22:36:37 -0400 Subject: [PATCH 1/3] pdn: switch initial building of rtrees to vectors and use bulk loading Signed-off-by: Peter Gadfort --- src/pdn/src/PdnGen.cc | 48 +++++++++++++++++----------- src/pdn/src/grid.cpp | 68 ++++++++++++++++++++++------------------ src/pdn/src/grid.h | 17 +++++----- src/pdn/src/renderer.cpp | 35 ++++++++++----------- src/pdn/src/shape.cpp | 21 +++++++++++-- src/pdn/src/shape.h | 6 +++- src/pdn/src/sroute.cpp | 14 +++------ 7 files changed, 121 insertions(+), 88 deletions(-) diff --git a/src/pdn/src/PdnGen.cc b/src/pdn/src/PdnGen.cc index 63b0d765a46..47b84d9effa 100644 --- a/src/pdn/src/PdnGen.cc +++ b/src/pdn/src/PdnGen.cc @@ -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()); @@ -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()) { @@ -812,8 +819,11 @@ 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); + net_shapes_vec.clear(); + // remove bterms that connect to swires std::set terms; for (auto* bterm : net->getBTerms()) { diff --git a/src/pdn/src/grid.cpp b/src/pdn/src/grid.cpp index c848afa9207..af247ac44c7 100644 --- a/src/pdn/src/grid.cpp +++ b/src/pdn/src/grid.cpp @@ -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 @@ -903,7 +902,7 @@ void Grid::writeToDb(const std::map& net_map, } } -void Grid::getGridLevelObstructions(ShapeTreeMap& obstructions) const +void Grid::getGridLevelObstructions(ShapeVectorMap& obstructions) const { debugPrint(getLogger(), utl::PDN, @@ -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_) { @@ -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& skip_insts, utl::Logger* logger) { @@ -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(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( box->getTechLayer(), obs_rect, Shape::BLOCK_OBS); - obs[shape->getLayer()].insert({shape->getObstructionBox(), shape}); + obs[shape->getLayer()].emplace_back(shape->getObstructionBox(), shape); } } @@ -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"); @@ -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 @@ -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(); @@ -1368,7 +1367,7 @@ ShapeTreeMap InstanceGrid::getInstanceObstructions( transform.apply(obs_rect); auto shape = std::make_shared(layer, obs_rect, Shape::BLOCK_OBS); - obs[layer].insert({shape->getObstructionBox(), shape}); + obs[layer].emplace_back(shape->getObstructionBox(), shape); } // generate obstructions based on pins @@ -1383,16 +1382,16 @@ 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(); @@ -1400,24 +1399,25 @@ void InstanceGrid::getGridLevelObstructions(ShapeTreeMap& obstructions) const // copy layer obs for (const auto& [layer, shapes] : local_obs) { auto obs = std::make_shared(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(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 pins; @@ -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; @@ -1562,7 +1562,8 @@ bool BumpGrid::isRouted() const { odb::dbNet* net = *getNets(startsWithPower()).begin(); - const auto pins = InstanceGrid::getInstancePins(getInstance()); + const auto pins = Shape::convertVectorToTree( + InstanceGrid::getInstancePins(getInstance())); for (auto* swire : net->getSWires()) { for (auto* sbox : swire->getWires()) { @@ -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 ring) diff --git a/src/pdn/src/grid.h b/src/pdn/src/grid.h index ac701995f00..0e499c2cda6 100644 --- a/src/pdn/src/grid.h +++ b/src/pdn/src/grid.h @@ -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(); @@ -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& skip_insts, utl::Logger* logger); static void makeInitialShapes(odb::dbBlock* block, - ShapeTreeMap& shapes, + ShapeVectorMap& shapes, utl::Logger* logger); virtual bool isReplaceable() const { return false; } @@ -246,7 +246,7 @@ class CoreGrid : public Grid void setupDirectConnect( const std::vector& connect_pad_layers); - void getGridLevelObstructions(ShapeTreeMap& obstructions) const override; + void getGridLevelObstructions(ShapeVectorMap& obstructions) const override; protected: void cleanupShapes() override; @@ -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 diff --git a/src/pdn/src/renderer.cpp b/src/pdn/src/renderer.cpp index 069f04975d3..06be6acb2af 100644 --- a/src/pdn/src/renderer.cpp +++ b/src/pdn/src/renderer.cpp @@ -74,32 +74,26 @@ void PDNRenderer::update() vias_.clear(); repair_.clear(); + ShapeVectorMap shapes; + ShapeVectorMap obs; + std::vector vias; for (const auto& domain : pdn_->getDomains()) { for (auto* net : domain->getBlock()->getNets()) { - ShapeTreeMap net_shapes; - Shape::populateMapFromDb(net, net_shapes); - for (const auto& [layer, net_obs_layer] : net_shapes) { - auto& obs_layer = grid_obstructions_[layer]; - for (const auto& [box, shape] : net_obs_layer) { - obs_layer.insert({shape->getObstructionBox(), shape}); - } - } + Shape::populateMapFromDb(net, obs); } for (const auto& grid : domain->getGrids()) { - grid->getGridLevelObstructions(grid_obstructions_); + grid->getGridLevelObstructions(obs); - for (const auto& [layer, shapes] : grid->getShapes()) { - auto& save_shapes = shapes_[layer]; - for (const auto& shape : shapes) { - save_shapes.insert(shape); - } + for (const auto& [layer, grid_shapes] : grid->getShapes()) { + shapes[layer].insert( + shapes[layer].end(), grid_shapes.begin(), grid_shapes.end()); } - std::vector vias; - grid->getVias(vias); - for (const auto& via : vias) { - vias_.insert({via->getBox(), via}); + std::vector grid_vias; + grid->getVias(grid_vias); + for (auto& via : grid_vias) { + vias.emplace_back(via->getBox(), via); } for (const auto& repair : @@ -125,6 +119,11 @@ void PDNRenderer::update() } } + shapes_ = Shape::convertVectorToTree(shapes); + grid_obstructions_ = Shape::convertVectorToTree(obs); + shapes_ = Shape::convertVectorToTree(shapes); + vias_ = Shape::convertVectorToTree(vias); + redraw(); } diff --git a/src/pdn/src/shape.cpp b/src/pdn/src/shape.cpp index 538428e1192..67ed7852632 100644 --- a/src/pdn/src/shape.cpp +++ b/src/pdn/src/shape.cpp @@ -444,7 +444,7 @@ void Shape::addBPinToDb(const odb::Rect& rect) const pin->setPlacementStatus(odb::dbPlacementStatus::FIRM); } -void Shape::populateMapFromDb(odb::dbNet* net, ShapeTreeMap& map) +void Shape::populateMapFromDb(odb::dbNet* net, ShapeVectorMap& map) { for (auto* swire : net->getSWires()) { for (auto* box : swire->getWires()) { @@ -464,7 +464,7 @@ void Shape::populateMapFromDb(odb::dbNet* net, ShapeTreeMap& map) shape->setShapeType(Shape::OBS); } shape->generateObstruction(); - map[layer].insert({shape->getRectBox(), shape}); + map[layer].emplace_back(shape->getRectBox(), shape); } } } @@ -617,6 +617,23 @@ Shape* Shape::extendTo( return new_shape.release(); } +ShapeTreeMap Shape::convertVectorToTree(const ShapeVectorMap& vec) +{ + ShapeTreeMap trees; + + for (auto& [layer, vals] : vec) { + trees[layer] = ShapeTree(vals.begin(), vals.end()); + } + + return trees; +} + +ViaTree Shape::convertVectorToTree(const std::vector& vec) +{ + ViaTree tree(vec.begin(), vec.end()); + return tree; +} + ///////// FollowPinShape::FollowPinShape(odb::dbTechLayer* layer, diff --git a/src/pdn/src/shape.h b/src/pdn/src/shape.h index be3d6c6cd15..12a1436e6b6 100644 --- a/src/pdn/src/shape.h +++ b/src/pdn/src/shape.h @@ -77,6 +77,7 @@ using ViaValue = std::pair; using ShapeTree = bgi::rtree>; using ViaTree = bgi::rtree>; using ShapeTreeMap = std::map; +using ShapeVectorMap = std::map>; class Grid; class GridComponent; @@ -221,7 +222,7 @@ class Shape bool add_pins, bool make_rect_as_pin) const; // copy existing shapes into the map - static void populateMapFromDb(odb::dbNet* net, ShapeTreeMap& map); + static void populateMapFromDb(odb::dbNet* net, ShapeVectorMap& map); static Box rectToBox(const odb::Rect& rect); @@ -234,6 +235,9 @@ class Shape allow_non_preferred_change_ = true; } + static ShapeTreeMap convertVectorToTree(const ShapeVectorMap& vec); + static ViaTree convertVectorToTree(const std::vector& vec); + protected: bool cut(const ShapeTree& obstructions, std::vector& replacements, diff --git a/src/pdn/src/sroute.cpp b/src/pdn/src/sroute.cpp index 998cda564ee..89ed21f6182 100644 --- a/src/pdn/src/sroute.cpp +++ b/src/pdn/src/sroute.cpp @@ -666,15 +666,11 @@ void SRoute::createSrouteWires( auto domains = getDomains(); // collect the the SWires from the block - ShapeTreeMap obstructions; - 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}); - } - } + ShapeVectorMap obstructions_vec; + Shape::populateMapFromDb(net, obstructions_vec); + const ShapeTreeMap obstructions + = Shape::convertVectorToTree(obstructions_vec); + obstructions_vec.clear(); for (auto* domain : domains) { for (const auto& grid : domain->getGrids()) { From 4fdf971b1071f0786b35a7a92d349e6527af867d Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Thu, 14 Mar 2024 18:06:47 -0400 Subject: [PATCH 2/3] pdn: ensure vectors are re-initialized Signed-off-by: Peter Gadfort --- src/pdn/src/PdnGen.cc | 1 - src/pdn/src/grid.cpp | 4 ++-- src/pdn/src/shape.cpp | 9 +++++++-- src/pdn/src/shape.h | 4 ++-- src/pdn/src/sroute.cpp | 1 - 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/pdn/src/PdnGen.cc b/src/pdn/src/PdnGen.cc index 47b84d9effa..20f682f82e3 100644 --- a/src/pdn/src/PdnGen.cc +++ b/src/pdn/src/PdnGen.cc @@ -822,7 +822,6 @@ void PdnGen::ripUp(odb::dbNet* net) ShapeVectorMap net_shapes_vec; Shape::populateMapFromDb(net, net_shapes_vec); ShapeTreeMap net_shapes = Shape::convertVectorToTree(net_shapes_vec); - net_shapes_vec.clear(); // remove bterms that connect to swires std::set terms; diff --git a/src/pdn/src/grid.cpp b/src/pdn/src/grid.cpp index af247ac44c7..646b7cae99d 100644 --- a/src/pdn/src/grid.cpp +++ b/src/pdn/src/grid.cpp @@ -1562,8 +1562,8 @@ bool BumpGrid::isRouted() const { odb::dbNet* net = *getNets(startsWithPower()).begin(); - const auto pins = Shape::convertVectorToTree( - 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()) { diff --git a/src/pdn/src/shape.cpp b/src/pdn/src/shape.cpp index 67ed7852632..b874dac6a73 100644 --- a/src/pdn/src/shape.cpp +++ b/src/pdn/src/shape.cpp @@ -617,7 +617,7 @@ Shape* Shape::extendTo( return new_shape.release(); } -ShapeTreeMap Shape::convertVectorToTree(const ShapeVectorMap& vec) +ShapeTreeMap Shape::convertVectorToTree(ShapeVectorMap& vec) { ShapeTreeMap trees; @@ -625,12 +625,17 @@ ShapeTreeMap Shape::convertVectorToTree(const ShapeVectorMap& vec) trees[layer] = ShapeTree(vals.begin(), vals.end()); } + vec = ShapeVectorMap(); + return trees; } -ViaTree Shape::convertVectorToTree(const std::vector& vec) +ViaTree Shape::convertVectorToTree(std::vector& vec) { ViaTree tree(vec.begin(), vec.end()); + + vec = std::vector(); + return tree; } diff --git a/src/pdn/src/shape.h b/src/pdn/src/shape.h index 12a1436e6b6..d70fc7e63b7 100644 --- a/src/pdn/src/shape.h +++ b/src/pdn/src/shape.h @@ -235,8 +235,8 @@ class Shape allow_non_preferred_change_ = true; } - static ShapeTreeMap convertVectorToTree(const ShapeVectorMap& vec); - static ViaTree convertVectorToTree(const std::vector& vec); + static ShapeTreeMap convertVectorToTree(ShapeVectorMap& vec); + static ViaTree convertVectorToTree(std::vector& vec); protected: bool cut(const ShapeTree& obstructions, diff --git a/src/pdn/src/sroute.cpp b/src/pdn/src/sroute.cpp index 89ed21f6182..dea8bdf9a87 100644 --- a/src/pdn/src/sroute.cpp +++ b/src/pdn/src/sroute.cpp @@ -670,7 +670,6 @@ void SRoute::createSrouteWires( Shape::populateMapFromDb(net, obstructions_vec); const ShapeTreeMap obstructions = Shape::convertVectorToTree(obstructions_vec); - obstructions_vec.clear(); for (auto* domain : domains) { for (const auto& grid : domain->getGrids()) { From 5674cb7b59b0e04b013751e4b3fa13fa318e8533 Mon Sep 17 00:00:00 2001 From: Matt Liberty Date: Thu, 14 Mar 2024 15:33:28 -0700 Subject: [PATCH 3/3] pdn: use swap in Shape::convertVectorToTree Assignment doesn't guarantee a capacity reduction. Signed-off-by: Matt Liberty --- src/pdn/src/shape.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pdn/src/shape.cpp b/src/pdn/src/shape.cpp index b874dac6a73..c8875f7d0d0 100644 --- a/src/pdn/src/shape.cpp +++ b/src/pdn/src/shape.cpp @@ -625,7 +625,8 @@ ShapeTreeMap Shape::convertVectorToTree(ShapeVectorMap& vec) trees[layer] = ShapeTree(vals.begin(), vals.end()); } - vec = ShapeVectorMap(); + ShapeVectorMap empty; + vec.swap(empty); return trees; }