From 467208fb6ed876c599129f3d8dec4bc844c3b56c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 14 Jan 2023 22:26:42 +0100 Subject: [PATCH] WIP: property-aware meging of deep region --- src/db/db/dbDeepRegion.cc | 4 +-- src/db/db/dbHierNetworkProcessor.cc | 54 ++++++++++++++++++----------- src/db/db/dbHierNetworkProcessor.h | 20 +++++++---- src/db/db/dbLocalOperationUtils.cc | 10 ++++-- src/db/db/dbLocalOperationUtils.h | 3 +- 5 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 1691218eb..6696a032e 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -598,7 +598,7 @@ private: // and run the merge step db::MergeOp op (min_wc); - db::PolygonRefToShapesGenerator pr (mp_layout, &s->second); + db::PolygonRefToShapesGenerator pr (mp_layout, &s->second, c.begin_attr () == c.end_attr () ? db::properties_id_type (0) : *c.begin_attr ()); db::PolygonGenerator pg (pr, false /*don't resolve holes*/, m_min_coherence); m_ep.process (pg, op); @@ -647,7 +647,7 @@ DeepRegion::ensure_merged_polygons_valid () const db::Connectivity conn; conn.connect (deep_layer ()); hc.set_base_verbosity (base_verbosity () + 10); - hc.build (layout, deep_layer ().initial_cell (), conn); + hc.build (layout, deep_layer ().initial_cell (), conn, 0, 0, true /*separate_attributes*/); // collect the clusters and merge them into big polygons // NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 8ed5314e4..12e226a44 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -872,8 +872,8 @@ struct cluster_building_receiver typedef std::set global_nets; typedef std::pair cluster_value; - cluster_building_receiver (const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence) - : mp_conn (&conn), mp_attr_equivalence (attr_equivalence) + cluster_building_receiver (const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, bool separate_attributes) + : mp_conn (&conn), mp_attr_equivalence (attr_equivalence), m_separate_attributes (separate_attributes) { if (mp_attr_equivalence) { // cache the global nets per attribute equivalence cluster @@ -930,6 +930,9 @@ struct cluster_building_receiver void add (const T *s1, std::pair p1, const T *s2, std::pair p2) { + if (m_separate_attributes && p1.second != p2.second) { + return; + } if (! mp_conn->interacts (*s1, p1.first, *s2, p2.first)) { return; } @@ -1021,6 +1024,7 @@ private: std::list m_clusters; std::map > m_global_nets_by_attribute_cluster; const tl::equivalence_clusters *mp_attr_equivalence; + bool m_separate_attributes; void join (typename std::list::iterator ic1, typename std::list::iterator ic2) { @@ -1126,7 +1130,7 @@ struct get_shape_flags template void -local_clusters::build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, bool report_progress) +local_clusters::build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, bool report_progress, bool separate_attributes) { static std::string desc = tl::to_string (tr ("Building local clusters")); @@ -1143,7 +1147,7 @@ local_clusters::build_clusters (const db::Cell &cell, const db::Connectivity } } - cluster_building_receiver rec (conn, attr_equivalence); + cluster_building_receiver rec (conn, attr_equivalence, separate_attributes); bs.process (rec, 1 /*==touching*/, bc); rec.generate_clusters (*this); @@ -1391,11 +1395,11 @@ hier_clusters::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpos template void -hier_clusters::build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence, const std::set *breakout_cells) +hier_clusters::build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence, const std::set *breakout_cells, bool separate_attributes) { clear (); cell_clusters_box_converter cbc (layout, *this); - do_build (cbc, layout, cell, conn, attr_equivalence, breakout_cells); + do_build (cbc, layout, cell, conn, attr_equivalence, breakout_cells, separate_attributes); } namespace @@ -1437,9 +1441,18 @@ public: /** * @brief Constructor */ - hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn, const std::set *breakout_cells, typename hier_clusters::instance_interaction_cache_type *instance_interaction_cache) - : mp_layout (&layout), mp_cell (&cell), mp_tree (&tree), mp_cbc (&cbc), mp_conn (&conn), mp_breakout_cells (breakout_cells), m_cluster_cache_misses (0), m_cluster_cache_hits (0), mp_instance_interaction_cache (instance_interaction_cache) + hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn, const std::set *breakout_cells, typename hier_clusters::instance_interaction_cache_type *instance_interaction_cache, bool separate_attributes) { + mp_layout = &layout; + mp_cell = &cell; + mp_tree = &tree; + mp_cbc = &cbc; + mp_conn = &conn; + mp_breakout_cells = breakout_cells; + m_cluster_cache_misses = 0; + m_cluster_cache_hits = 0; + mp_instance_interaction_cache = instance_interaction_cache; + m_separate_attributes = separate_attributes; mp_cell_clusters = &cell_clusters; } @@ -1568,6 +1581,7 @@ private: instance_interaction_cache, std::list > > m_interaction_cache_for_clusters; size_t m_cluster_cache_misses, m_cluster_cache_hits; typename hier_clusters::instance_interaction_cache_type *mp_instance_interaction_cache; + bool m_separate_attributes; /** * @brief Investigate a pair of instances @@ -1838,7 +1852,7 @@ private: box_type bc2 = (common2 & i->bbox ().transformed (t12)); for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (bc2); ! j.at_end (); ++j) { - if (i->interacts (*j, t21, *mp_conn)) { + if ((! m_separate_attributes || i->same_attrs (*j)) && i->interacts (*j, t21, *mp_conn)) { new_interactions.push_back (std::make_pair (i->id (), j->id ())); } @@ -2010,7 +2024,7 @@ private: for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (c1.bbox ().transformed (t2.inverted ())); ! j.at_end (); ++j) { - if (c1.interacts (*j, t2, *mp_conn)) { + if ((! m_separate_attributes || c1.same_attrs (*j)) && c1.interacts (*j, t2, *mp_conn)) { interactions.push_back (std::make_pair (c1.id (), j->id ())); } @@ -2249,7 +2263,7 @@ hier_clusters::propagate_cluster_inst (const db::Layout &layout, const db::Ce template void -hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence, const std::set *breakout_cells) +hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence, const std::set *breakout_cells, bool separate_attributes) { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters"))); @@ -2284,7 +2298,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou } } - build_local_cluster (layout, layout.cell (*c), conn, ec); + build_local_cluster (layout, layout.cell (*c), conn, ec, separate_attributes); ++progress; @@ -2315,7 +2329,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou todo.push_back (*c); } else { tl_assert (! todo.empty ()); - build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache, separate_attributes); done.insert (todo.begin (), todo.end ()); todo.clear (); todo.push_back (*c); @@ -2325,7 +2339,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou } - build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache, separate_attributes); } if (tl::verbosity () >= m_base_verbosity + 20) { @@ -2335,7 +2349,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou template void -hier_clusters::build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence) +hier_clusters::build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, bool separate_attributes) { std::string msg = tl::to_string (tr ("Computing local clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ())); if (tl::verbosity () >= m_base_verbosity + 20) { @@ -2344,15 +2358,15 @@ hier_clusters::build_local_cluster (const db::Layout &layout, const db::Cell tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 20, msg); connected_clusters &local = m_per_cell_clusters [cell.cell_index ()]; - local.build_clusters (cell, conn, attr_equivalence, true); + local.build_clusters (cell, conn, attr_equivalence, true, separate_attributes); } template void -hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache) +hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache, bool separate_attributes) { for (std::vector::const_iterator c = cells.begin (); c != cells.end (); ++c) { - build_hier_connections (cbc, layout, layout.cell (*c), conn, breakout_cells, instance_interaction_cache); + build_hier_connections (cbc, layout, layout.cell (*c), conn, breakout_cells, instance_interaction_cache, separate_attributes); ++progress; } } @@ -2436,7 +2450,7 @@ private: template void -hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache) +hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache, bool separate_attributes) { std::string msg = tl::to_string (tr ("Computing hierarchical clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ())); if (tl::verbosity () >= m_base_verbosity + 20) { @@ -2448,7 +2462,7 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c // NOTE: this is a receiver for both the child-to-child and // local to child interactions. - std::unique_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn, breakout_cells, &instance_interaction_cache)); + std::unique_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn, breakout_cells, &instance_interaction_cache, separate_attributes)); cell_inst_clusters_box_converter cibc (cbc); // The box scanner needs pointers so we have to first store the instances diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index a440439b2..f528967c6 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -337,6 +337,14 @@ public: */ void add_attr (attr_id a); + /** + * @brief Gets a value indicating whether the attributes of the clusters are identical + */ + bool same_attrs (const local_cluster &other) const + { + return m_attrs == other.m_attrs; + } + /** * @brief Gets the attribute iterator (begin) */ @@ -537,7 +545,7 @@ public: * cluster joining may happen in this case, because multi-attribute * assignment might create connections too. */ - void build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence = 0, bool report_progress = false); + void build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence = 0, bool report_progress = false, bool separate_attributes = false); /** * @brief Creates and inserts a new clusters @@ -1212,7 +1220,7 @@ public: /** * @brief Builds a hierarchy of clusters from a cell hierarchy and given connectivity */ - void build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence = 0, const std::set *breakout_cells = 0); + void build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence = 0, const std::set *breakout_cells = 0, bool separate_attributes = false); /** * @brief Gets the connected clusters for a given cell @@ -1255,10 +1263,10 @@ public: void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const; private: - void build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence); - void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache); - void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache); - void do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence, const std::set *breakout_cells); + void build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, bool separate_attributes); + void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache, bool separate_attributes); + void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache, bool separate_attributes); + void do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map > *attr_equivalence, const std::set *breakout_cells, bool separate_attributes); std::map > m_per_cell_clusters; int m_base_verbosity; diff --git a/src/db/db/dbLocalOperationUtils.cc b/src/db/db/dbLocalOperationUtils.cc index 3712f67e1..2ad889cc8 100644 --- a/src/db/db/dbLocalOperationUtils.cc +++ b/src/db/db/dbLocalOperationUtils.cc @@ -57,8 +57,8 @@ void EdgeToEdgeSetGenerator::put (const db::Edge &edge, int tag) // ----------------------------------------------------------------------------------------------- // class PolygonRefGenerator -PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes) - : PolygonSink (), mp_layout (layout), mp_shapes (shapes) +PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes, db::properties_id_type prop_id) + : PolygonSink (), mp_layout (layout), mp_shapes (shapes), m_prop_id (prop_id) { // .. nothing yet .. } @@ -66,7 +66,11 @@ PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db void PolygonRefToShapesGenerator::put (const db::Polygon &polygon) { tl::MutexLocker locker (&mp_layout->lock ()); - mp_shapes->insert (db::PolygonRef (polygon, mp_layout->shape_repository ())); + if (m_prop_id != 0) { + mp_shapes->insert (db::PolygonRefWithProperties (db::PolygonRef (polygon, mp_layout->shape_repository ()), m_prop_id)); + } else { + mp_shapes->insert (db::PolygonRef (polygon, mp_layout->shape_repository ())); + } } // ----------------------------------------------------------------------------------------------- diff --git a/src/db/db/dbLocalOperationUtils.h b/src/db/db/dbLocalOperationUtils.h index f1f89cf5c..0000ca0d9 100644 --- a/src/db/db/dbLocalOperationUtils.h +++ b/src/db/db/dbLocalOperationUtils.h @@ -155,7 +155,7 @@ public: /** * @brief Constructor specifying an external vector for storing the polygons */ - PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes); + PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes, db::properties_id_type prop_id = 0); /** * @brief Implementation of the PolygonSink interface @@ -165,6 +165,7 @@ public: private: db::Layout *mp_layout; db::Shapes *mp_shapes; + db::properties_id_type m_prop_id; }; class DB_PUBLIC PolygonSplitter