WIP: preparations for multi-input/multi-output local processor.

This commit is contained in:
Matthias Koefferlein 2020-06-07 18:04:30 +02:00
parent 689b3c5af9
commit 96caa646f5
9 changed files with 412 additions and 243 deletions

View File

@ -1041,14 +1041,17 @@ public:
return 1;
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front ();
db::box_scanner<db::Edge, size_t> scanner;
std::set<db::Edge> others;
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1116,14 +1119,17 @@ public:
return 1;
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front ();
db::box_scanner<db::Edge, size_t> scanner;
std::set<db::Edge> others;
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1168,14 +1174,17 @@ public:
return 1;
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front ();
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner;
std::set<db::PolygonRef> others;
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Edge, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1264,14 +1273,17 @@ public:
return 1;
}
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner;
std::set<db::PolygonRef> others;
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Edge, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1427,8 +1439,11 @@ public:
// .. nothing yet ..
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::EdgePair> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::EdgePair> &result = results.front ();
edge2edge_check_for_edges<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_has_other);
db::box_scanner<db::Edge, size_t> scanner;
@ -1438,7 +1453,7 @@ public:
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1460,7 +1475,7 @@ public:
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
others.insert (interactions.subject_shape (i->first));
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}

View File

@ -1267,8 +1267,11 @@ public:
// .. nothing yet ..
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::EdgePair> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::EdgePair> &result = results.front ();
edge2edge_check<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_different_polygons, m_has_other, true /*shielded*/);
poly2poly_check<std::unordered_set<db::EdgePair> > poly_check (edge_check);
@ -1280,7 +1283,7 @@ public:
std::set<db::PolygonRef> others;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1305,7 +1308,7 @@ public:
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
polygons.insert (interactions.subject_shape (i->first));
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
polygons.insert (interactions.intruder_shape (*j));
polygons.insert (interactions.intruder_shape (*j).second);
}
}
@ -1443,14 +1446,17 @@ public:
return m_touching ? 1 : 0;
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
db::EdgeProcessor ep;
std::set<db::PolygonRef> others;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1525,14 +1531,17 @@ public:
return m_touching ? 1 : 0;
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
db::EdgeProcessor ep;
std::set<db::PolygonRef> others;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -1641,8 +1650,11 @@ public:
return 1;
}
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::Edge> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::Edge> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
db::box_scanner2<db::Polygon, size_t, db::Edge, size_t> scanner;
ResultInserter inserter (layout, result);
@ -1650,7 +1662,7 @@ public:
for (shape_interactions<db::PolygonRef, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
scanner.insert2 (& interactions.intruder_shape (*j), 0);
scanner.insert2 (& interactions.intruder_shape (*j).second, 0);
}
}
@ -1706,8 +1718,11 @@ public:
return 1;
}
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front ();
db::box_scanner2<db::Polygon, size_t, db::Edge, size_t> scanner;
EdgeResultInserter inserter (result);
@ -1715,7 +1730,7 @@ public:
for (shape_interactions<db::PolygonRef, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
scanner.insert2 (& interactions.intruder_shape (*j), 0);
scanner.insert2 (& interactions.intruder_shape (*j).second, 0);
}
}
@ -1777,8 +1792,11 @@ public:
return 1;
}
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::unordered_set<db::TextRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::vector<std::unordered_set<db::TextRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::TextRef> &result = results.front ();
db::box_scanner2<db::Polygon, size_t, db::TextRef, size_t> scanner;
TextResultInserter inserter (result);
@ -1786,7 +1804,7 @@ public:
for (shape_interactions<db::PolygonRef, db::TextRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::TextRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
scanner.insert2 (& interactions.intruder_shape (*j), 0);
scanner.insert2 (& interactions.intruder_shape (*j).second, 0);
}
}
@ -1830,8 +1848,11 @@ public:
return 1;
}
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
db::box_scanner2<db::Polygon, size_t, db::TextRef, size_t> scanner;
ResultInserter inserter (layout, result);
@ -1839,7 +1860,7 @@ public:
for (shape_interactions<db::PolygonRef, db::Text>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::Text>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
scanner.insert2 (& interactions.intruder_shape (*j), 0);
scanner.insert2 (& interactions.intruder_shape (*j).second, 0);
}
}

View File

@ -428,14 +428,17 @@ public:
return 1;
}
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::unordered_set<db::TextRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::TextRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::TextRef> &result = results.front ();
db::box_scanner2<db::TextRef, size_t, db::Polygon, size_t> scanner;
std::set<db::PolygonRef> others;
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -524,14 +527,17 @@ public:
return 1;
}
virtual void compute_local (db::Layout *layout, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void compute_local (db::Layout *layout, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
db::box_scanner2<db::TextRef, size_t, db::Polygon, size_t> scanner;
std::set<db::PolygonRef> others;
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}

View File

@ -420,6 +420,23 @@ namespace std
return hf;
}
};
/**
* @brief Generic hash for an ordered map
*/
template <class T1, class T2>
struct hash<std::map<T1, T2> >
{
size_t operator() (const std::map<T1, T2> &o) const
{
size_t hf = 0;
for (typename std::map<T1, T2>::const_iterator i = o.begin (); i != o.end (); ++i) {
hf = hfunc (hf, std::hash <T1> () (i->first));
hf = hfunc (hf, std::hash <T2> () (i->second));
}
return hf;
}
};
}
#endif

View File

@ -286,7 +286,7 @@ local_processor_cell_context<TS, TI, TR>::add (db::local_processor_cell_context<
template <class TS, class TI, class TR>
void
local_processor_cell_context<TS, TI, TR>::propagate (const std::unordered_set<TR> &res)
local_processor_cell_context<TS, TI, TR>::propagate (unsigned int output_layer, const std::unordered_set<TR> &res)
{
if (res.empty ()) {
return;
@ -307,7 +307,7 @@ local_processor_cell_context<TS, TI, TR>::propagate (const std::unordered_set<TR
{
tl::MutexLocker locker (&d->parent_context->lock ());
d->parent_context->propagated ().insert (new_refs.begin (), new_refs.end ());
d->parent_context->propagated (output_layer).insert (new_refs.begin (), new_refs.end ());
}
}
@ -418,12 +418,13 @@ struct context_sorter
template <class TS, class TI, class TR>
void
local_processor_cell_contexts<TS, TI, TR>::compute_results (const local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, const local_operation<TS, TI, TR> *op, unsigned int output_layer, const local_processor<TS, TI, TR> *proc)
local_processor_cell_contexts<TS, TI, TR>::compute_results (const local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers, const local_processor<TS, TI, TR> *proc)
{
CRONOLOGY_COMPUTE_BRACKET(event_compute_results)
bool first = true;
std::unordered_set<TR> common;
std::vector<std::unordered_set<TR> > common;
common.resize (output_layers.size ());
int index = 0;
int total = int (m_contexts.size ());
@ -452,7 +453,9 @@ local_processor_cell_contexts<TS, TI, TR>::compute_results (const local_processo
{
tl::MutexLocker locker (&c->second->lock ());
common = c->second->propagated ();
for (std::vector<unsigned int>::const_iterator o = output_layers.begin (); o != output_layers.end (); ++o) {
common [o - output_layers.begin ()] = c->second->propagated (*o);
}
}
CRONOLOGY_COMPUTE_BRACKET(event_compute_local_cell)
@ -461,10 +464,14 @@ local_processor_cell_contexts<TS, TI, TR>::compute_results (const local_processo
} else {
std::unordered_set<TR> res;
std::vector<std::unordered_set<TR> > res;
res.resize (output_layers.size ());
{
tl::MutexLocker locker (&c->second->lock ());
res = c->second->propagated ();
for (std::vector<unsigned int>::const_iterator o = output_layers.begin (); o != output_layers.end (); ++o) {
res [o - output_layers.begin ()] = c->second->propagated (*o);
}
}
{
@ -475,7 +482,9 @@ local_processor_cell_contexts<TS, TI, TR>::compute_results (const local_processo
if (common.empty ()) {
CRONOLOGY_COMPUTE_BRACKET(event_propagate)
c->second->propagate (res);
for (std::vector<unsigned int>::const_iterator o = output_layers.begin (); o != output_layers.end (); ++o) {
c->second->propagate (*o, res [o - output_layers.begin ()]);
}
// gcc 4.4.7 (at least) doesn't have an operator== in std::unordered_set, so we skip this
// optimization
@ -487,39 +496,52 @@ local_processor_cell_contexts<TS, TI, TR>::compute_results (const local_processo
CRONOLOGY_COMPUTE_BRACKET(event_propagate)
std::unordered_set<TR> lost;
for (typename std::unordered_set<TR>::const_iterator i = common.begin (); i != common.end (); ++i) {
if (res.find (*i) == res.end ()) {
lost.insert (*i);
}
}
for (std::vector<unsigned int>::const_iterator o = output_layers.begin (); o != output_layers.end (); ++o) {
if (! lost.empty ()) {
size_t oi = o - output_layers.begin ();
subtract (lost, res, cell->layout (), proc);
std::unordered_set<TR> lost;
if (! lost.empty ()) {
subtract (common, lost, cell->layout (), proc);
for (typename std::vector<std::pair<const context_key_type *, db::local_processor_cell_context<TS, TI, TR> *> >::const_iterator cc = sorted_contexts.begin (); cc != c; ++cc) {
cc->second->propagate (lost);
for (typename std::unordered_set<TR>::const_iterator i = common[oi].begin (); i != common[oi].end (); ++i) {
if (res[oi].find (*i) == res[oi].end ()) {
lost.insert (*i);
}
}
}
if (! lost.empty ()) {
subtract (lost, res[oi], cell->layout (), proc);
if (! lost.empty ()) {
subtract (common[oi], lost, cell->layout (), proc);
for (typename std::vector<std::pair<const context_key_type *, db::local_processor_cell_context<TS, TI, TR> *> >::const_iterator cc = sorted_contexts.begin (); cc != c; ++cc) {
cc->second->propagate (*o, lost);
}
}
std::unordered_set<TR> gained;
for (typename std::unordered_set<TR>::const_iterator i = res.begin (); i != res.end (); ++i) {
if (common.find (*i) == common.end ()) {
gained.insert (*i);
}
}
if (! gained.empty ()) {
for (std::vector<unsigned int>::const_iterator o = output_layers.begin (); o != output_layers.end (); ++o) {
subtract (gained, common, cell->layout (), proc);
std::unordered_set<TR> gained;
size_t oi = o - output_layers.begin ();
for (typename std::unordered_set<TR>::const_iterator i = res[oi].begin (); i != res[oi].end (); ++i) {
if (common[oi].find (*i) == common[oi].end ()) {
gained.insert (*i);
}
}
if (! gained.empty ()) {
c->second->propagate (gained);
subtract (gained, common[oi], cell->layout (), proc);
if (! gained.empty ()) {
c->second->propagate (*o, gained);
}
}
}
@ -530,7 +552,10 @@ local_processor_cell_contexts<TS, TI, TR>::compute_results (const local_processo
}
proc->push_results (cell, output_layer, common);
for (std::vector<unsigned int>::const_iterator o = output_layers.begin (); o != output_layers.end (); ++o) {
size_t oi = o - output_layers.begin ();
proc->push_results (cell, *o, common[oi]);
}
}
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
@ -565,9 +590,9 @@ shape_interactions<TS, TI>::has_subject_shape_id (unsigned int id) const
template <class TS, class TI>
void
shape_interactions<TS, TI>::add_intruder_shape (unsigned int id, const TI &shape)
shape_interactions<TS, TI>::add_intruder_shape (unsigned int id, unsigned int layer, const TI &shape)
{
m_intruder_shapes [id] = shape;
m_intruder_shapes [id] = std::make_pair (layer, shape);
}
template <class TS, class TI>
@ -619,12 +644,12 @@ shape_interactions<TS, TI>::subject_shape (unsigned int id) const
}
template <class TS, class TI>
const TI &
const std::pair<unsigned int, TI> &
shape_interactions<TS, TI>::intruder_shape (unsigned int id) const
{
typename std::unordered_map<unsigned int, TI>::const_iterator i = m_intruder_shapes.find (id);
typename std::unordered_map<unsigned int, std::pair<unsigned int, TI> >::const_iterator i = m_intruder_shapes.find (id);
if (i == m_intruder_shapes.end ()) {
static TI s;
static std::pair<unsigned int, TI> s;
return s;
} else {
return i->second;
@ -670,8 +695,8 @@ struct interaction_registration_shape2shape
: db::box_scanner_receiver2<TS, unsigned int, TI, unsigned int>
{
public:
interaction_registration_shape2shape (db::Layout *layout, shape_interactions<TS, TI> *result)
: mp_result (result), mp_layout (layout)
interaction_registration_shape2shape (db::Layout *layout, shape_interactions<TS, TI> *result, unsigned int intruder_layer)
: mp_result (result), mp_layout (layout), m_intruder_layer (intruder_layer)
{
// nothing yet ..
}
@ -685,10 +710,10 @@ public:
// rewrite them
if (!mp_result->has_intruder_shape_id (id2)) {
db::shape_reference_translator<TI> rt (mp_layout);
mp_result->add_intruder_shape (id2, rt (*ref2));
mp_result->add_intruder_shape (id2, m_intruder_layer, rt (*ref2));
}
} else {
mp_result->add_intruder_shape (id2, *ref2);
mp_result->add_intruder_shape (id2, m_intruder_layer, *ref2);
}
mp_result->add_interaction (id1, id2);
@ -697,6 +722,7 @@ public:
private:
shape_interactions<TS, TI> *mp_result;
db::Layout *mp_layout;
unsigned int m_intruder_layer;
};
template <class TS, class TI>
@ -704,8 +730,8 @@ struct interaction_registration_shape1
: db::box_scanner_receiver2<TS, unsigned int, TI, unsigned int>
{
public:
interaction_registration_shape1 (shape_interactions<TS, TI> *result)
: mp_result (result)
interaction_registration_shape1 (shape_interactions<TS, TI> *result, unsigned int intruder_layer)
: mp_result (result), m_intruder_layer (intruder_layer)
{
// nothing yet ..
}
@ -713,12 +739,13 @@ public:
void add (const TS *ref1, unsigned int id1, const TI *ref2, unsigned int id2)
{
mp_result->add_subject_shape (id1, *ref1);
mp_result->add_intruder_shape (id2, *ref2);
mp_result->add_intruder_shape (id2, m_intruder_layer, *ref2);
mp_result->add_interaction (id1, id2);
}
private:
shape_interactions<TS, TI> *mp_result;
unsigned int m_intruder_layer;
};
template <class T>
@ -726,8 +753,8 @@ struct interaction_registration_shape1<T, T>
: db::box_scanner_receiver<T, unsigned int>
{
public:
interaction_registration_shape1 (shape_interactions<T, T> *result)
: mp_result (result)
interaction_registration_shape1 (shape_interactions<T, T> *result, unsigned int intruder_layer)
: mp_result (result), m_intruder_layer (intruder_layer)
{
// nothing yet ..
}
@ -735,12 +762,13 @@ public:
void add (const T *ref1, unsigned int id1, const T *ref2, unsigned int id2)
{
mp_result->add_subject_shape (id1, *ref1);
mp_result->add_intruder_shape (id2, *ref2);
mp_result->add_intruder_shape (id2, m_intruder_layer, *ref2);
mp_result->add_interaction (id1, id2);
}
private:
shape_interactions<T, T> *mp_result;
unsigned int m_intruder_layer;
};
template <class TS, class TI>
@ -801,7 +829,7 @@ private:
if (k == m_inst_shape_ids.end ()) {
k = m_inst_shape_ids.insert (std::make_pair (ref2, mp_result->next_id ())).first;
mp_result->add_intruder_shape (k->second, ref2);
mp_result->add_intruder_shape (k->second, m_intruder_layer, ref2);
}
@ -883,7 +911,7 @@ struct interaction_registration_inst2inst
: db::box_scanner_receiver2<db::CellInstArray, unsigned int, db::CellInstArray, unsigned int>
{
public:
typedef std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<T> > interaction_value_type;
typedef std::pair<std::unordered_set<const db::CellInstArray *>, std::map<unsigned int, std::unordered_set<T> > > interaction_value_type;
interaction_registration_inst2inst (const db::Layout *subject_layout, unsigned int subject_layer, const db::Layout *intruder_layout, unsigned int intruder_layer, db::Coord dist, std::unordered_map<const db::CellInstArray *, interaction_value_type> *result)
: mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), m_subject_layer (subject_layer), m_intruder_layer (intruder_layer), m_dist (dist), mp_result (result)
@ -918,7 +946,7 @@ private:
const db::Layout *mp_subject_layout, *mp_intruder_layout;
unsigned int m_subject_layer, m_intruder_layer;
db::Coord m_dist;
std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<T> > > *mp_result;
std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::map<unsigned int, std::unordered_set<T> > > > *mp_result;
std::unordered_set<std::pair<unsigned int, unsigned int> > m_interactions;
};
@ -959,16 +987,16 @@ struct interaction_registration_inst2shape
: db::box_scanner_receiver2<db::CellInstArray, unsigned int, T, unsigned int>
{
public:
interaction_registration_inst2shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<T> > > *result)
interaction_registration_inst2shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::map<unsigned int, std::unordered_set<T> > > > *result)
: mp_subject_layout (subject_layout), m_subject_layer (subject_layer), m_dist (dist), mp_result (result)
{
// nothing yet ..
}
void add (const db::CellInstArray *inst, unsigned int, const T *ref, unsigned int)
void add (const db::CellInstArray *inst, unsigned int, const T *ref, unsigned int layer)
{
if (instance_shape_interacts (mp_subject_layout, inst, m_subject_layer, *ref, m_dist)) {
(*mp_result) [inst].second.insert (*ref);
(*mp_result) [inst].second [layer].insert (*ref);
}
}
@ -976,7 +1004,7 @@ private:
const db::Layout *mp_subject_layout;
unsigned int m_subject_layer;
db::Coord m_dist;
std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<T> > > *mp_result;
std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::map<unsigned int, std::unordered_set<T> > > > *mp_result;
};
}
@ -1013,8 +1041,8 @@ template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::
// LocalProcessorResultComputationTask implementation
template <class TS, class TI, class TR>
local_processor_result_computation_task<TS, TI, TR>::local_processor_result_computation_task (const local_processor<TS, TI, TR> *proc, local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, local_processor_cell_contexts<TS, TI, TR> *cell_contexts, const local_operation<TS, TI, TR> *op, unsigned int output_layer)
: mp_proc (proc), mp_contexts (&contexts), mp_cell (cell), mp_cell_contexts (cell_contexts), mp_op (op), m_output_layer (output_layer)
local_processor_result_computation_task<TS, TI, TR>::local_processor_result_computation_task (const local_processor<TS, TI, TR> *proc, local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, local_processor_cell_contexts<TS, TI, TR> *cell_contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers)
: mp_proc (proc), mp_contexts (&contexts), mp_cell (cell), mp_cell_contexts (cell_contexts), mp_op (op), m_output_layers (output_layers)
{
// .. nothing yet ..
}
@ -1023,7 +1051,7 @@ template <class TS, class TI, class TR>
void
local_processor_result_computation_task<TS, TI, TR>::perform ()
{
mp_cell_contexts->compute_results (*mp_contexts, mp_cell, mp_op, m_output_layer, mp_proc);
mp_cell_contexts->compute_results (*mp_contexts, mp_cell, mp_op, m_output_layers, mp_proc);
// erase the contexts we don't need any longer
{
@ -1116,12 +1144,29 @@ size_t local_processor<TS, TI, TR>::get_progress () const
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer)
{
std::vector<unsigned int> ol, il;
ol.push_back (output_layer);
il.push_back (intruder_layer);
run (op, subject_layer, il, ol);
}
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, unsigned int output_layer)
{
std::vector<unsigned int> ol;
ol.push_back (output_layer);
run (op, subject_layer, intruder_layers, ol);
}
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers)
{
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Executing ")) + description (op));
local_processor_contexts<TS, TI, TR> contexts;
compute_contexts (contexts, op, subject_layer, intruder_layer);
compute_results (contexts, op, output_layer);
compute_contexts (contexts, op, subject_layer, intruder_layers);
compute_results (contexts, op, output_layers);
}
template <class TS, class TI, class TR>
@ -1134,7 +1179,7 @@ void local_processor<TS, TI, TR>::push_results (db::Cell *cell, unsigned int out
}
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer) const
void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers) const
{
try {
@ -1147,7 +1192,7 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
}
contexts.clear ();
contexts.set_intruder_layer (intruder_layer);
contexts.set_intruder_layers (intruder_layers);
contexts.set_subject_layer (subject_layer);
typename local_processor_cell_contexts<TS, TI, TR>::context_key_type intruders;
@ -1244,21 +1289,24 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
// perform the actual task ..
CRONOLOGY_COLLECTION_BRACKET(event_compute_contexts_unlocked)
const db::Shapes *intruder_shapes = 0;
std::map<unsigned int, const db::Shapes *> intruder_shapes;
if (intruder_cell) {
intruder_shapes = &intruder_cell->shapes (contexts.intruder_layer ());
for (std::vector<unsigned int>::const_iterator l = contexts.intruder_layers ().begin (); l != contexts.intruder_layers ().end (); ++l) {
const db::Shapes *s = &intruder_cell->shapes (*l);
if (! s->empty ()) {
intruder_shapes.insert (std::make_pair (*l, s));
}
}
}
db::box_convert <db::CellInstArray, true> inst_bcs (*mp_subject_layout, contexts.subject_layer ());
db::box_convert <db::CellInstArray, true> inst_bci (*mp_intruder_layout, contexts.intruder_layer ());
db::box_convert <db::CellInst, true> inst_bcii (*mp_intruder_layout, contexts.intruder_layer ());
// handle top-down interactions (subject instances interacting with intruder shapes)
// and sibling interactions
if (! subject_cell->begin ().at_end ()) {
typedef std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<TI> > interaction_value_type;
typedef std::pair<std::unordered_set<const db::CellInstArray *>, std::map<unsigned int, std::unordered_set<TI> > > interaction_value_type;
std::unordered_map<const db::CellInstArray *, interaction_value_type> interactions;
@ -1272,9 +1320,12 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
}
// TODO: can we shortcut this if interactions is empty?
{
for (std::vector<unsigned int>::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) {
db::box_convert <db::CellInstArray, true> inst_bci (*mp_intruder_layout, *il);
db::box_scanner2<db::CellInstArray, int, db::CellInstArray, int> scanner;
interaction_registration_inst2inst<TI> rec (mp_subject_layout, contexts.subject_layer (), mp_intruder_layout, contexts.intruder_layer (), dist, &interactions);
interaction_registration_inst2inst<TI> rec (mp_subject_layout, contexts.subject_layer (), mp_intruder_layout, *il, dist, &interactions);
unsigned int id = 0;
@ -1318,6 +1369,7 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
}
scanner.process (rec, dist, inst_bcs, inst_bci);
}
// TODO: can we shortcut this if interactions is empty?
@ -1331,13 +1383,15 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
}
}
for (typename std::set<TI>::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) {
scanner.insert2 (i.operator-> (), 0);
for (typename std::map<unsigned int, std::set<TI> >::const_iterator il = intruders.second.begin (); il != intruders.second.end (); ++il) {
for (typename std::set<TI>::const_iterator i = il->second.begin (); i != il->second.end (); ++i) {
scanner.insert2 (i.operator-> (), il->first);
}
}
if (intruder_shapes) {
for (db::Shapes::shape_iterator i = intruder_shapes->begin (shape_flags<TI> ()); !i.at_end (); ++i) {
scanner.insert2 (i->basic_ptr (typename TI::tag ()), 0);
for (std::map<unsigned int, const db::Shapes *>::const_iterator im = intruder_shapes.begin (); im != intruder_shapes.end (); ++im) {
for (db::Shapes::shape_iterator i = im->second->begin (shape_flags<TI> ()); !i.at_end (); ++i) {
scanner.insert2 (i->basic_ptr (typename TI::tag ()), im->first);
}
}
@ -1360,26 +1414,35 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
db::shape_reference_translator_with_trans<TI, db::ICplxTrans> rt (mp_subject_layout, tni);
for (typename std::unordered_set<TI>::const_iterator p = i->second.second.begin (); p != i->second.second.end (); ++p) {
if (nbox.overlaps (db::box_convert<TI> () (*p))) {
intruders_below.second.insert (rt (*p));
for (typename std::map<unsigned int, std::unordered_set<TI> >::const_iterator pl = i->second.second.begin (); pl != i->second.second.end (); ++pl) {
std::set<TI> &out = intruders_below.second [pl->first];
for (typename std::unordered_set<TI>::const_iterator p = pl->second.begin (); p != pl->second.end (); ++p) {
if (nbox.overlaps (db::box_convert<TI> () (*p))) {
out.insert (rt (*p));
}
}
}
// TODO: in some cases, it may be possible to optimize this for arrays
for (std::unordered_set<const db::CellInstArray *>::const_iterator j = i->second.first.begin (); j != i->second.first.end (); ++j) {
for (db::CellInstArray::iterator k = (*j)->begin_touching (safe_box_enlarged (nbox, -1, -1), inst_bcii); ! k.at_end (); ++k) {
db::ICplxTrans tk = (*j)->complex_trans (*k);
// NOTE: no self-interactions
if (i->first != *j || tn != tk) {
// optimize the intruder instance so it will be as low as possible
std::pair<bool, db::CellInstArray> ei = effective_instance (contexts, i->first->object ().cell_index (), (*j)->object ().cell_index (), tni * tk, dist);
if (ei.first) {
intruders_below.first.insert (ei.second);
for (std::vector<unsigned int>::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) {
db::box_convert <db::CellInst, true> inst_bcii (*mp_intruder_layout, *il);
for (std::unordered_set<const db::CellInstArray *>::const_iterator j = i->second.first.begin (); j != i->second.first.end (); ++j) {
for (db::CellInstArray::iterator k = (*j)->begin_touching (safe_box_enlarged (nbox, -1, -1), inst_bcii); ! k.at_end (); ++k) {
db::ICplxTrans tk = (*j)->complex_trans (*k);
// NOTE: no self-interactions
if (i->first != *j || tn != tk) {
// optimize the intruder instance so it will be as low as possible
std::pair<bool, db::CellInstArray> ei = effective_instance (contexts.subject_layer (), i->first->object ().cell_index (), *il, (*j)->object ().cell_index (), tni * tk, dist);
if (ei.first) {
intruders_below.first.insert (ei.second);
}
}
}
}
}
db::Cell *intruder_child_cell = (subject_cell == intruder_cell ? &subject_child_cell : 0);
@ -1406,9 +1469,9 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
*/
template <class TS, class TI, class TR>
std::pair<bool, db::CellInstArray>
local_processor<TS, TI, TR>::effective_instance (local_processor_contexts<TS, TI, TR> &contexts, db::cell_index_type subject_cell_index, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const
local_processor<TS, TI, TR>::effective_instance (unsigned int subject_layer, db::cell_index_type subject_cell_index, unsigned int intruder_layer, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const
{
db::Box bbox = safe_box_enlarged (mp_subject_layout->cell (subject_cell_index).bbox (contexts.subject_layer ()), dist - 1, dist - 1);
db::Box bbox = safe_box_enlarged (mp_subject_layout->cell (subject_cell_index).bbox (subject_layer), dist - 1, dist - 1);
if (bbox.empty ()) {
// should not happen, but skip if it does
return std::make_pair (false, db::CellInstArray ());
@ -1417,12 +1480,12 @@ local_processor<TS, TI, TR>::effective_instance (local_processor_contexts<TS, TI
db::Box ibbox = bbox.transformed (ti2s.inverted ());
const db::Cell &intruder_cell = mp_intruder_layout->cell (intruder_cell_index);
const db::Shapes &intruder_shapes = intruder_cell.shapes (contexts.intruder_layer ());
const db::Shapes &intruder_shapes = intruder_cell.shapes (intruder_layer);
if (! intruder_shapes.empty () && ! intruder_shapes.begin_touching (ibbox, db::ShapeIterator::All).at_end ()) {
return std::make_pair (true, db::CellInstArray (db::CellInst (intruder_cell_index), ti2s));
}
db::box_convert <db::CellInst, true> inst_bcii (*mp_intruder_layout, contexts.intruder_layer ());
db::box_convert <db::CellInst, true> inst_bcii (*mp_intruder_layout, intruder_layer);
size_t ni = 0;
db::cell_index_type eff_cell_index = 0;
@ -1430,7 +1493,7 @@ local_processor<TS, TI, TR>::effective_instance (local_processor_contexts<TS, TI
for (db::Cell::touching_iterator i = intruder_cell.begin_touching (ibbox); ! i.at_end() && ni < 2; ++i) {
const db::CellInstArray &ci = i->cell_inst ();
db::Box cbox = mp_intruder_layout->cell (ci.object ().cell_index ()).bbox (contexts.intruder_layer ());
db::Box cbox = mp_intruder_layout->cell (ci.object ().cell_index ()).bbox (intruder_layer);
for (db::CellInstArray::iterator k = ci.begin_touching (ibbox, inst_bcii); ! k.at_end () && ni < 2; ++k) {
db::ICplxTrans tk = ci.complex_trans (*k);
if (ibbox.overlaps (cbox.transformed (tk))) {
@ -1446,7 +1509,7 @@ local_processor<TS, TI, TR>::effective_instance (local_processor_contexts<TS, TI
return std::make_pair (false, db::CellInstArray ());
} else if (ni == 1) {
// one instance - dive down
return effective_instance (contexts, subject_cell_index, eff_cell_index, ti2s * eff_trans, dist);
return effective_instance (subject_layer, subject_cell_index, intruder_layer, eff_cell_index, ti2s * eff_trans, dist);
} else {
return std::make_pair (true, db::CellInstArray (db::CellInst (intruder_cell_index), ti2s));
}
@ -1454,7 +1517,7 @@ local_processor<TS, TI, TR>::effective_instance (local_processor_contexts<TS, TI
template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int output_layer) const
local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers) const
{
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::to_string (tr ("Computing results for ")) + description (op));
@ -1505,7 +1568,7 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
if (later.find (*bu) == later.end ()) {
rc_job->schedule (new local_processor_result_computation_task<TS, TI, TR> (this, contexts, cpc->first, &cpc->second, op, output_layer));
rc_job->schedule (new local_processor_result_computation_task<TS, TI, TR> (this, contexts, cpc->first, &cpc->second, op, output_layers));
any = true;
} else {
@ -1554,7 +1617,7 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
typename local_processor_contexts<TS, TI, TR>::iterator cpc = contexts.context_map ().find (&mp_subject_layout->cell (*bu));
if (cpc != contexts.context_map ().end ()) {
cpc->second.compute_results (contexts, cpc->first, op, output_layer, this);
cpc->second.compute_results (contexts, cpc->first, op, output_layers, this);
contexts.context_map ().erase (cpc);
}
@ -1574,10 +1637,10 @@ template <class TS, class TI>
struct scan_shape2shape_same_layer
{
void
operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set<TI> &intruders, shape_interactions<TS, TI> &interactions, db::Coord dist) const
operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set<TI> &intruders, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
{
db::box_scanner2<TS, int, TI, int> scanner;
interaction_registration_shape1<TS, TI> rec (&interactions);
interaction_registration_shape1<TS, TI> rec (&interactions, intruder_layer);
unsigned int id = subject_id0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
@ -1598,10 +1661,10 @@ template <class T>
struct scan_shape2shape_same_layer<T, T>
{
void
operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set<T> &intruders, shape_interactions<T, T> &interactions, db::Coord dist) const
operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set<T> &intruders, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
{
db::box_scanner<T, int> scanner;
interaction_registration_shape1<T, T> rec (&interactions);
interaction_registration_shape1<T, T> rec (&interactions, intruder_layer);
unsigned int id = subject_id0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<T> ()); !i.at_end (); ++i) {
@ -1622,10 +1685,10 @@ template <class TS, class TI>
struct scan_shape2shape_different_layers
{
void
operator () (db::Layout *layout, const db::Shapes *subject_shapes, const db::Shapes *intruder_shapes, unsigned int subject_id0, const std::set<TI> &intruders, shape_interactions<TS, TI> &interactions, db::Coord dist)
operator () (db::Layout *layout, const db::Shapes *subject_shapes, const db::Shapes *intruder_shapes, unsigned int subject_id0, const std::set<TI> &intruders, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist)
{
db::box_scanner2<TS, int, TI, int> scanner;
interaction_registration_shape2shape<TS, TI> rec (layout, &interactions);
interaction_registration_shape2shape<TS, TI> rec (layout, &interactions, intruder_layer);
unsigned int id = subject_id0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
@ -1651,90 +1714,98 @@ struct scan_shape2shape_different_layers
template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_contexts<TS, TI, TR> &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation<TS, TI, TR> *op, const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, std::unordered_set<TR> &result) const
local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_contexts<TS, TI, TR> &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation<TS, TI, TR> *op, const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, std::vector<std::unordered_set<TR> > &result) const
{
const db::Shapes *subject_shapes = &subject_cell->shapes (contexts.subject_layer ());
const db::Shapes *intruder_shapes = 0;
if (intruder_cell) {
intruder_shapes = &intruder_cell->shapes (contexts.intruder_layer ());
if (intruder_shapes->empty ()) {
intruder_shapes = 0;
}
}
// local shapes vs. child cell
shape_interactions<TS, TI> interactions;
db::box_convert<db::CellInstArray, true> inst_bci (*mp_intruder_layout, contexts.intruder_layer ());
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
// range for the subject shapes.
unsigned int subject_id0 = 0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
for (std::vector<unsigned int>::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) {
unsigned int id = interactions.next_id ();
if (subject_id0 == 0) {
subject_id0 = id;
const db::Shapes *intruder_shapes = 0;
if (intruder_cell) {
intruder_shapes = &intruder_cell->shapes (*il);
if (intruder_shapes->empty ()) {
intruder_shapes = 0;
}
}
if (op->on_empty_intruder_hint () != local_operation<TS, TI, TR>::Drop) {
const TS *ref = i->basic_ptr (typename TS::tag ());
interactions.add_subject (id, *ref);
}
// local shapes vs. child cell
}
db::box_convert<db::CellInstArray, true> inst_bci (*mp_intruder_layout, *il);
if (! subject_shapes->empty () && (intruder_shapes || ! intruders.second.empty ())) {
if (subject_cell == intruder_cell && contexts.subject_layer () == contexts.intruder_layer ()) {
scan_shape2shape_same_layer<TS, TI> () (subject_shapes, subject_id0, intruders.second, interactions, op->dist ());
} else {
db::Layout *target_layout = (mp_subject_layout == mp_intruder_layout ? 0 : mp_subject_layout);
scan_shape2shape_different_layers<TS, TI> () (target_layout, subject_shapes, intruder_shapes, subject_id0, intruders.second, interactions, op->dist ());
}
}
if (! subject_shapes->empty () && ! ((! intruder_cell || intruder_cell->begin ().at_end ()) && intruders.first.empty ())) {
db::box_scanner2<TS, int, db::CellInstArray, int> scanner;
interaction_registration_shape2inst<TS, TI> rec (mp_subject_layout, mp_intruder_layout, contexts.intruder_layer (), op->dist (), &interactions);
unsigned int id = subject_id0;
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
// range for the subject shapes.
unsigned int subject_id0 = 0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
scanner.insert1 (i->basic_ptr (typename TS::tag ()), id++);
unsigned int id = interactions.next_id ();
if (subject_id0 == 0) {
subject_id0 = id;
}
if (op->on_empty_intruder_hint () != local_operation<TS, TI, TR>::Drop) {
const TS *ref = i->basic_ptr (typename TS::tag ());
interactions.add_subject (id, *ref);
}
}
unsigned int inst_id = 0;
typename std::map<unsigned int, std::set<TI> >::const_iterator ipl = intruders.second.find (*il);
static std::set<TI> empty_intruders;
if (subject_cell == intruder_cell && contexts.subject_layer () == contexts.intruder_layer ()) {
if (! subject_shapes->empty () && (intruder_shapes || ipl != intruders.second.end ())) {
// Same cell, same layer -> no shape to child instance interactions because this will be taken care of
// by the instances themselves (and their intruders). This also means, we prefer to deal with
// interactions low in the hierarchy.
if (subject_cell == intruder_cell && contexts.subject_layer () == *il) {
} else if (intruder_cell) {
// TODO: can we confine this search to the subject's (sized) bounding box?
for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) {
if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) {
scanner.insert2 (&i->cell_inst (), ++inst_id);
scan_shape2shape_same_layer<TS, TI> () (subject_shapes, subject_id0, ipl == intruders.second.end () ? empty_intruders : ipl->second, *il, interactions, op->dist ());
} else {
db::Layout *target_layout = (mp_subject_layout == mp_intruder_layout ? 0 : mp_subject_layout);
scan_shape2shape_different_layers<TS, TI> () (target_layout, subject_shapes, intruder_shapes, subject_id0, ipl == intruders.second.end () ? empty_intruders : ipl->second, *il, interactions, op->dist ());
}
}
if (! subject_shapes->empty () && ! ((! intruder_cell || intruder_cell->begin ().at_end ()) && intruders.first.empty ())) {
db::box_scanner2<TS, int, db::CellInstArray, int> scanner;
interaction_registration_shape2inst<TS, TI> rec (mp_subject_layout, mp_intruder_layout, *il, op->dist (), &interactions);
unsigned int id = subject_id0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
scanner.insert1 (i->basic_ptr (typename TS::tag ()), id++);
}
unsigned int inst_id = 0;
if (subject_cell == intruder_cell && contexts.subject_layer () == *il) {
// Same cell, same layer -> no shape to child instance interactions because this will be taken care of
// by the instances themselves (and their intruders). This also means, we prefer to deal with
// interactions low in the hierarchy.
} else if (intruder_cell) {
// TODO: can we confine this search to the subject's (sized) bounding box?
for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) {
if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) {
scanner.insert2 (&i->cell_inst (), ++inst_id);
}
}
}
}
// TODO: can we confine this search to the subject's (sized) bounding box?
for (std::set<db::CellInstArray>::const_iterator i = intruders.first.begin (); i != intruders.first.end (); ++i) {
if (! inst_bci (*i).empty ()) {
scanner.insert2 (i.operator-> (), ++inst_id);
// TODO: can we confine this search to the subject's (sized) bounding box?
for (std::set<db::CellInstArray>::const_iterator i = intruders.first.begin (); i != intruders.first.end (); ++i) {
if (! inst_bci (*i).empty ()) {
scanner.insert2 (i.operator-> (), ++inst_id);
}
}
}
scanner.process (rec, op->dist (), db::box_convert<TS> (), inst_bci);
scanner.process (rec, op->dist (), db::box_convert<TS> (), inst_bci);
}
}

View File

@ -56,7 +56,7 @@ public:
typedef container::const_iterator iterator;
typedef container::value_type::second_type::const_iterator iterator2;
typedef typename std::unordered_map<unsigned int, TS>::const_iterator subject_iterator;
typedef typename std::unordered_map<unsigned int, TI>::const_iterator intruder_iterator;
typedef typename std::unordered_map<unsigned int, std::pair<unsigned int, TI> >::const_iterator intruder_iterator;
shape_interactions ();
@ -92,13 +92,13 @@ public:
bool has_intruder_shape_id (unsigned int id) const;
bool has_subject_shape_id (unsigned int id) const;
void add_intruder_shape (unsigned int id, const TI &shape);
void add_intruder_shape (unsigned int id, unsigned int layer, const TI &shape);
void add_subject_shape (unsigned int id, const TS &shape);
void add_subject (unsigned int id, const TS &shape);
void add_interaction (unsigned int subject_id, unsigned int intruder_id);
const std::vector<unsigned int> &intruders_for (unsigned int subject_id) const;
const TS &subject_shape (unsigned int id) const;
const TI &intruder_shape (unsigned int id) const;
const std::pair<unsigned int, TI> &intruder_shape (unsigned int id) const;
unsigned int next_id ()
{
@ -108,7 +108,7 @@ public:
private:
std::unordered_map<unsigned int, std::vector<unsigned int> > m_interactions;
std::unordered_map<unsigned int, TS> m_subject_shapes;
std::unordered_map<unsigned int, TI> m_intruder_shapes;
std::unordered_map<unsigned int, std::pair<unsigned int, TI> > m_intruder_shapes;
unsigned int m_id;
};
@ -139,16 +139,22 @@ public:
local_processor_cell_context (const local_processor_cell_context &other);
void add (db::local_processor_cell_context<TS, TI, TR> *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst);
void propagate (const std::unordered_set<TR> &res);
void propagate (unsigned int layer, const std::unordered_set<TR> &res);
std::unordered_set<TR> &propagated ()
std::unordered_set<TR> &propagated (unsigned int l)
{
return m_propagated;
return m_propagated [l];
}
const std::unordered_set<TR> &propagated () const
const std::unordered_set<TR> &propagated (unsigned int l) const
{
return m_propagated;
typename std::map<unsigned int, std::unordered_set<TR> >::const_iterator i = m_propagated.find (l);
if (i != m_propagated.end ()) {
return i->second;
} else {
static std::unordered_set<TR> s_empty;
return s_empty;
}
}
size_t size () const
@ -174,7 +180,7 @@ public:
}
private:
std::unordered_set<TR> m_propagated;
std::map<unsigned int, std::unordered_set<TR> > m_propagated;
std::vector<local_processor_cell_drop<TS, TI, TR> > m_drops;
tl::Mutex m_lock;
};
@ -183,7 +189,7 @@ template <class TS, class TI, class TR>
class DB_PUBLIC local_processor_cell_contexts
{
public:
typedef std::pair<std::set<CellInstArray>, std::set<TI> > context_key_type;
typedef std::pair<std::set<CellInstArray>, std::map<unsigned int, std::set<TI> > > context_key_type;
typedef std::unordered_map<context_key_type, db::local_processor_cell_context<TS, TI, TR> > context_map_type;
typedef typename context_map_type::const_iterator iterator;
@ -192,7 +198,7 @@ public:
db::local_processor_cell_context<TS, TI, TR> *find_context (const context_key_type &intruders);
db::local_processor_cell_context<TS, TI, TR> *create (const context_key_type &intruders);
void compute_results (const local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, const local_operation<TS, TI, TR> *op, unsigned int output_layer, const local_processor<TS, TI, TR> *proc);
void compute_results (const local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layer, const local_processor<TS, TI, TR> *proc);
size_t size () const
{
@ -222,13 +228,13 @@ public:
typedef typename contexts_per_cell_type::iterator iterator;
local_processor_contexts ()
: m_subject_layer (0), m_intruder_layer (0)
: m_subject_layer (0), m_intruder_layers ()
{
// .. nothing yet ..
}
local_processor_contexts (const local_processor_contexts &other)
: m_contexts_per_cell (other.m_contexts_per_cell), m_subject_layer (other.m_subject_layer), m_intruder_layer (other.m_intruder_layer)
: m_contexts_per_cell (other.m_contexts_per_cell), m_subject_layer (other.m_subject_layer), m_intruder_layers (other.m_intruder_layers)
{
// .. nothing yet ..
}
@ -272,14 +278,14 @@ public:
return m_subject_layer;
}
void set_intruder_layer (unsigned int l)
void set_intruder_layers (const std::vector<unsigned int> &l)
{
m_intruder_layer = l;
m_intruder_layers = l;
}
unsigned int intruder_layer () const
const std::vector<unsigned int> &intruder_layers () const
{
return m_intruder_layer;
return m_intruder_layers;
}
tl::Mutex &lock () const
@ -289,7 +295,8 @@ public:
private:
contexts_per_cell_type m_contexts_per_cell;
unsigned int m_subject_layer, m_intruder_layer;
unsigned int m_subject_layer;
std::vector<unsigned int> m_intruder_layers;
mutable tl::Mutex m_lock;
};
@ -335,7 +342,7 @@ class DB_PUBLIC local_processor_result_computation_task
: public tl::Task
{
public:
local_processor_result_computation_task (const local_processor<TS, TI, TR> *proc, local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, local_processor_cell_contexts<TS, TI, TR> *cell_contexts, const local_operation<TS, TI, TR> *op, unsigned int output_layer);
local_processor_result_computation_task (const local_processor<TS, TI, TR> *proc, local_processor_contexts<TS, TI, TR> &contexts, db::Cell *cell, local_processor_cell_contexts<TS, TI, TR> *cell_contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers);
void perform ();
private:
@ -344,7 +351,7 @@ private:
db::Cell *mp_cell;
local_processor_cell_contexts<TS, TI, TR> *mp_cell_contexts;
const local_operation<TS, TI, TR> *mp_op;
unsigned int m_output_layer;
std::vector<unsigned int> m_output_layers;
};
template <class TS, class TI, class TR>
@ -370,9 +377,11 @@ class DB_PUBLIC local_processor
public:
local_processor (db::Layout *layout, db::Cell *top, const std::set<db::cell_index_type> *breakout_cells = 0);
local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set<db::cell_index_type> *subject_breakout_cells = 0, const std::set<db::cell_index_type> *intruder_breakout_cells = 0);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer);
void compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer) const;
void compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int output_layer) const;
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layers);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, unsigned int output_layer);
void compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers) const;
void compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers) const;
void set_description (const std::string &d)
{
@ -445,8 +454,8 @@ private:
void do_compute_contexts (db::local_processor_cell_context<TS, TI, TR> *cell_context, const db::local_processor_contexts<TS, TI, TR> &contexts, db::local_processor_cell_context<TS, TI, TR> *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, db::Coord dist) const;
void issue_compute_contexts (db::local_processor_contexts<TS, TI, TR> &contexts, db::local_processor_cell_context<TS, TI, TR> *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, db::Coord dist) const;
void push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set<TR> &result) const;
void compute_local_cell (const db::local_processor_contexts<TS, TI, TR> &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation<TS, TI, TR> *op, const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, std::unordered_set<TR> &result) const;
std::pair<bool, db::CellInstArray> effective_instance (local_processor_contexts<TS, TI, TR> &contexts, db::cell_index_type subject_cell_index, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const;
void compute_local_cell (const db::local_processor_contexts<TS, TI, TR> &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation<TS, TI, TR> *op, const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, std::vector<std::unordered_set<TR> > &result) const;
std::pair<bool, db::CellInstArray> effective_instance (unsigned int subject_layer, db::cell_index_type subject_cell_index, unsigned int intruder_layer, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const;
bool subject_cell_is_breakout (db::cell_index_type ci) const
{

View File

@ -59,8 +59,11 @@ BoolAndOrNotLocalOperation::description () const
}
void
BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t max_vertex_count, double area_ratio) const
BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
db::EdgeProcessor ep;
size_t p1 = 0, p2 = 1;
@ -68,7 +71,7 @@ BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_inter
std::set<db::PolygonRef> others;
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -120,8 +123,12 @@ SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wra
// .. nothing yet ..
}
void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void
SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
if (m_wrap_count == 0) {
return;
}
@ -147,7 +154,7 @@ void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const sh
// set does not take care to list just one copy of the same item on the intruder side.
if (seen.find (*o) == seen.end ()) {
seen.insert (*o);
const db::PolygonRef &intruder = interactions.intruder_shape (*o);
const db::PolygonRef &intruder = interactions.intruder_shape (*o).second;
for (db::PolygonRef::polygon_edge_iterator e = intruder.begin_edge (); ! e.at_end(); ++e) {
ep.insert (*e, p2);
}
@ -204,8 +211,11 @@ EdgeBoolAndOrNotLocalOperation::description () const
}
void
EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front ();
EdgeBooleanClusterCollector<std::unordered_set<db::Edge> > cluster_collector (&result, m_op);
db::box_scanner<db::Edge, size_t> scanner;
@ -213,7 +223,7 @@ EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const sh
std::set<db::Edge> others;
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}
@ -272,14 +282,17 @@ EdgeToPolygonLocalOperation::description () const
}
void
EdgeToPolygonLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
EdgeToPolygonLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front ();
db::EdgeProcessor ep;
std::set<db::PolygonRef> others;
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
for (shape_interactions<db::Edge, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
others.insert (interactions.intruder_shape (*j));
others.insert (interactions.intruder_shape (*j).second);
}
}

View File

@ -90,7 +90,7 @@ public:
* @param interactions The interaction set
* @param result The container to which the results are written
*/
virtual void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::unordered_set<TR> &result, size_t max_vertex_count, double area_ratio) const = 0;
virtual void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, size_t max_vertex_count, double area_ratio) const = 0;
/**
* @brief Indicates the desired behaviour when a shape does not have an intruder
@ -118,7 +118,7 @@ class DB_PUBLIC BoolAndOrNotLocalOperation
public:
BoolAndOrNotLocalOperation (bool is_and);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t max_vertex_count, double area_ratio) const;
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const;
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
virtual std::string description () const;
@ -137,7 +137,7 @@ class DB_PUBLIC SelfOverlapMergeLocalOperation
public:
SelfOverlapMergeLocalOperation (unsigned int wrap_count);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t max_vertex_count, double area_ratio) const;
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const;
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
virtual std::string description () const;
@ -154,7 +154,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation
public:
EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t max_vertex_count, double area_ratio) const;
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
virtual std::string description () const;
@ -177,7 +177,7 @@ class DB_PUBLIC EdgeToPolygonLocalOperation
public:
EdgeToPolygonLocalOperation (bool outside, bool include_borders);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::unordered_set<db::Edge> &result, size_t max_vertex_count, double area_ratio) const;
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
virtual std::string description () const;

View File

@ -55,18 +55,19 @@ public:
// .. nothing yet ..
}
virtual void compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t max_vertex_count, double area_ratio) const
virtual void compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
{
db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions;
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
const db::PolygonRef &ref = interactions.intruder_shape (*j);
db::Polygon poly = ref.obj ().transformed (ref.trans ());
const std::pair<unsigned int, db::PolygonRef> &intruder = interactions.intruder_shape (*j);
db::Polygon poly = intruder.second.obj ().transformed (intruder.second.trans ());
poly.size (m_dist, m_dist);
sized_interactions.add_intruder_shape (*j, db::PolygonRef (poly, layout->shape_repository ()));
sized_interactions.add_intruder_shape (*j, intruder.first, db::PolygonRef (poly, layout->shape_repository ()));
}
}
BoolAndOrNotLocalOperation::compute_local (layout, sized_interactions, result, max_vertex_count, area_ratio);
BoolAndOrNotLocalOperation::compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio);
}
db::Coord dist () const
@ -91,26 +92,28 @@ public:
// .. nothing yet ..
}
virtual void compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t max_vertex_count, double area_ratio) const
virtual void compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
{
db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions;
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
const db::PolygonRef &ref = interactions.subject_shape (i->first);
db::Polygon poly = ref.obj ().transformed (ref.trans ());
poly.size (m_dist / 2, m_dist / 2);
sized_interactions.add_subject_shape (i->first, db::PolygonRef (poly, layout->shape_repository ()));
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
const db::PolygonRef &ref = interactions.intruder_shape (*j);
unsigned int il = interactions.intruder_shape (*j).first;
const db::PolygonRef &ref = interactions.intruder_shape (*j).second;
db::Polygon poly = ref.obj ().transformed (ref.trans ());
poly.size (m_dist / 2, m_dist / 2);
sized_interactions.add_intruder_shape (*j, db::PolygonRef (poly, layout->shape_repository ()));
sized_interactions.add_intruder_shape (*j, il, db::PolygonRef (poly, layout->shape_repository ()));
}
}
SelfOverlapMergeLocalOperation::compute_local (layout, sized_interactions, result, max_vertex_count, area_ratio);
SelfOverlapMergeLocalOperation::compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio);
}
db::Coord dist () const
@ -149,7 +152,15 @@ static std::string contexts_to_s (db::Layout *layout, db::local_processor_contex
if (cc != contexts.context_map ().end ()) {
int index = 1;
for (db::local_processor_cell_contexts<db::PolygonRef, db::PolygonRef, db::PolygonRef>::iterator j = cc->second.begin (); j != cc->second.end (); ++j) {
res += tl::sprintf ("%s[%d] %d insts, %d shapes (%d times)\n", layout->cell_name (*i), index, int (j->first.first.size ()), int (j->first.second.size ()), int (j->second.size ()));
size_t nshapes = 0;
for (std::map<unsigned int, std::set<db::PolygonRef> >::const_iterator i = j->first.second.begin (); i != j->first.second.end (); ++i) {
nshapes += i->second.size ();
}
if (j->first.first.size () > 1) {
res += tl::sprintf ("%s[%d] %d insts, %d shapes/%d layers (%d times)\n", layout->cell_name (*i), index, int (j->first.first.size ()), int (nshapes), int (j->first.second.size ()), int (j->second.size ()));
} else {
res += tl::sprintf ("%s[%d] %d insts, %d shapes (%d times)\n", layout->cell_name (*i), index, int (j->first.first.size ()), int (nshapes), int (j->second.size ()));
}
index += 1;
}
}
@ -233,9 +244,12 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m
proc.run (lop, l1, l2, lout);
} else {
db::local_processor_contexts<db::PolygonRef, db::PolygonRef, db::PolygonRef> contexts;
proc.compute_contexts (contexts, lop, l1, l2);
std::vector<unsigned int> ilv, olv;
ilv.push_back (l2);
olv.push_back (lout);
proc.compute_contexts (contexts, lop, l1, ilv);
*context_doc = contexts_to_s (&layout_org, contexts);
proc.compute_results (contexts, lop, lout);
proc.compute_results (contexts, lop, olv);
}
} else {
@ -251,9 +265,12 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m
proc.run (lop, l1, l2, lout);
} else {
db::local_processor_contexts<db::PolygonRef, db::PolygonRef, db::PolygonRef> contexts;
proc.compute_contexts (contexts, lop, l1, l2);
std::vector<unsigned int> ilv, olv;
ilv.push_back (l2);
olv.push_back (lout);
proc.compute_contexts (contexts, lop, l1, ilv);
*context_doc = contexts_to_s (&layout_org, contexts);
proc.compute_results (contexts, lop, lout);
proc.compute_results (contexts, lop, olv);
}
}