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
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

View File

@ -872,8 +872,8 @@ struct cluster_building_receiver
typedef std::set<size_t> global_nets;
typedef std::pair<shape_vector, global_nets> cluster_value;
cluster_building_receiver (const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence)
: mp_conn (&conn), mp_attr_equivalence (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), 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<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)) {
return;
}
@ -1021,6 +1024,7 @@ private:
std::list<cluster_value> m_clusters;
std::map<size_t, std::set<size_t> > m_global_nets_by_attribute_cluster;
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)
{
@ -1126,7 +1130,7 @@ struct get_shape_flags<db::NetShape>
template <class T>
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"));
@ -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);
rec.generate_clusters (*this);
@ -1391,11 +1395,11 @@ hier_clusters<T>::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpos
template <class T>
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 ();
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
@ -1437,9 +1441,18 @@ public:
/**
* @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)
: 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<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;
m_separate_attributes = separate_attributes;
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;
size_t m_cluster_cache_misses, m_cluster_cache_hits;
typename hier_clusters<T>::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<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 ()));
}
@ -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) {
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<T>::propagate_cluster_inst (const db::Layout &layout, const db::Ce
template <class T>
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")));
@ -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;
@ -2315,7 +2329,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &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<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) {
@ -2335,7 +2349,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
template <class T>
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 ()));
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);
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>
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) {
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 <class T>
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 ()));
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
// 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);
// 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);
/**
* @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)
*/
@ -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<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
@ -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<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
@ -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<size_t> *attr_equivalence);
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_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 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 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, 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, 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, bool separate_attributes);
std::map<db::cell_index_type, connected_clusters<T> > m_per_cell_clusters;
int m_base_verbosity;

View File

@ -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 ()));
}
}
// -----------------------------------------------------------------------------------------------

View File

@ -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