WIP: property-aware meging of deep region

This commit is contained in:
Matthias Koefferlein 2023-01-14 22:26:42 +01:00
parent 2191db0c6d
commit 467208fb6e
5 changed files with 59 additions and 32 deletions

View File

@ -598,7 +598,7 @@ private:
// and run the merge step // and run the merge step
db::MergeOp op (min_wc); 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); db::PolygonGenerator pg (pr, false /*don't resolve holes*/, m_min_coherence);
m_ep.process (pg, op); m_ep.process (pg, op);
@ -647,7 +647,7 @@ DeepRegion::ensure_merged_polygons_valid () const
db::Connectivity conn; db::Connectivity conn;
conn.connect (deep_layer ()); conn.connect (deep_layer ());
hc.set_base_verbosity (base_verbosity () + 10); 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 // collect the clusters and merge them into big polygons
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is // NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is

View File

@ -872,8 +872,8 @@ struct cluster_building_receiver
typedef std::set<size_t> global_nets; typedef std::set<size_t> global_nets;
typedef std::pair<shape_vector, global_nets> cluster_value; typedef std::pair<shape_vector, global_nets> cluster_value;
cluster_building_receiver (const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence) cluster_building_receiver (const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence, bool separate_attributes)
: mp_conn (&conn), mp_attr_equivalence (attr_equivalence) : mp_conn (&conn), mp_attr_equivalence (attr_equivalence), m_separate_attributes (separate_attributes)
{ {
if (mp_attr_equivalence) { if (mp_attr_equivalence) {
// cache the global nets per attribute equivalence cluster // cache the global nets per attribute equivalence cluster
@ -930,6 +930,9 @@ struct cluster_building_receiver
void add (const T *s1, std::pair<unsigned int, size_t> p1, const T *s2, std::pair<unsigned int, size_t> p2) void add (const T *s1, std::pair<unsigned int, size_t> p1, const T *s2, std::pair<unsigned int, size_t> p2)
{ {
if (m_separate_attributes && p1.second != p2.second) {
return;
}
if (! mp_conn->interacts (*s1, p1.first, *s2, p2.first)) { if (! mp_conn->interacts (*s1, p1.first, *s2, p2.first)) {
return; return;
} }
@ -1021,6 +1024,7 @@ private:
std::list<cluster_value> m_clusters; std::list<cluster_value> m_clusters;
std::map<size_t, std::set<size_t> > m_global_nets_by_attribute_cluster; std::map<size_t, std::set<size_t> > m_global_nets_by_attribute_cluster;
const tl::equivalence_clusters<size_t> *mp_attr_equivalence; const tl::equivalence_clusters<size_t> *mp_attr_equivalence;
bool m_separate_attributes;
void join (typename std::list<cluster_value>::iterator ic1, typename std::list<cluster_value>::iterator ic2) void join (typename std::list<cluster_value>::iterator ic1, typename std::list<cluster_value>::iterator ic2)
{ {
@ -1126,7 +1130,7 @@ struct get_shape_flags<db::NetShape>
template <class T> template <class T>
void void
local_clusters<T>::build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence, bool report_progress) local_clusters<T>::build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence, bool report_progress, bool separate_attributes)
{ {
static std::string desc = tl::to_string (tr ("Building local clusters")); static std::string desc = tl::to_string (tr ("Building local clusters"));
@ -1143,7 +1147,7 @@ local_clusters<T>::build_clusters (const db::Cell &cell, const db::Connectivity
} }
} }
cluster_building_receiver<T, box_type> rec (conn, attr_equivalence); cluster_building_receiver<T, box_type> rec (conn, attr_equivalence, separate_attributes);
bs.process (rec, 1 /*==touching*/, bc); bs.process (rec, 1 /*==touching*/, bc);
rec.generate_clusters (*this); rec.generate_clusters (*this);
@ -1391,11 +1395,11 @@ hier_clusters<T>::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpos
template <class T> template <class T>
void void
hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells) hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells, bool separate_attributes)
{ {
clear (); clear ();
cell_clusters_box_converter<T> cbc (layout, *this); cell_clusters_box_converter<T> 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 namespace
@ -1437,9 +1441,18 @@ public:
/** /**
* @brief Constructor * @brief Constructor
*/ */
hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters<T> &cell_clusters, hier_clusters<T> &tree, const cell_clusters_box_converter<T> &cbc, const db::Connectivity &conn, const std::set<db::cell_index_type> *breakout_cells, typename hier_clusters<T>::instance_interaction_cache_type *instance_interaction_cache) hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters<T> &cell_clusters, hier_clusters<T> &tree, const cell_clusters_box_converter<T> &cbc, const db::Connectivity &conn, const std::set<db::cell_index_type> *breakout_cells, typename hier_clusters<T>::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)
{ {
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; mp_cell_clusters = &cell_clusters;
} }
@ -1568,6 +1581,7 @@ private:
instance_interaction_cache<interaction_key_for_clusters<box_type>, std::list<std::pair<size_t, size_t> > > m_interaction_cache_for_clusters; instance_interaction_cache<interaction_key_for_clusters<box_type>, std::list<std::pair<size_t, size_t> > > m_interaction_cache_for_clusters;
size_t m_cluster_cache_misses, m_cluster_cache_hits; size_t m_cluster_cache_misses, m_cluster_cache_hits;
typename hier_clusters<T>::instance_interaction_cache_type *mp_instance_interaction_cache; typename hier_clusters<T>::instance_interaction_cache_type *mp_instance_interaction_cache;
bool m_separate_attributes;
/** /**
* @brief Investigate a pair of instances * @brief Investigate a pair of instances
@ -1838,7 +1852,7 @@ private:
box_type bc2 = (common2 & i->bbox ().transformed (t12)); box_type bc2 = (common2 & i->bbox ().transformed (t12));
for (typename db::local_clusters<T>::touching_iterator j = cl2.begin_touching (bc2); ! j.at_end (); ++j) { for (typename db::local_clusters<T>::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 ())); new_interactions.push_back (std::make_pair (i->id (), j->id ()));
} }
@ -2010,7 +2024,7 @@ private:
for (typename db::local_clusters<T>::touching_iterator j = cl2.begin_touching (c1.bbox ().transformed (t2.inverted ())); ! j.at_end (); ++j) { for (typename db::local_clusters<T>::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 ())); interactions.push_back (std::make_pair (c1.id (), j->id ()));
} }
@ -2249,7 +2263,7 @@ hier_clusters<T>::propagate_cluster_inst (const db::Layout &layout, const db::Ce
template <class T> template <class T>
void void
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells) hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells, bool separate_attributes)
{ {
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters"))); tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters")));
@ -2284,7 +2298,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &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; ++progress;
@ -2315,7 +2329,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
todo.push_back (*c); todo.push_back (*c);
} else { } else {
tl_assert (! todo.empty ()); 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 ()); done.insert (todo.begin (), todo.end ());
todo.clear (); todo.clear ();
todo.push_back (*c); todo.push_back (*c);
@ -2325,7 +2339,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &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) { if (tl::verbosity () >= m_base_verbosity + 20) {
@ -2335,7 +2349,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
template <class T> template <class T>
void void
hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence) hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *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 ())); 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) { if (tl::verbosity () >= m_base_verbosity + 20) {
@ -2344,15 +2358,15 @@ hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 20, msg); tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 20, msg);
connected_clusters<T> &local = m_per_cell_clusters [cell.cell_index ()]; connected_clusters<T> &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 <class T> template <class T>
void void
hier_clusters<T>::build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<db::cell_index_type> *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache) hier_clusters<T>::build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<db::cell_index_type> *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache, bool separate_attributes)
{ {
for (std::vector<db::cell_index_type>::const_iterator c = cells.begin (); c != cells.end (); ++c) { for (std::vector<db::cell_index_type>::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; ++progress;
} }
} }
@ -2436,7 +2450,7 @@ private:
template <class T> template <class T>
void void
hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<db::cell_index_type> *breakout_cells, instance_interaction_cache_type &instance_interaction_cache) hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<db::cell_index_type> *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 ())); 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) { if (tl::verbosity () >= m_base_verbosity + 20) {
@ -2448,7 +2462,7 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
// NOTE: this is a receiver for both the child-to-child and // NOTE: this is a receiver for both the child-to-child and
// local to child interactions. // local to child interactions.
std::unique_ptr<hc_receiver<T> > rec (new hc_receiver<T> (layout, cell, local, *this, cbc, conn, breakout_cells, &instance_interaction_cache)); std::unique_ptr<hc_receiver<T> > rec (new hc_receiver<T> (layout, cell, local, *this, cbc, conn, breakout_cells, &instance_interaction_cache, separate_attributes));
cell_inst_clusters_box_converter<T> cibc (cbc); cell_inst_clusters_box_converter<T> cibc (cbc);
// The box scanner needs pointers so we have to first store the instances // The box scanner needs pointers so we have to first store the instances

View File

@ -337,6 +337,14 @@ public:
*/ */
void add_attr (attr_id a); 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<T> &other) const
{
return m_attrs == other.m_attrs;
}
/** /**
* @brief Gets the attribute iterator (begin) * @brief Gets the attribute iterator (begin)
*/ */
@ -537,7 +545,7 @@ public:
* cluster joining may happen in this case, because multi-attribute * cluster joining may happen in this case, because multi-attribute
* assignment might create connections too. * assignment might create connections too.
*/ */
void build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence = 0, bool report_progress = false); void build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence = 0, bool report_progress = false, bool separate_attributes = false);
/** /**
* @brief Creates and inserts a new clusters * @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 * @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<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence = 0, const std::set<cell_index_type> *breakout_cells = 0); void build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence = 0, const std::set<cell_index_type> *breakout_cells = 0, bool separate_attributes = false);
/** /**
* @brief Gets the connected clusters for a given cell * @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; void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const;
private: private:
void build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence); void build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence, bool separate_attributes);
void build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, instance_interaction_cache_type &instance_interaction_cache); void build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, instance_interaction_cache_type &instance_interaction_cache, bool separate_attributes);
void build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache); void build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache, bool separate_attributes);
void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<cell_index_type> *breakout_cells); void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<cell_index_type> *breakout_cells, bool separate_attributes);
std::map<db::cell_index_type, connected_clusters<T> > m_per_cell_clusters; std::map<db::cell_index_type, connected_clusters<T> > m_per_cell_clusters;
int m_base_verbosity; int m_base_verbosity;

View File

@ -57,8 +57,8 @@ void EdgeToEdgeSetGenerator::put (const db::Edge &edge, int tag)
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
// class PolygonRefGenerator // class PolygonRefGenerator
PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes) PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes, db::properties_id_type prop_id)
: PolygonSink (), mp_layout (layout), mp_shapes (shapes) : PolygonSink (), mp_layout (layout), mp_shapes (shapes), m_prop_id (prop_id)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -66,7 +66,11 @@ PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db
void PolygonRefToShapesGenerator::put (const db::Polygon &polygon) void PolygonRefToShapesGenerator::put (const db::Polygon &polygon)
{ {
tl::MutexLocker locker (&mp_layout->lock ()); 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 ()));
}
} }
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------

View File

@ -155,7 +155,7 @@ public:
/** /**
* @brief Constructor specifying an external vector for storing the polygons * @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 * @brief Implementation of the PolygonSink interface
@ -165,6 +165,7 @@ public:
private: private:
db::Layout *mp_layout; db::Layout *mp_layout;
db::Shapes *mp_shapes; db::Shapes *mp_shapes;
db::properties_id_type m_prop_id;
}; };
class DB_PUBLIC PolygonSplitter class DB_PUBLIC PolygonSplitter