mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
8de70c742a
commit
6db937d9df
|
|
@ -879,6 +879,13 @@ local_clusters<T>::insert ()
|
||||||
return i.operator-> ();
|
return i.operator-> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void
|
||||||
|
local_clusters<T>::make_soft_connection (typename local_cluster<T>::id_type a, typename local_cluster<T>::id_type b)
|
||||||
|
{
|
||||||
|
// @@@ TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void
|
||||||
local_clusters<T>::ensure_sorted ()
|
local_clusters<T>::ensure_sorted ()
|
||||||
|
|
@ -942,6 +949,8 @@ struct cluster_building_receiver
|
||||||
|
|
||||||
void generate_clusters (local_clusters<T> &clusters)
|
void generate_clusters (local_clusters<T> &clusters)
|
||||||
{
|
{
|
||||||
|
std::map<const cluster_value *, local_cluster<T> *> in_to_out;
|
||||||
|
|
||||||
// build the resulting clusters
|
// build the resulting clusters
|
||||||
for (typename std::list<cluster_value>::const_iterator c = m_clusters.begin (); c != m_clusters.end (); ++c) {
|
for (typename std::list<cluster_value>::const_iterator c = m_clusters.begin (); c != m_clusters.end (); ++c) {
|
||||||
|
|
||||||
|
|
@ -952,6 +961,8 @@ struct cluster_building_receiver
|
||||||
cluster->add_attr (s->second.second);
|
cluster->add_attr (s->second.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_to_out.insert (std::make_pair (c.operator-> (), cluster));
|
||||||
|
|
||||||
std::set<size_t> global_nets = c->second;
|
std::set<size_t> global_nets = c->second;
|
||||||
|
|
||||||
// Add the global nets we derive from the attribute equivalence (join_nets of labelled vs.
|
// Add the global nets we derive from the attribute equivalence (join_nets of labelled vs.
|
||||||
|
|
@ -980,6 +991,20 @@ struct cluster_building_receiver
|
||||||
cluster->set_global_nets (global_nets);
|
cluster->set_global_nets (global_nets);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto sc = m_soft_connections.begin (); sc != m_soft_connections.end (); ++sc) {
|
||||||
|
|
||||||
|
if (sc->second >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto c1 = in_to_out.find (sc->first.first);
|
||||||
|
auto c2 = in_to_out.find (sc->first.second);
|
||||||
|
tl_assert (c1 != in_to_out.end () && c2 != in_to_out.end ());
|
||||||
|
|
||||||
|
clusters.make_soft_connection (c1->second->id (), c2->second->id ());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -1153,6 +1178,7 @@ private:
|
||||||
std::map<const T *, typename std::list<cluster_value>::iterator> m_shape_to_clusters;
|
std::map<const T *, typename std::list<cluster_value>::iterator> m_shape_to_clusters;
|
||||||
std::map<size_t, typename std::list<cluster_value>::iterator> m_global_to_clusters;
|
std::map<size_t, typename std::list<cluster_value>::iterator> m_global_to_clusters;
|
||||||
std::list<cluster_value> m_clusters;
|
std::list<cluster_value> m_clusters;
|
||||||
|
std::map<std::pair<const cluster_value *, const cluster_value *>, int> m_soft_connections;
|
||||||
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;
|
bool m_separate_attributes;
|
||||||
|
|
@ -1170,13 +1196,35 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clusters.erase (ic2);
|
m_clusters.erase (ic2);
|
||||||
|
|
||||||
|
auto i1 = m_soft_connections.find (std::make_pair (ic1.operator-> (), ic2.operator-> ()));
|
||||||
|
if (i1 != m_soft_connections.end ()) {
|
||||||
|
i1->second = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto i2 = m_soft_connections.find (std::make_pair (ic2.operator-> (), ic1.operator-> ()));
|
||||||
|
if (i2 != m_soft_connections.end ()) {
|
||||||
|
i2->second = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_soft_connection (typename std::list<cluster_value>::iterator ic1, typename std::list<cluster_value>::iterator ic2, int soft)
|
void register_soft_connection (typename std::list<cluster_value>::iterator ic1, typename std::list<cluster_value>::iterator ic2, int soft)
|
||||||
{
|
{
|
||||||
|
auto i1 = m_soft_connections.find (std::make_pair (ic1.operator-> (), ic2.operator-> ()));
|
||||||
|
auto i2 = m_soft_connections.find (std::make_pair (ic2.operator-> (), ic1.operator-> ()));
|
||||||
|
|
||||||
// @@@ TODO: implement
|
if (i1 != m_soft_connections.end () && i1->second != 0 && i1->second != soft) {
|
||||||
|
i1->second = 0;
|
||||||
|
}
|
||||||
|
if (i2 != m_soft_connections.end () && i2->second != 0 && i2->second != -soft) {
|
||||||
|
i2->second = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i1 == m_soft_connections.end ()) {
|
||||||
|
tl_assert (i2 == m_soft_connections.end ());
|
||||||
|
m_soft_connections.insert (std::make_pair (std::make_pair (ic1.operator-> (), ic2.operator-> ()), soft));
|
||||||
|
m_soft_connections.insert (std::make_pair (std::make_pair (ic2.operator-> (), ic1.operator-> ()), -soft));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1269,6 +1317,7 @@ void
|
||||||
local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<size_t> &attr_equivalence)
|
local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<size_t> &attr_equivalence)
|
||||||
{
|
{
|
||||||
// identify the layout clusters joined into one attribute cluster and join them
|
// identify the layout clusters joined into one attribute cluster and join them
|
||||||
|
// NOTE: soft connections are not supported here, but that is a deprecated mechanism anyway.
|
||||||
|
|
||||||
std::map<tl::equivalence_clusters<size_t>::cluster_id_type, std::set<size_t> > c2c;
|
std::map<tl::equivalence_clusters<size_t>::cluster_id_type, std::set<size_t> > c2c;
|
||||||
|
|
||||||
|
|
@ -1533,17 +1582,18 @@ public:
|
||||||
|
|
||||||
struct ClusterInstanceInteraction
|
struct ClusterInstanceInteraction
|
||||||
{
|
{
|
||||||
ClusterInstanceInteraction (size_t _cluster_id, const ClusterInstance &_other_ci)
|
ClusterInstanceInteraction (size_t _cluster_id, const ClusterInstance &_other_ci, int _soft)
|
||||||
: cluster_id (_cluster_id), other_ci (_other_ci)
|
: cluster_id (_cluster_id), other_ci (_other_ci), soft (_soft)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool operator== (const ClusterInstanceInteraction &other) const
|
bool operator== (const ClusterInstanceInteraction &other) const
|
||||||
{
|
{
|
||||||
return cluster_id == other.cluster_id && other_ci == other.other_ci;
|
return cluster_id == other.cluster_id && other_ci == other.other_ci && soft == other.soft;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cluster_id;
|
size_t cluster_id;
|
||||||
ClusterInstance other_ci;
|
ClusterInstance other_ci;
|
||||||
|
int soft;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1597,7 +1647,7 @@ public:
|
||||||
{
|
{
|
||||||
db::ICplxTrans t;
|
db::ICplxTrans t;
|
||||||
|
|
||||||
std::list<std::pair<ClusterInstance, ClusterInstance> > ic;
|
std::list<ClusterInstancePair> ic;
|
||||||
consider_instance_pair (box_type::world (), *i1, t, db::CellInstArray::iterator (), *i2, t, db::CellInstArray::iterator (), ic);
|
consider_instance_pair (box_type::world (), *i1, t, db::CellInstArray::iterator (), *i2, t, db::CellInstArray::iterator (), ic);
|
||||||
|
|
||||||
connect_clusters (ic);
|
connect_clusters (ic);
|
||||||
|
|
@ -1634,11 +1684,23 @@ public:
|
||||||
void finish_cluster_to_instance_interactions ()
|
void finish_cluster_to_instance_interactions ()
|
||||||
{
|
{
|
||||||
for (typename std::list<ClusterInstanceInteraction>::const_iterator ii = m_ci_interactions.begin (); ii != m_ci_interactions.end (); ++ii) {
|
for (typename std::list<ClusterInstanceInteraction>::const_iterator ii = m_ci_interactions.begin (); ii != m_ci_interactions.end (); ++ii) {
|
||||||
mp_tree->propagate_cluster_inst (*mp_layout, *mp_cell, ii->other_ci, mp_cell->cell_index (), false);
|
|
||||||
|
// NOTE: soft connections make a dummy cluster at the level of our instance. This allows registering a soft connection to it.
|
||||||
|
mp_tree->propagate_cluster_inst (*mp_layout, *mp_cell, ii->other_ci, mp_cell->cell_index (), ii->soft != 0 ? true /*with self*/ : false /*without self*/);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (typename std::list<ClusterInstanceInteraction>::const_iterator ii = m_ci_interactions.begin (); ii != m_ci_interactions.end (); ++ii) {
|
for (typename std::list<ClusterInstanceInteraction>::const_iterator ii = m_ci_interactions.begin (); ii != m_ci_interactions.end (); ++ii) {
|
||||||
|
|
||||||
|
if (ii->soft != 0) {
|
||||||
|
|
||||||
|
id_type other = mp_cell_clusters->find_cluster_with_connection (ii->other_ci);
|
||||||
|
tl_assert (other > 0); // because we used "with self" in "propagate_cluster_inst"
|
||||||
|
|
||||||
|
register_soft_connection (ii->cluster_id, other, ii->soft);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
id_type other = mp_cell_clusters->find_cluster_with_connection (ii->other_ci);
|
id_type other = mp_cell_clusters->find_cluster_with_connection (ii->other_ci);
|
||||||
if (other > 0) {
|
if (other > 0) {
|
||||||
|
|
||||||
|
|
@ -1653,6 +1715,8 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (typename std::list<std::set<id_type> >::const_iterator sc = m_cm2join_sets.begin (); sc != m_cm2join_sets.end (); ++sc) {
|
for (typename std::list<std::set<id_type> >::const_iterator sc = m_cm2join_sets.begin (); sc != m_cm2join_sets.end (); ++sc) {
|
||||||
|
|
||||||
if (sc->empty ()) {
|
if (sc->empty ()) {
|
||||||
|
|
@ -1664,6 +1728,22 @@ public:
|
||||||
typename std::set<id_type>::const_iterator cc = c;
|
typename std::set<id_type>::const_iterator cc = c;
|
||||||
for (++cc; cc != sc->end (); ++cc) {
|
for (++cc; cc != sc->end (); ++cc) {
|
||||||
mp_cell_clusters->join_cluster_with (*c, *cc);
|
mp_cell_clusters->join_cluster_with (*c, *cc);
|
||||||
|
m_soft_connections.erase (std::make_pair (*c < *cc ? *c : *cc, *c < *cc ? *cc : *c));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto sc = m_soft_connections.begin (); sc != m_soft_connections.end (); ++sc) {
|
||||||
|
|
||||||
|
if (sc->second == 0) {
|
||||||
|
// dropped soft connection
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc->second > 0) {
|
||||||
|
mp_cell_clusters->make_soft_connection (sc->first.second, sc->first.first);
|
||||||
|
} else {
|
||||||
|
mp_cell_clusters->make_soft_connection (sc->first.first, sc->first.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1685,8 +1765,9 @@ private:
|
||||||
typedef std::list<std::set<id_type> > join_set_list;
|
typedef std::list<std::set<id_type> > join_set_list;
|
||||||
std::map<id_type, typename join_set_list::iterator> m_cm2join_map;
|
std::map<id_type, typename join_set_list::iterator> m_cm2join_map;
|
||||||
join_set_list m_cm2join_sets;
|
join_set_list m_cm2join_sets;
|
||||||
|
std::map<std::pair<size_t, size_t>, int> m_soft_connections;
|
||||||
std::list<ClusterInstanceInteraction> m_ci_interactions;
|
std::list<ClusterInstanceInteraction> m_ci_interactions;
|
||||||
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<ClusterIDPair> > 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;
|
bool m_separate_attributes;
|
||||||
|
|
@ -1762,10 +1843,10 @@ private:
|
||||||
interacting_clusters = *cached;
|
interacting_clusters = *cached;
|
||||||
for (cluster_instance_pair_list_type::iterator i = interacting_clusters.begin (); i != interacting_clusters.end (); ++i) {
|
for (cluster_instance_pair_list_type::iterator i = interacting_clusters.begin (); i != interacting_clusters.end (); ++i) {
|
||||||
// translate the property IDs
|
// translate the property IDs
|
||||||
i->first.set_inst_prop_id (i1.prop_id ());
|
i->a.set_inst_prop_id (i1.prop_id ());
|
||||||
i->first.transform (i1t);
|
i->a.transform (i1t);
|
||||||
i->second.set_inst_prop_id (i2.prop_id ());
|
i->b.set_inst_prop_id (i2.prop_id ());
|
||||||
i->second.transform (i2t);
|
i->b.transform (i2t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -1832,23 +1913,23 @@ private:
|
||||||
box_type common12 = ib1 & ib2 & common;
|
box_type common12 = ib1 & ib2 & common;
|
||||||
if (! common12.empty ()) {
|
if (! common12.empty ()) {
|
||||||
|
|
||||||
const std::list<std::pair<size_t, size_t> > &i2i_interactions = compute_instance_interactions (common12, i1.cell_index (), tt1, i2.cell_index (), tt2);
|
const std::list<ClusterIDPair> &i2i_interactions = compute_instance_interactions (common12, i1.cell_index (), tt1, i2.cell_index (), tt2);
|
||||||
|
|
||||||
for (std::list<std::pair<size_t, size_t> >::const_iterator ii = i2i_interactions.begin (); ii != i2i_interactions.end (); ++ii) {
|
for (std::list<ClusterIDPair>::const_iterator ii = i2i_interactions.begin (); ii != i2i_interactions.end (); ++ii) {
|
||||||
ClusterInstance k1 (ii->first, i1.cell_index (), i1t, i1.prop_id ());
|
ClusterInstance k1 (ii->a, i1.cell_index (), i1t, i1.prop_id ());
|
||||||
ClusterInstance k2 (ii->second, i2.cell_index (), i2t, i2.prop_id ());
|
ClusterInstance k2 (ii->b, i2.cell_index (), i2t, i2.prop_id ());
|
||||||
interacting_clusters.push_back (std::make_pair (k1, k2));
|
interacting_clusters.push_back (ClusterInstancePair (k1, k2, ii->soft));
|
||||||
}
|
}
|
||||||
|
|
||||||
// dive into cell of ii2
|
// dive into cell of ii2
|
||||||
const db::Cell &cell2 = mp_layout->cell (i2.cell_index ());
|
const db::Cell &cell2 = mp_layout->cell (i2.cell_index ());
|
||||||
for (db::Cell::touching_iterator jj2 = cell2.begin_touching (common12.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) {
|
for (db::Cell::touching_iterator jj2 = cell2.begin_touching (common12.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) {
|
||||||
|
|
||||||
std::list<std::pair<ClusterInstance, ClusterInstance> > ii_interactions;
|
std::list<ClusterInstancePair> ii_interactions;
|
||||||
consider_instance_pair (common12, i1, t1, ii1, *jj2, tt2, db::CellInstArray::iterator (), ii_interactions);
|
consider_instance_pair (common12, i1, t1, ii1, *jj2, tt2, db::CellInstArray::iterator (), ii_interactions);
|
||||||
|
|
||||||
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator i = ii_interactions.begin (); i != ii_interactions.end (); ++i) {
|
for (std::list<ClusterInstancePair>::iterator i = ii_interactions.begin (); i != ii_interactions.end (); ++i) {
|
||||||
propagate_cluster_inst (i->second, i2.cell_index (), i2t, i2.prop_id ());
|
propagate_cluster_inst (i->b, i2.cell_index (), i2t, i2.prop_id ());
|
||||||
}
|
}
|
||||||
|
|
||||||
ii_interactions.unique ();
|
ii_interactions.unique ();
|
||||||
|
|
@ -1860,11 +1941,11 @@ private:
|
||||||
const db::Cell &cell1 = mp_layout->cell (i1.cell_index ());
|
const db::Cell &cell1 = mp_layout->cell (i1.cell_index ());
|
||||||
for (db::Cell::touching_iterator jj1 = cell1.begin_touching (common12.transformed (tt1.inverted ())); ! jj1.at_end (); ++jj1) {
|
for (db::Cell::touching_iterator jj1 = cell1.begin_touching (common12.transformed (tt1.inverted ())); ! jj1.at_end (); ++jj1) {
|
||||||
|
|
||||||
std::list<std::pair<ClusterInstance, ClusterInstance> > ii_interactions;
|
std::list<ClusterInstancePair> ii_interactions;
|
||||||
consider_instance_pair (common12, *jj1, tt1, db::CellInstArray::iterator (), i2, t2, ii2, ii_interactions);
|
consider_instance_pair (common12, *jj1, tt1, db::CellInstArray::iterator (), i2, t2, ii2, ii_interactions);
|
||||||
|
|
||||||
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator i = ii_interactions.begin (); i != ii_interactions.end (); ++i) {
|
for (std::list<ClusterInstancePair>::iterator i = ii_interactions.begin (); i != ii_interactions.end (); ++i) {
|
||||||
propagate_cluster_inst (i->first, i1.cell_index (), i1t, i1.prop_id ());
|
propagate_cluster_inst (i->a, i1.cell_index (), i1t, i1.prop_id ());
|
||||||
}
|
}
|
||||||
|
|
||||||
ii_interactions.unique ();
|
ii_interactions.unique ();
|
||||||
|
|
@ -1889,7 +1970,7 @@ private:
|
||||||
// remove duplicates (after doing a quick unique before)
|
// remove duplicates (after doing a quick unique before)
|
||||||
// NOTE: duplicates may happen due to manifold child/child interactions which boil down to
|
// NOTE: duplicates may happen due to manifold child/child interactions which boil down to
|
||||||
// identical parent cluster interactions.
|
// identical parent cluster interactions.
|
||||||
std::vector<std::pair<ClusterInstance, ClusterInstance> > sorted_interactions;
|
std::vector<ClusterInstancePair> sorted_interactions;
|
||||||
sorted_interactions.reserve (interacting_clusters.size ());
|
sorted_interactions.reserve (interacting_clusters.size ());
|
||||||
sorted_interactions.insert (sorted_interactions.end (), interacting_clusters.begin (), interacting_clusters.end ());
|
sorted_interactions.insert (sorted_interactions.end (), interacting_clusters.begin (), interacting_clusters.end ());
|
||||||
interacting_clusters.clear ();
|
interacting_clusters.clear ();
|
||||||
|
|
@ -1903,9 +1984,9 @@ private:
|
||||||
|
|
||||||
// normalize transformations for cache
|
// normalize transformations for cache
|
||||||
db::ICplxTrans i1ti = i1t.inverted (), i2ti = i2t.inverted ();
|
db::ICplxTrans i1ti = i1t.inverted (), i2ti = i2t.inverted ();
|
||||||
for (std::vector<std::pair<ClusterInstance, ClusterInstance> >::iterator i = sorted_interactions.begin (); i != sorted_interactions.end (); ++i) {
|
for (std::vector<ClusterInstancePair>::iterator i = sorted_interactions.begin (); i != sorted_interactions.end (); ++i) {
|
||||||
i->first.transform (i1ti);
|
i->a.transform (i1ti);
|
||||||
i->second.transform (i2ti);
|
i->b.transform (i2ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster_instance_pair_list_type &cached = mp_instance_interaction_cache->insert (i1.cell_index (), i2.cell_index (), ii_key);
|
cluster_instance_pair_list_type &cached = mp_instance_interaction_cache->insert (i1.cell_index (), i2.cell_index (), ii_key);
|
||||||
|
|
@ -1917,13 +1998,13 @@ private:
|
||||||
/**
|
/**
|
||||||
* @brief Computes a list of interacting clusters for two instances
|
* @brief Computes a list of interacting clusters for two instances
|
||||||
*/
|
*/
|
||||||
const std::list<std::pair<size_t, size_t> > &
|
const std::list<ClusterIDPair> &
|
||||||
compute_instance_interactions (const box_type &common,
|
compute_instance_interactions (const box_type &common,
|
||||||
db::cell_index_type ci1, const db::ICplxTrans &t1,
|
db::cell_index_type ci1, const db::ICplxTrans &t1,
|
||||||
db::cell_index_type ci2, const db::ICplxTrans &t2)
|
db::cell_index_type ci2, const db::ICplxTrans &t2)
|
||||||
{
|
{
|
||||||
if (is_breakout_cell (mp_breakout_cells, ci1) || is_breakout_cell (mp_breakout_cells, ci2)) {
|
if (is_breakout_cell (mp_breakout_cells, ci1) || is_breakout_cell (mp_breakout_cells, ci2)) {
|
||||||
static const std::list<std::pair<size_t, size_t> > empty;
|
static const std::list<ClusterIDPair> empty;
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1935,7 +2016,7 @@ private:
|
||||||
|
|
||||||
interaction_key_for_clusters<box_type> ikey (t1i, t21, common2);
|
interaction_key_for_clusters<box_type> ikey (t1i, t21, common2);
|
||||||
|
|
||||||
const std::list<std::pair<size_t, size_t> > *ici = m_interaction_cache_for_clusters.find (ci1, ci2, ikey);
|
const std::list<ClusterIDPair> *ici = m_interaction_cache_for_clusters.find (ci1, ci2, ikey);
|
||||||
if (ici) {
|
if (ici) {
|
||||||
|
|
||||||
return *ici;
|
return *ici;
|
||||||
|
|
@ -1947,7 +2028,7 @@ private:
|
||||||
const db::local_clusters<T> &cl1 = mp_tree->clusters_per_cell (ci1);
|
const db::local_clusters<T> &cl1 = mp_tree->clusters_per_cell (ci1);
|
||||||
const db::local_clusters<T> &cl2 = mp_tree->clusters_per_cell (ci2);
|
const db::local_clusters<T> &cl2 = mp_tree->clusters_per_cell (ci2);
|
||||||
|
|
||||||
std::list<std::pair<size_t, size_t> > &new_interactions = m_interaction_cache_for_clusters.insert (ci1, ci2, ikey);
|
std::list<ClusterIDPair> &new_interactions = m_interaction_cache_for_clusters.insert (ci1, ci2, ikey);
|
||||||
db::ICplxTrans t12 = t2i * t1;
|
db::ICplxTrans t12 = t2i * t1;
|
||||||
|
|
||||||
for (typename db::local_clusters<T>::touching_iterator i = cl1.begin_touching (common2.transformed (t21)); ! i.at_end (); ++i) {
|
for (typename db::local_clusters<T>::touching_iterator i = cl1.begin_touching (common2.transformed (t21)); ! i.at_end (); ++i) {
|
||||||
|
|
@ -1962,8 +2043,7 @@ private:
|
||||||
|
|
||||||
int soft = 0;
|
int soft = 0;
|
||||||
if ((! m_separate_attributes || i->same_attrs (*j)) && i->interacts (*j, t21, *mp_conn, soft)) {
|
if ((! m_separate_attributes || i->same_attrs (*j)) && i->interacts (*j, t21, *mp_conn, soft)) {
|
||||||
// @@@ soft mode?
|
new_interactions.push_back (ClusterIDPair (i->id (), j->id (), soft));
|
||||||
new_interactions.push_back (std::make_pair (i->id (), j->id ()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2015,22 +2095,22 @@ private:
|
||||||
cluster_instance_pair_list_type interacting_clusters;
|
cluster_instance_pair_list_type interacting_clusters;
|
||||||
|
|
||||||
box_type common = (ib & ib2);
|
box_type common = (ib & ib2);
|
||||||
const std::list<std::pair<size_t, size_t> > &i2i_interactions = compute_instance_interactions (common, i.cell_index (), tt, i.cell_index (), tt2);
|
const std::list<ClusterIDPair> &i2i_interactions = compute_instance_interactions (common, i.cell_index (), tt, i.cell_index (), tt2);
|
||||||
for (std::list<std::pair<size_t, size_t> >::const_iterator ii = i2i_interactions.begin (); ii != i2i_interactions.end (); ++ii) {
|
for (std::list<ClusterIDPair>::const_iterator ii = i2i_interactions.begin (); ii != i2i_interactions.end (); ++ii) {
|
||||||
ClusterInstance k1 (ii->first, i.cell_index (), tt, i.prop_id ());
|
ClusterInstance k1 (ii->a, i.cell_index (), tt, i.prop_id ());
|
||||||
ClusterInstance k2 (ii->second, i.cell_index (), tt2, i.prop_id ());
|
ClusterInstance k2 (ii->b, i.cell_index (), tt2, i.prop_id ());
|
||||||
interacting_clusters.push_back (std::make_pair (k1, k2));
|
interacting_clusters.push_back (ClusterInstancePair (k1, k2, ii->soft));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (db::Cell::touching_iterator jj2 = cell.begin_touching (common.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) {
|
for (db::Cell::touching_iterator jj2 = cell.begin_touching (common.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) {
|
||||||
|
|
||||||
db::ICplxTrans t;
|
db::ICplxTrans t;
|
||||||
|
|
||||||
std::list<std::pair<ClusterInstance, ClusterInstance> > ii_interactions;
|
std::list<ClusterInstancePair> ii_interactions;
|
||||||
consider_instance_pair (common, i, t, ii, *jj2, tt2, db::CellInstArray::iterator (), ii_interactions);
|
consider_instance_pair (common, i, t, ii, *jj2, tt2, db::CellInstArray::iterator (), ii_interactions);
|
||||||
|
|
||||||
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator ii = ii_interactions.begin (); ii != ii_interactions.end (); ++ii) {
|
for (std::list<ClusterInstancePair>::iterator ii = ii_interactions.begin (); ii != ii_interactions.end (); ++ii) {
|
||||||
propagate_cluster_inst (ii->second, i.cell_index (), tt2, i.prop_id ());
|
propagate_cluster_inst (ii->b, i.cell_index (), tt2, i.prop_id ());
|
||||||
}
|
}
|
||||||
|
|
||||||
interacting_clusters.splice (interacting_clusters.end (), ii_interactions, ii_interactions.begin (), ii_interactions.end ());
|
interacting_clusters.splice (interacting_clusters.end (), ii_interactions, ii_interactions.begin (), ii_interactions.end ());
|
||||||
|
|
@ -2051,6 +2131,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2077,7 +2158,7 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<size_t, size_t> > c2i_interactions;
|
std::vector<ClusterIDPair> c2i_interactions;
|
||||||
|
|
||||||
for (db::CellInstArray::iterator ii2 = i2.begin_touching ((b1 & b2).transformed (t2.inverted ()), mp_layout); ! ii2.at_end (); ++ii2) {
|
for (db::CellInstArray::iterator ii2 = i2.begin_touching ((b1 & b2).transformed (t2.inverted ()), mp_layout); ! ii2.at_end (); ++ii2) {
|
||||||
|
|
||||||
|
|
@ -2090,9 +2171,9 @@ private:
|
||||||
c2i_interactions.clear ();
|
c2i_interactions.clear ();
|
||||||
compute_cluster_instance_interactions (c1, i2.cell_index (), tt2, c2i_interactions);
|
compute_cluster_instance_interactions (c1, i2.cell_index (), tt2, c2i_interactions);
|
||||||
|
|
||||||
for (std::vector<std::pair<size_t, size_t> >::const_iterator ii = c2i_interactions.begin (); ii != c2i_interactions.end (); ++ii) {
|
for (std::vector<ClusterIDPair>::const_iterator ii = c2i_interactions.begin (); ii != c2i_interactions.end (); ++ii) {
|
||||||
ClusterInstance k (ii->second, i2.cell_index (), i2t, i2.prop_id ());
|
ClusterInstance k (ii->b, i2.cell_index (), i2t, i2.prop_id ());
|
||||||
interactions_out.push_back (ClusterInstanceInteraction (ii->first, k));
|
interactions_out.push_back (ClusterInstanceInteraction (ii->a, k, ii->soft));
|
||||||
}
|
}
|
||||||
|
|
||||||
// dive into cell of ii2
|
// dive into cell of ii2
|
||||||
|
|
@ -2124,7 +2205,7 @@ private:
|
||||||
void
|
void
|
||||||
compute_cluster_instance_interactions (const local_cluster<T> &c1,
|
compute_cluster_instance_interactions (const local_cluster<T> &c1,
|
||||||
db::cell_index_type ci2, const db::ICplxTrans &t2,
|
db::cell_index_type ci2, const db::ICplxTrans &t2,
|
||||||
std::vector<std::pair<size_t, size_t> > &interactions)
|
std::vector<ClusterIDPair> &interactions)
|
||||||
{
|
{
|
||||||
if (is_breakout_cell (mp_breakout_cells, ci2)) {
|
if (is_breakout_cell (mp_breakout_cells, ci2)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -2136,11 +2217,7 @@ private:
|
||||||
|
|
||||||
int soft = 0;
|
int soft = 0;
|
||||||
if ((! m_separate_attributes || c1.same_attrs (*j)) && c1.interacts (*j, t2, *mp_conn, soft)) {
|
if ((! m_separate_attributes || c1.same_attrs (*j)) && c1.interacts (*j, t2, *mp_conn, soft)) {
|
||||||
if (soft != 0) {
|
interactions.push_back (ClusterIDPair (c1.id (), j->id (), soft));
|
||||||
// @@@ TODO: soft mode
|
|
||||||
} else {
|
|
||||||
interactions.push_back (std::make_pair (c1.id (), j->id ()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2243,8 +2320,8 @@ private:
|
||||||
{
|
{
|
||||||
for (cluster_instance_pair_list_type::const_iterator ic = interacting_clusters.begin (); ic != interacting_clusters.end (); ++ic) {
|
for (cluster_instance_pair_list_type::const_iterator ic = interacting_clusters.begin (); ic != interacting_clusters.end (); ++ic) {
|
||||||
|
|
||||||
const ClusterInstance &k1 = ic->first;
|
const ClusterInstance &k1 = ic->a;
|
||||||
const ClusterInstance &k2 = ic->second;
|
const ClusterInstance &k2 = ic->b;
|
||||||
|
|
||||||
// Note: "with_self" is false as we're going to create a connected cluster anyway
|
// Note: "with_self" is false as we're going to create a connected cluster anyway
|
||||||
id_type x1 = mp_tree->propagate_cluster_inst (*mp_layout, *mp_cell, k1, mp_cell->cell_index (), false);
|
id_type x1 = mp_tree->propagate_cluster_inst (*mp_layout, *mp_cell, k1, mp_cell->cell_index (), false);
|
||||||
|
|
@ -2254,33 +2331,101 @@ private:
|
||||||
|
|
||||||
if (x2 == 0) {
|
if (x2 == 0) {
|
||||||
|
|
||||||
|
if (ic->soft != 0) {
|
||||||
|
|
||||||
|
id_type ca = mp_cell_clusters->insert_dummy ();
|
||||||
|
id_type cb = mp_cell_clusters->insert_dummy ();
|
||||||
|
mp_cell_clusters->add_connection (ca, k1);
|
||||||
|
mp_cell_clusters->add_connection (cb, k2);
|
||||||
|
|
||||||
|
register_soft_connection (ca, cb, ic->soft);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
id_type connector = mp_cell_clusters->insert_dummy ();
|
id_type connector = mp_cell_clusters->insert_dummy ();
|
||||||
mp_cell_clusters->add_connection (connector, k1);
|
mp_cell_clusters->add_connection (connector, k1);
|
||||||
mp_cell_clusters->add_connection (connector, k2);
|
mp_cell_clusters->add_connection (connector, k2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (ic->soft != 0) {
|
||||||
|
|
||||||
|
id_type ca = mp_cell_clusters->insert_dummy ();
|
||||||
|
mp_cell_clusters->add_connection (ca, k1);
|
||||||
|
|
||||||
|
register_soft_connection (ca, x2, ic->soft);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
mp_cell_clusters->add_connection (x2, k1);
|
mp_cell_clusters->add_connection (x2, k1);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (x2 == 0) {
|
} else if (x2 == 0) {
|
||||||
|
|
||||||
|
if (ic->soft != 0) {
|
||||||
|
|
||||||
|
id_type cb = mp_cell_clusters->insert_dummy ();
|
||||||
|
mp_cell_clusters->add_connection (cb, k2);
|
||||||
|
|
||||||
|
register_soft_connection (x1, cb, ic->soft);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
mp_cell_clusters->add_connection (x1, k2);
|
mp_cell_clusters->add_connection (x1, k2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else if (x1 != x2) {
|
} else if (x1 != x2) {
|
||||||
|
|
||||||
|
int soft = ic->soft;
|
||||||
|
|
||||||
// for instance-to-instance interactions the number of connections is more important for the
|
// for instance-to-instance interactions the number of connections is more important for the
|
||||||
// cost of the join operation: make the one with more connections the target
|
// cost of the join operation: make the one with more connections the target
|
||||||
// TODO: this will be SLOW for STL's not providing a fast size()
|
// TODO: this will be SLOW for STL's not providing a fast size()
|
||||||
if (mp_cell_clusters->connections_for_cluster (x1).size () < mp_cell_clusters->connections_for_cluster (x2).size ()) {
|
if (mp_cell_clusters->connections_for_cluster (x1).size () < mp_cell_clusters->connections_for_cluster (x2).size ()) {
|
||||||
std::swap (x1, x2);
|
std::swap (x1, x2);
|
||||||
|
soft = -soft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (soft != 0) {
|
||||||
|
|
||||||
|
register_soft_connection (x1, x2, soft);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
mp_cell_clusters->join_cluster_with (x1, x2);
|
mp_cell_clusters->join_cluster_with (x1, x2);
|
||||||
mp_cell_clusters->remove_cluster (x2);
|
mp_cell_clusters->remove_cluster (x2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers a soft connection for clusters a and b
|
||||||
|
*/
|
||||||
|
void register_soft_connection (id_type a, id_type b, int soft)
|
||||||
|
{
|
||||||
|
std::pair<size_t, size_t> key (a < b ? a : b, a < b ? b : a);
|
||||||
|
if (!(a < b)) {
|
||||||
|
soft = -soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sc = m_soft_connections.find (key);
|
||||||
|
if (sc != m_soft_connections.end ()) {
|
||||||
|
if (sc->second != 0 && sc->second != soft) {
|
||||||
|
sc->second = 0; // turn into hard connection
|
||||||
|
mark_to_join (a, b);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_soft_connections [key] = soft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -622,6 +622,11 @@ public:
|
||||||
return id > m_clusters.size ();
|
return id > m_clusters.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Makes a soft connection between clusters a and b (a: upper, b: lower)
|
||||||
|
*/
|
||||||
|
void make_soft_connection (typename local_cluster<T>::id_type a, typename local_cluster<T>::id_type b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the number of clusters
|
* @brief Gets the number of clusters
|
||||||
*/
|
*/
|
||||||
|
|
@ -844,7 +849,61 @@ private:
|
||||||
size_t m_id;
|
size_t m_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<std::pair<ClusterInstance, ClusterInstance> > cluster_instance_pair_list_type;
|
struct ClusterInstancePair
|
||||||
|
{
|
||||||
|
ClusterInstancePair (const ClusterInstance &_a, const ClusterInstance &_b, int _soft)
|
||||||
|
: a (_a), b (_b), soft (_soft)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool operator== (const ClusterInstancePair &other) const
|
||||||
|
{
|
||||||
|
return a == other.a && b == other.b && soft == other.soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator< (const ClusterInstancePair &other) const
|
||||||
|
{
|
||||||
|
if (!(a == other.a)) {
|
||||||
|
return a < other.a;
|
||||||
|
}
|
||||||
|
if (!(b == other.b)) {
|
||||||
|
return b < other.b;
|
||||||
|
}
|
||||||
|
return soft < other.soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClusterInstance a, b;
|
||||||
|
int soft;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::list<ClusterInstancePair> cluster_instance_pair_list_type;
|
||||||
|
|
||||||
|
struct ClusterIDPair
|
||||||
|
{
|
||||||
|
typedef size_t id_type;
|
||||||
|
|
||||||
|
ClusterIDPair (id_type _a, id_type _b, int _soft)
|
||||||
|
: a (_a), b (_b), soft (_soft)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool operator== (const ClusterIDPair &other) const
|
||||||
|
{
|
||||||
|
return a == other.a && b == other.b && soft == other.soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator< (const ClusterIDPair &other) const
|
||||||
|
{
|
||||||
|
if (!(a == other.a)) {
|
||||||
|
return a < other.a;
|
||||||
|
}
|
||||||
|
if (!(b == other.b)) {
|
||||||
|
return b < other.b;
|
||||||
|
}
|
||||||
|
return soft < other.soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
id_type a, b;
|
||||||
|
int soft;
|
||||||
|
};
|
||||||
|
|
||||||
inline bool equal_array_delegates (const db::ArrayBase *a, const db::ArrayBase *b)
|
inline bool equal_array_delegates (const db::ArrayBase *a, const db::ArrayBase *b)
|
||||||
{
|
{
|
||||||
|
|
@ -1156,7 +1215,7 @@ public:
|
||||||
* The "with_id" cluster is removed. All connections of "with_id" are transferred to the
|
* The "with_id" cluster is removed. All connections of "with_id" are transferred to the
|
||||||
* first one. All shapes of "with_id" are transferred to "id".
|
* first one. All shapes of "with_id" are transferred to "id".
|
||||||
*/
|
*/
|
||||||
void join_cluster_with(typename local_cluster<T>::id_type id, typename local_cluster<T>::id_type with_id);
|
void join_cluster_with (typename local_cluster<T>::id_type id, typename local_cluster<T>::id_type with_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An iterator delivering all clusters (even the connectors)
|
* @brief An iterator delivering all clusters (even the connectors)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue