From 92f956faadcc845537f18bdf484fc1983f9186c5 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Tue, 7 Apr 2026 16:41:06 -0400 Subject: [PATCH 1/5] psm: simplify compare Signed-off-by: Peter Gadfort --- src/psm/src/connection.cpp | 52 +++++++++++++++++++++++--------------- src/psm/src/connection.h | 4 --- src/psm/src/node.cpp | 47 +++++++++++++++++++++++----------- src/psm/src/node.h | 4 --- 4 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/psm/src/connection.cpp b/src/psm/src/connection.cpp index 9308d3f27d6..24e8efbee79 100644 --- a/src/psm/src/connection.cpp +++ b/src/psm/src/connection.cpp @@ -70,31 +70,43 @@ int Connection::getDBUs() const bool Connection::compare(const Connection* other) const { - return compareTuple() < other->compareTuple(); -} - -bool Connection::compare(const std::unique_ptr& other) const -{ - return compare(other.get()); -} + if (other == nullptr) { + return true; + } -Connection::CompareInformation Connection::compareTuple() const -{ - Node::CompareInformation node0_info; - if (node0_ != nullptr) { - node0_info = node0_->compareTuple(); - } else { - node0_info = Node::dummyCompareTuple(); + // Compare node0_ with null handling + if (node0_ == nullptr && other->node0_ != nullptr) { + return true; + } + if (node0_ != nullptr && other->node0_ == nullptr) { + return false; + } + if (node0_ != nullptr && other->node0_ != nullptr) { + if (node0_->compare(other->node0_)) { + return true; + } + if (other->node0_->compare(node0_)) { + return false; + } } - Node::CompareInformation node1_info; - if (node1_ != nullptr) { - node1_info = node1_->compareTuple(); - } else { - node1_info = Node::dummyCompareTuple(); + // Compare node1_ with null handling + if (node1_ == nullptr && other->node1_ != nullptr) { + return true; + } + if (node1_ != nullptr && other->node1_ == nullptr) { + return false; } + if (node1_ != nullptr && other->node1_ != nullptr) { + return node1_->compare(other->node1_); + } + + return false; +} - return {node0_info, node1_info}; +bool Connection::compare(const std::unique_ptr& other) const +{ + return compare(other.get()); } std::string Connection::describeWithNodes() const diff --git a/src/psm/src/connection.h b/src/psm/src/connection.h index 8cf02e444f1..35c669d4edd 100644 --- a/src/psm/src/connection.h +++ b/src/psm/src/connection.h @@ -84,10 +84,6 @@ class Connection Node* node1_; private: - using CompareInformation - = std::tuple; - CompareInformation compareTuple() const; - template bool hasNodeOfType() const; }; diff --git a/src/psm/src/node.cpp b/src/psm/src/node.cpp index 1cbef9785b9..27aaa3b13d4 100644 --- a/src/psm/src/node.cpp +++ b/src/psm/src/node.cpp @@ -18,27 +18,44 @@ Node::Node(const odb::Point& pt, odb::dbTechLayer* layer) { } -Node::CompareInformation Node::compareTuple() const -{ - const int x = pt_.getX(); - const int y = pt_.getY(); - const int layer = layer_->getNumber(); - - return {layer, x, y, getType(), getTypeCompareInfo()}; -} - -Node::CompareInformation Node::dummyCompareTuple() -{ - return {-1, 0, 0, NodeType::kUnknown, -1}; -} - bool Node::compare(const Node* other) const { if (other == nullptr) { return true; } - return compareTuple() < other->compareTuple(); + // Compare layer + const int layer1 = layer_->getNumber(); + const int layer2 = other->layer_->getNumber(); + if (layer1 != layer2) { + return layer1 < layer2; + } + + // Compare x coordinate + const int x1 = pt_.getX(); + const int x2 = other->pt_.getX(); + if (x1 != x2) { + return x1 < x2; + } + + // Compare y coordinate + const int y1 = pt_.getY(); + const int y2 = other->pt_.getY(); + if (y1 != y2) { + return y1 < y2; + } + + // Compare node type + const NodeType type1 = getType(); + const NodeType type2 = other->getType(); + if (type1 != type2) { + return type1 < type2; + } + + // Compare type-specific info + const int info1 = getTypeCompareInfo(); + const int info2 = other->getTypeCompareInfo(); + return info1 < info2; } bool Node::compare(const std::unique_ptr& other) const diff --git a/src/psm/src/node.h b/src/psm/src/node.h index 475231461f2..0177d9a1775 100644 --- a/src/psm/src/node.h +++ b/src/psm/src/node.h @@ -64,10 +64,6 @@ class Node std::string getName() const; std::string getTypeName() const; - using CompareInformation = std::tuple; - CompareInformation compareTuple() const; - static CompareInformation dummyCompareTuple(); - protected: virtual NodeType getType() const { return NodeType::kNode; } From 10323ad209bd01aa7fe91486c3eec6b3506d98c0 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Tue, 7 Apr 2026 17:40:03 -0400 Subject: [PATCH 2/5] psm: avoid additional call to compare Signed-off-by: Peter Gadfort --- src/psm/src/connection.cpp | 13 ++++++------- src/psm/src/debug_gui.cpp | 6 +++--- src/psm/src/ir_network.cpp | 9 ++++----- src/psm/src/node.cpp | 16 ++++++++-------- src/psm/src/node.h | 7 ++++--- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/psm/src/connection.cpp b/src/psm/src/connection.cpp index 24e8efbee79..d4beaac6f56 100644 --- a/src/psm/src/connection.cpp +++ b/src/psm/src/connection.cpp @@ -20,7 +20,7 @@ Connection::Connection(Node* node0, Node* node1) : node0_(node0), node1_(node1) void Connection::ensureNodeOrder() { - if (node0_ && !node0_->compare(node1_)) { + if (node0_ && node0_->compare(node1_) > 0) { std::swap(node0_, node1_); } } @@ -82,11 +82,9 @@ bool Connection::compare(const Connection* other) const return false; } if (node0_ != nullptr && other->node0_ != nullptr) { - if (node0_->compare(other->node0_)) { - return true; - } - if (other->node0_->compare(node0_)) { - return false; + const int cmp0 = node0_->compare(other->node0_); + if (cmp0 != 0) { + return cmp0 < 0; } } @@ -98,7 +96,8 @@ bool Connection::compare(const Connection* other) const return false; } if (node1_ != nullptr && other->node1_ != nullptr) { - return node1_->compare(other->node1_); + const int cmp1 = node1_->compare(other->node1_); + return cmp1 < 0; } return false; diff --git a/src/psm/src/debug_gui.cpp b/src/psm/src/debug_gui.cpp index 150ea461253..95634152828 100644 --- a/src/psm/src/debug_gui.cpp +++ b/src/psm/src/debug_gui.cpp @@ -138,7 +138,7 @@ bool NodeDescriptor::lessThan(const std::any& l, const std::any& r) const { auto l_node = std::any_cast(l); auto r_node = std::any_cast(r); - return l_node->compare(r_node); + return l_node->compare(r_node) < 0; } void NodeDescriptor::highlight(const std::any& object, @@ -195,7 +195,7 @@ bool ITermNodeDescriptor::lessThan(const std::any& l, const std::any& r) const { auto l_node = std::any_cast(l); auto r_node = std::any_cast(r); - return l_node->compare(r_node); + return l_node->compare(r_node) < 0; } void ITermNodeDescriptor::highlight(const std::any& object, @@ -251,7 +251,7 @@ bool BPinNodeDescriptor::lessThan(const std::any& l, const std::any& r) const { auto l_node = std::any_cast(l); auto r_node = std::any_cast(r); - return l_node->compare(r_node); + return l_node->compare(r_node) < 0; } void BPinNodeDescriptor::highlight(const std::any& object, diff --git a/src/psm/src/ir_network.cpp b/src/psm/src/ir_network.cpp index 7a7079b3766..e207409e220 100644 --- a/src/psm/src/ir_network.cpp +++ b/src/psm/src/ir_network.cpp @@ -804,7 +804,7 @@ void IRNetwork::sortNodes() for (auto& [layer, nodes] : nodes_) { std::ranges::stable_sort(nodes, [](const auto& lhs, const auto& rhs) { - return lhs->compare(rhs); + return lhs->compare(rhs) < 0; }); } } @@ -813,10 +813,9 @@ void IRNetwork::sortConnections() { const utl::DebugScopedTimer timer( logger_, utl::PSM, "timer", 1, "Sorting connections: {}"); - std::ranges::stable_sort( - connections_, - - [](const auto& lhs, const auto& rhs) { return lhs->compare(rhs); }); + std::ranges::stable_sort(connections_, [](const auto& lhs, const auto& rhs) { + return lhs->compare(rhs); + }); } int IRNetwork::getEffectiveNumberOfCuts(const odb::dbShape& shape) const diff --git a/src/psm/src/node.cpp b/src/psm/src/node.cpp index 27aaa3b13d4..0ae0979aab2 100644 --- a/src/psm/src/node.cpp +++ b/src/psm/src/node.cpp @@ -18,47 +18,47 @@ Node::Node(const odb::Point& pt, odb::dbTechLayer* layer) { } -bool Node::compare(const Node* other) const +int Node::compare(const Node* other) const { if (other == nullptr) { - return true; + return 1; } // Compare layer const int layer1 = layer_->getNumber(); const int layer2 = other->layer_->getNumber(); if (layer1 != layer2) { - return layer1 < layer2; + return layer1 < layer2 ? -1 : 1; } // Compare x coordinate const int x1 = pt_.getX(); const int x2 = other->pt_.getX(); if (x1 != x2) { - return x1 < x2; + return x1 < x2 ? -1 : 1; } // Compare y coordinate const int y1 = pt_.getY(); const int y2 = other->pt_.getY(); if (y1 != y2) { - return y1 < y2; + return y1 < y2 ? -1 : 1; } // Compare node type const NodeType type1 = getType(); const NodeType type2 = other->getType(); if (type1 != type2) { - return type1 < type2; + return type1 < type2 ? -1 : 1; } // Compare type-specific info const int info1 = getTypeCompareInfo(); const int info2 = other->getTypeCompareInfo(); - return info1 < info2; + return info1 == info2 ? 0 : (info1 < info2 ? -1 : 1); } -bool Node::compare(const std::unique_ptr& other) const +int Node::compare(const std::unique_ptr& other) const { return compare(other.get()); } diff --git a/src/psm/src/node.h b/src/psm/src/node.h index 0177d9a1775..50325259dd9 100644 --- a/src/psm/src/node.h +++ b/src/psm/src/node.h @@ -43,7 +43,7 @@ class Node { bool operator()(const Node* lhs, const Node* rhs) const { - return lhs->compare(rhs); + return lhs->compare(rhs) < 0; } }; @@ -52,8 +52,9 @@ class Node Node(const odb::Point& pt, odb::dbTechLayer* layer); virtual ~Node() = default; - bool compare(const Node* other) const; - bool compare(const std::unique_ptr& other) const; + // Returns -1 if this < other, 0 if equal, +1 if this > other + int compare(const Node* other) const; + int compare(const std::unique_ptr& other) const; const odb::Point& getPoint() const { return pt_; }; odb::dbTechLayer* getLayer() const { return layer_; }; From 16ed5c9015692d5ad80247c3f2ce86e8930d1286 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Tue, 7 Apr 2026 18:56:49 -0400 Subject: [PATCH 3/5] psm: node hold visited Signed-off-by: Peter Gadfort --- src/psm/src/ir_network.cpp | 15 +++++++++++++++ src/psm/src/ir_network.h | 2 ++ src/psm/src/ir_solver.cpp | 29 +++++++---------------------- src/psm/src/ir_solver.h | 5 ----- src/psm/src/node.cpp | 2 +- src/psm/src/node.h | 4 ++++ 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/psm/src/ir_network.cpp b/src/psm/src/ir_network.cpp index e207409e220..db00d0c7c10 100644 --- a/src/psm/src/ir_network.cpp +++ b/src/psm/src/ir_network.cpp @@ -1298,4 +1298,19 @@ Node::NodeSet IRNetwork::getBPinShapeNodes() const return pin_nodes; } +void IRNetwork::clearVisitedNodes() +{ + for (const auto& [layer, nodes] : nodes_) { + for (const auto& node : nodes) { + node->setVisited(false); + } + } + for (const auto& node : iterm_nodes_) { + node->setVisited(false); + } + for (const auto& node : bpin_nodes_) { + node->setVisited(false); + } +} + } // namespace psm diff --git a/src/psm/src/ir_network.h b/src/psm/src/ir_network.h index f70e599251c..2084fb7dfd4 100644 --- a/src/psm/src/ir_network.h +++ b/src/psm/src/ir_network.h @@ -106,6 +106,8 @@ class IRNetwork std::size_t getNodeCount(bool include_iterms = false) const; + void clearVisitedNodes(); + const Connections& getConnections() const { return connections_; } NodePtrMap getConnectionMap() const; diff --git a/src/psm/src/ir_solver.cpp b/src/psm/src/ir_solver.cpp index 9d9389c1345..5a64bb784db 100644 --- a/src/psm/src/ir_solver.cpp +++ b/src/psm/src/ir_solver.cpp @@ -141,27 +141,12 @@ bool IRSolver::check(bool check_bterms) return connected_.value(); } -bool IRSolver::wasNodeVisited(const std::unique_ptr& node) const -{ - return wasNodeVisited(node.get()); -} - -bool IRSolver::wasNodeVisited(const std::unique_ptr& node) const -{ - return wasNodeVisited(node.get()); -} - -bool IRSolver::wasNodeVisited(const Node* node) const -{ - return visited_.find(node) != visited_.end(); -} - bool IRSolver::checkOpen() { const utl::DebugScopedTimer timer( logger_, utl::PSM, "timer", 1, "Check open: {}"); - visited_.clear(); + network_->clearVisitedNodes(); const std::size_t total_nodes = network_->getNodeCount(true); const auto connections_map = network_->getConnectionMap(); @@ -179,7 +164,7 @@ bool IRSolver::checkOpen() while (!queue.empty()) { Node* node = queue.front(); queue.pop(); - if (wasNodeVisited(node)) { + if (node->isVisited()) { // already been here, so we can continue to next node continue; } @@ -196,11 +181,11 @@ bool IRSolver::checkOpen() total_nodes); } - visited_.insert(node); + node->setVisited(true); for (const auto* conn : connections_map.at(node)) { Node* next = conn->getOtherNode(node); - if (wasNodeVisited(next)) { + if (next->isVisited()) { // already been here, so we do not need to add it to the queue continue; } @@ -210,7 +195,7 @@ bool IRSolver::checkOpen() for (const auto& [layer, layer_nodes] : network_->getNodes()) { for (const auto& node : layer_nodes) { - if (wasNodeVisited(node)) { + if (node->isVisited()) { continue; } @@ -249,7 +234,7 @@ IRSolver::ConnectivityResults IRSolver::getConnectivityResults() const for (const auto& [layer, nodes] : network_->getNodes()) { for (const auto& node : nodes) { - if (wasNodeVisited(node)) { + if (node->isVisited()) { continue; } @@ -258,7 +243,7 @@ IRSolver::ConnectivityResults IRSolver::getConnectivityResults() const } for (const auto& node : network_->getITermNodes()) { - if (wasNodeVisited(node)) { + if (node->isVisited()) { continue; } diff --git a/src/psm/src/ir_solver.h b/src/psm/src/ir_solver.h index 0c21e5ad725..1a158ecf927 100644 --- a/src/psm/src/ir_solver.h +++ b/src/psm/src/ir_solver.h @@ -162,9 +162,6 @@ class IRSolver void reportUnconnectedNodes() const; void reportMissingBTerm() const; - bool wasNodeVisited(const std::unique_ptr& node) const; - bool wasNodeVisited(const std::unique_ptr& node) const; - bool wasNodeVisited(const Node* node) const; std::map getNodeConnectionMap( const Connection::ConnectionMap& conductance) @@ -216,8 +213,6 @@ class IRSolver const PDNSim::GeneratedSourceSettings& generated_source_settings_; - // Holds nodes that were visited during the open net check - std::set visited_; std::optional connected_; std::map> voltages_; diff --git a/src/psm/src/node.cpp b/src/psm/src/node.cpp index 0ae0979aab2..3f581eeb31c 100644 --- a/src/psm/src/node.cpp +++ b/src/psm/src/node.cpp @@ -14,7 +14,7 @@ namespace psm { Node::Node(const odb::Point& pt, odb::dbTechLayer* layer) - : pt_(pt), layer_(layer) + : pt_(pt), layer_(layer), visited_(false) { } diff --git a/src/psm/src/node.h b/src/psm/src/node.h index 50325259dd9..180b1aa5c90 100644 --- a/src/psm/src/node.h +++ b/src/psm/src/node.h @@ -59,6 +59,9 @@ class Node const odb::Point& getPoint() const { return pt_; }; odb::dbTechLayer* getLayer() const { return layer_; }; + bool isVisited() const { return visited_; } + void setVisited(bool visited) { visited_ = visited; } + void print(utl::Logger* logger, const std::string& prefix = "") const; virtual std::string describe(const std::string& prefix) const; @@ -75,6 +78,7 @@ class Node odb::Point pt_; odb::dbTechLayer* layer_; + bool visited_ = false; }; class SourceNode : public Node From 3833a6a0492c223174361258e7bc8ac64a52c654 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Tue, 7 Apr 2026 19:04:09 -0400 Subject: [PATCH 4/5] psm: use boost geom point Signed-off-by: Peter Gadfort --- src/psm/src/ir_network.cpp | 4 ++-- src/psm/src/ir_network.h | 4 ---- src/psm/src/shape.cpp | 3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/psm/src/ir_network.cpp b/src/psm/src/ir_network.cpp index db00d0c7c10..55e2088c682 100644 --- a/src/psm/src/ir_network.cpp +++ b/src/psm/src/ir_network.cpp @@ -709,9 +709,9 @@ std::set IRNetwork::getSharedShapeNodes() const const auto layer_shapes = getShapeTree(layer); for (const auto& node : nodes) { - const Point pt(node->getPoint().x(), node->getPoint().y()); const auto shapes = std::distance( - layer_shapes.qbegin(boost::geometry::index::intersects(pt)), + layer_shapes.qbegin( + boost::geometry::index::intersects(node->getPoint())), layer_shapes.qend()); if (shapes > 1) { shared_nodes.insert(node.get()); diff --git a/src/psm/src/ir_network.h b/src/psm/src/ir_network.h index 2084fb7dfd4..da58f63e560 100644 --- a/src/psm/src/ir_network.h +++ b/src/psm/src/ir_network.h @@ -45,10 +45,6 @@ class IRNetwork template using LayerMap = std::map; - using Point - = boost::geometry::model::d2::point_xy; - using TerminalTree = boost::geometry::index::rtree, diff --git a/src/psm/src/shape.cpp b/src/psm/src/shape.cpp index 1be3185637f..15c4ec626d2 100644 --- a/src/psm/src/shape.cpp +++ b/src/psm/src/shape.cpp @@ -44,7 +44,6 @@ Connections Shape::connectNodes(const IRNetwork::NodeTree& layer_nodes) for (auto* node : sorted_nodes) { const auto& pt = node->getPoint(); - const IRNetwork::Point point(pt.x(), pt.y()); std::vector ordered_neighbors; @@ -52,7 +51,7 @@ Connections Shape::connectNodes(const IRNetwork::NodeTree& layer_nodes) tree.query(boost::geometry::index::satisfies([&](const auto value) { return used.find(value) == used.end(); - }) && boost::geometry::index::nearest(point, 1), + }) && boost::geometry::index::nearest(pt, 1), std::back_inserter(ordered_neighbors)); for (Node* other : ordered_neighbors) { From 6122d1c8e89d6cfe68ac93f20d7728bd1db37513 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Tue, 7 Apr 2026 20:03:10 -0400 Subject: [PATCH 5/5] psm: apply suggestions Signed-off-by: Peter Gadfort --- src/psm/src/connection.cpp | 2 +- src/psm/src/node.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/psm/src/connection.cpp b/src/psm/src/connection.cpp index d4beaac6f56..afc3e8d01e1 100644 --- a/src/psm/src/connection.cpp +++ b/src/psm/src/connection.cpp @@ -71,7 +71,7 @@ int Connection::getDBUs() const bool Connection::compare(const Connection* other) const { if (other == nullptr) { - return true; + return false; } // Compare node0_ with null handling diff --git a/src/psm/src/node.cpp b/src/psm/src/node.cpp index 3f581eeb31c..f77af30ebc8 100644 --- a/src/psm/src/node.cpp +++ b/src/psm/src/node.cpp @@ -14,7 +14,7 @@ namespace psm { Node::Node(const odb::Point& pt, odb::dbTechLayer* layer) - : pt_(pt), layer_(layer), visited_(false) + : pt_(pt), layer_(layer) { } @@ -55,7 +55,10 @@ int Node::compare(const Node* other) const // Compare type-specific info const int info1 = getTypeCompareInfo(); const int info2 = other->getTypeCompareInfo(); - return info1 == info2 ? 0 : (info1 < info2 ? -1 : 1); + if (info1 == info2) { + return 0; + } + return info1 < info2 ? -1 : 1; } int Node::compare(const std::unique_ptr& other) const