From 96caa646f5f986656106cbc9af8591def96f95a5 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 7 Jun 2020 18:04:30 +0200 Subject: [PATCH] WIP: preparations for multi-input/multi-output local processor. --- src/db/db/dbDeepEdges.cc | 37 +- src/db/db/dbDeepRegion.cc | 51 ++- src/db/db/dbDeepTexts.cc | 14 +- src/db/db/dbHash.h | 17 + src/db/db/dbHierProcessor.cc | 391 +++++++++++++--------- src/db/db/dbHierProcessor.h | 61 ++-- src/db/db/dbLocalOperation.cc | 29 +- src/db/db/dbLocalOperation.h | 10 +- src/db/unit_tests/dbHierProcessorTests.cc | 45 ++- 9 files changed, 412 insertions(+), 243 deletions(-) diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 5f0961b00..981f65381 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -1041,14 +1041,17 @@ public: return 1; } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner scanner; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner scanner; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + edge2edge_check_for_edges > edge_check (m_check, result, m_has_other); db::box_scanner scanner; @@ -1438,7 +1453,7 @@ public: for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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::iterator i = interactions.begin (); i != interactions.end (); ++i) { others.insert (interactions.subject_shape (i->first)); for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { - others.insert (interactions.intruder_shape (*j)); + others.insert (interactions.intruder_shape (*j).second); } } diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 9b027f19f..f5eba16fa 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1267,8 +1267,11 @@ public: // .. nothing yet .. } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + edge2edge_check > edge_check (m_check, result, m_different_polygons, m_has_other, true /*shielded*/); poly2poly_check > poly_check (edge_check); @@ -1280,7 +1283,7 @@ public: std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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::iterator i = interactions.begin (); i != interactions.end (); ++i) { polygons.insert (interactions.subject_shape (i->first)); for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::EdgeProcessor ep; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::EdgeProcessor ep; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; ResultInserter inserter (layout, result); @@ -1650,7 +1662,7 @@ public: for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout *, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; EdgeResultInserter inserter (result); @@ -1715,7 +1730,7 @@ public: for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout *, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; TextResultInserter inserter (result); @@ -1786,7 +1804,7 @@ public: for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; ResultInserter inserter (layout, result); @@ -1839,7 +1860,7 @@ public: for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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); } } diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index 264a36485..9516fc94e 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -428,14 +428,17 @@ public: return 1; } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::box_scanner2 scanner; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { - others.insert (interactions.intruder_shape (*j)); + others.insert (interactions.intruder_shape (*j).second); } } diff --git a/src/db/db/dbHash.h b/src/db/db/dbHash.h index 91c950468..7fd15f07c 100644 --- a/src/db/db/dbHash.h +++ b/src/db/db/dbHash.h @@ -420,6 +420,23 @@ namespace std return hf; } }; + + /** + * @brief Generic hash for an ordered map + */ + template + struct hash > + { + size_t operator() (const std::map &o) const + { + size_t hf = 0; + for (typename std::map::const_iterator i = o.begin (); i != o.end (); ++i) { + hf = hfunc (hf, std::hash () (i->first)); + hf = hfunc (hf, std::hash () (i->second)); + } + return hf; + } + }; } #endif diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 674f81430..ea5ddabd0 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -286,7 +286,7 @@ local_processor_cell_context::add (db::local_processor_cell_context< template void -local_processor_cell_context::propagate (const std::unordered_set &res) +local_processor_cell_context::propagate (unsigned int output_layer, const std::unordered_set &res) { if (res.empty ()) { return; @@ -307,7 +307,7 @@ local_processor_cell_context::propagate (const std::unordered_setparent_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 void -local_processor_cell_contexts::compute_results (const local_processor_contexts &contexts, db::Cell *cell, const local_operation *op, unsigned int output_layer, const local_processor *proc) +local_processor_cell_contexts::compute_results (const local_processor_contexts &contexts, db::Cell *cell, const local_operation *op, const std::vector &output_layers, const local_processor *proc) { CRONOLOGY_COMPUTE_BRACKET(event_compute_results) bool first = true; - std::unordered_set common; + std::vector > common; + common.resize (output_layers.size ()); int index = 0; int total = int (m_contexts.size ()); @@ -452,7 +453,9 @@ local_processor_cell_contexts::compute_results (const local_processo { tl::MutexLocker locker (&c->second->lock ()); - common = c->second->propagated (); + for (std::vector::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::compute_results (const local_processo } else { - std::unordered_set res; + std::vector > res; + res.resize (output_layers.size ()); + { tl::MutexLocker locker (&c->second->lock ()); - res = c->second->propagated (); + for (std::vector::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::compute_results (const local_processo if (common.empty ()) { CRONOLOGY_COMPUTE_BRACKET(event_propagate) - c->second->propagate (res); + for (std::vector::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::compute_results (const local_processo CRONOLOGY_COMPUTE_BRACKET(event_propagate) - std::unordered_set lost; - for (typename std::unordered_set::const_iterator i = common.begin (); i != common.end (); ++i) { - if (res.find (*i) == res.end ()) { - lost.insert (*i); - } - } + for (std::vector::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 lost; - if (! lost.empty ()) { - subtract (common, lost, cell->layout (), proc); - for (typename std::vector *> >::const_iterator cc = sorted_contexts.begin (); cc != c; ++cc) { - cc->second->propagate (lost); + for (typename std::unordered_set::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 *> >::const_iterator cc = sorted_contexts.begin (); cc != c; ++cc) { + cc->second->propagate (*o, lost); + } + } - std::unordered_set gained; - for (typename std::unordered_set::const_iterator i = res.begin (); i != res.end (); ++i) { - if (common.find (*i) == common.end ()) { - gained.insert (*i); } + } - if (! gained.empty ()) { + for (std::vector::const_iterator o = output_layers.begin (); o != output_layers.end (); ++o) { - subtract (gained, common, cell->layout (), proc); + std::unordered_set gained; + + size_t oi = o - output_layers.begin (); + for (typename std::unordered_set::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::compute_results (const local_processo } - proc->push_results (cell, output_layer, common); + for (std::vector::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; @@ -565,9 +590,9 @@ shape_interactions::has_subject_shape_id (unsigned int id) const template void -shape_interactions::add_intruder_shape (unsigned int id, const TI &shape) +shape_interactions::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 @@ -619,12 +644,12 @@ shape_interactions::subject_shape (unsigned int id) const } template -const TI & +const std::pair & shape_interactions::intruder_shape (unsigned int id) const { - typename std::unordered_map::const_iterator i = m_intruder_shapes.find (id); + typename std::unordered_map >::const_iterator i = m_intruder_shapes.find (id); if (i == m_intruder_shapes.end ()) { - static TI s; + static std::pair s; return s; } else { return i->second; @@ -670,8 +695,8 @@ struct interaction_registration_shape2shape : db::box_scanner_receiver2 { public: - interaction_registration_shape2shape (db::Layout *layout, shape_interactions *result) - : mp_result (result), mp_layout (layout) + interaction_registration_shape2shape (db::Layout *layout, shape_interactions *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 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 *mp_result; db::Layout *mp_layout; + unsigned int m_intruder_layer; }; template @@ -704,8 +730,8 @@ struct interaction_registration_shape1 : db::box_scanner_receiver2 { public: - interaction_registration_shape1 (shape_interactions *result) - : mp_result (result) + interaction_registration_shape1 (shape_interactions *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 *mp_result; + unsigned int m_intruder_layer; }; template @@ -726,8 +753,8 @@ struct interaction_registration_shape1 : db::box_scanner_receiver { public: - interaction_registration_shape1 (shape_interactions *result) - : mp_result (result) + interaction_registration_shape1 (shape_interactions *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 *mp_result; + unsigned int m_intruder_layer; }; template @@ -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 { public: - typedef std::pair, std::unordered_set > interaction_value_type; + typedef std::pair, std::map > > 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 *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, std::unordered_set > > *mp_result; + std::unordered_map, std::map > > > *mp_result; std::unordered_set > m_interactions; }; @@ -959,16 +987,16 @@ struct interaction_registration_inst2shape : db::box_scanner_receiver2 { public: - interaction_registration_inst2shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::unordered_map, std::unordered_set > > *result) + interaction_registration_inst2shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::unordered_map, std::map > > > *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, std::unordered_set > > *mp_result; + std::unordered_map, std::map > > > *mp_result; }; } @@ -1013,8 +1041,8 @@ template class DB_PUBLIC local_processor_context_computation_task -local_processor_result_computation_task::local_processor_result_computation_task (const local_processor *proc, local_processor_contexts &contexts, db::Cell *cell, local_processor_cell_contexts *cell_contexts, const local_operation *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::local_processor_result_computation_task (const local_processor *proc, local_processor_contexts &contexts, db::Cell *cell, local_processor_cell_contexts *cell_contexts, const local_operation *op, const std::vector &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 void local_processor_result_computation_task::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::get_progress () const template void local_processor::run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer) +{ + std::vector ol, il; + ol.push_back (output_layer); + il.push_back (intruder_layer); + run (op, subject_layer, il, ol); +} + +template +void local_processor::run (local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers, unsigned int output_layer) +{ + std::vector ol; + ol.push_back (output_layer); + run (op, subject_layer, intruder_layers, ol); +} + +template +void local_processor::run (local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers, const std::vector &output_layers) { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Executing ")) + description (op)); local_processor_contexts 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 @@ -1134,7 +1179,7 @@ void local_processor::push_results (db::Cell *cell, unsigned int out } template -void local_processor::compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, unsigned int intruder_layer) const +void local_processor::compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers) const { try { @@ -1147,7 +1192,7 @@ void local_processor::compute_contexts (local_processor_contexts::context_key_type intruders; @@ -1244,21 +1289,24 @@ void local_processor::compute_contexts (local_processor_contexts intruder_shapes; if (intruder_cell) { - intruder_shapes = &intruder_cell->shapes (contexts.intruder_layer ()); + for (std::vector::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 inst_bcs (*mp_subject_layout, contexts.subject_layer ()); - db::box_convert inst_bci (*mp_intruder_layout, contexts.intruder_layer ()); - db::box_convert 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 > interaction_value_type; + typedef std::pair, std::map > > interaction_value_type; std::unordered_map interactions; @@ -1272,9 +1320,12 @@ void local_processor::compute_contexts (local_processor_contexts::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) { + + db::box_convert inst_bci (*mp_intruder_layout, *il); + db::box_scanner2 scanner; - interaction_registration_inst2inst rec (mp_subject_layout, contexts.subject_layer (), mp_intruder_layout, contexts.intruder_layer (), dist, &interactions); + interaction_registration_inst2inst rec (mp_subject_layout, contexts.subject_layer (), mp_intruder_layout, *il, dist, &interactions); unsigned int id = 0; @@ -1318,6 +1369,7 @@ void local_processor::compute_contexts (local_processor_contexts::compute_contexts (local_processor_contexts::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) { - scanner.insert2 (i.operator-> (), 0); + for (typename std::map >::const_iterator il = intruders.second.begin (); il != intruders.second.end (); ++il) { + for (typename std::set::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 ()); !i.at_end (); ++i) { - scanner.insert2 (i->basic_ptr (typename TI::tag ()), 0); + for (std::map::const_iterator im = intruder_shapes.begin (); im != intruder_shapes.end (); ++im) { + for (db::Shapes::shape_iterator i = im->second->begin (shape_flags ()); !i.at_end (); ++i) { + scanner.insert2 (i->basic_ptr (typename TI::tag ()), im->first); } } @@ -1360,26 +1414,35 @@ void local_processor::compute_contexts (local_processor_contexts rt (mp_subject_layout, tni); - for (typename std::unordered_set::const_iterator p = i->second.second.begin (); p != i->second.second.end (); ++p) { - if (nbox.overlaps (db::box_convert () (*p))) { - intruders_below.second.insert (rt (*p)); + for (typename std::map >::const_iterator pl = i->second.second.begin (); pl != i->second.second.end (); ++pl) { + std::set &out = intruders_below.second [pl->first]; + for (typename std::unordered_set::const_iterator p = pl->second.begin (); p != pl->second.end (); ++p) { + if (nbox.overlaps (db::box_convert () (*p))) { + out.insert (rt (*p)); + } } } // TODO: in some cases, it may be possible to optimize this for arrays - for (std::unordered_set::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 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::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) { + + db::box_convert inst_bcii (*mp_intruder_layout, *il); + + for (std::unordered_set::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 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::compute_contexts (local_processor_contexts std::pair -local_processor::effective_instance (local_processor_contexts &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::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::effective_instance (local_processor_contextscell (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 inst_bcii (*mp_intruder_layout, contexts.intruder_layer ()); + db::box_convert 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::effective_instance (local_processor_contextscell_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::effective_instance (local_processor_contexts::effective_instance (local_processor_contexts void -local_processor::compute_results (local_processor_contexts &contexts, const local_operation *op, unsigned int output_layer) const +local_processor::compute_results (local_processor_contexts &contexts, const local_operation *op, const std::vector &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::compute_results (local_processor_contextsschedule (new local_processor_result_computation_task (this, contexts, cpc->first, &cpc->second, op, output_layer)); + rc_job->schedule (new local_processor_result_computation_task (this, contexts, cpc->first, &cpc->second, op, output_layers)); any = true; } else { @@ -1554,7 +1617,7 @@ local_processor::compute_results (local_processor_contexts::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 struct scan_shape2shape_same_layer { void - operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set &intruders, shape_interactions &interactions, db::Coord dist) const + operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set &intruders, unsigned int intruder_layer, shape_interactions &interactions, db::Coord dist) const { db::box_scanner2 scanner; - interaction_registration_shape1 rec (&interactions); + interaction_registration_shape1 rec (&interactions, intruder_layer); unsigned int id = subject_id0; for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags ()); !i.at_end (); ++i) { @@ -1598,10 +1661,10 @@ template struct scan_shape2shape_same_layer { void - operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set &intruders, shape_interactions &interactions, db::Coord dist) const + operator () (const db::Shapes *subject_shapes, unsigned int subject_id0, const std::set &intruders, unsigned int intruder_layer, shape_interactions &interactions, db::Coord dist) const { db::box_scanner scanner; - interaction_registration_shape1 rec (&interactions); + interaction_registration_shape1 rec (&interactions, intruder_layer); unsigned int id = subject_id0; for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags ()); !i.at_end (); ++i) { @@ -1622,10 +1685,10 @@ template 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 &intruders, shape_interactions &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 &intruders, unsigned int intruder_layer, shape_interactions &interactions, db::Coord dist) { db::box_scanner2 scanner; - interaction_registration_shape2shape rec (layout, &interactions); + interaction_registration_shape2shape rec (layout, &interactions, intruder_layer); unsigned int id = subject_id0; for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags ()); !i.at_end (); ++i) { @@ -1651,90 +1714,98 @@ struct scan_shape2shape_different_layers template void -local_processor::compute_local_cell (const db::local_processor_contexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation *op, const typename local_processor_cell_contexts::context_key_type &intruders, std::unordered_set &result) const +local_processor::compute_local_cell (const db::local_processor_contexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation *op, const typename local_processor_cell_contexts::context_key_type &intruders, std::vector > &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 interactions; - db::box_convert 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 ()); !i.at_end (); ++i) { + for (std::vector::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::Drop) { - const TS *ref = i->basic_ptr (typename TS::tag ()); - interactions.add_subject (id, *ref); - } + // local shapes vs. child cell - } + db::box_convert 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 () (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 () (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 scanner; - interaction_registration_shape2inst 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 ()); !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::Drop) { + const TS *ref = i->basic_ptr (typename TS::tag ()); + interactions.add_subject (id, *ref); + } + } - unsigned int inst_id = 0; + typename std::map >::const_iterator ipl = intruders.second.find (*il); + static std::set 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 () (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 () (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 scanner; + interaction_registration_shape2inst 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 ()); !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::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::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 (), inst_bci); + scanner.process (rec, op->dist (), db::box_convert (), inst_bci); + + } } diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index fc034c341..f5044af15 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -56,7 +56,7 @@ public: typedef container::const_iterator iterator; typedef container::value_type::second_type::const_iterator iterator2; typedef typename std::unordered_map::const_iterator subject_iterator; - typedef typename std::unordered_map::const_iterator intruder_iterator; + typedef typename std::unordered_map >::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 &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 &intruder_shape (unsigned int id) const; unsigned int next_id () { @@ -108,7 +108,7 @@ public: private: std::unordered_map > m_interactions; std::unordered_map m_subject_shapes; - std::unordered_map m_intruder_shapes; + std::unordered_map > 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 *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst); - void propagate (const std::unordered_set &res); + void propagate (unsigned int layer, const std::unordered_set &res); - std::unordered_set &propagated () + std::unordered_set &propagated (unsigned int l) { - return m_propagated; + return m_propagated [l]; } - const std::unordered_set &propagated () const + const std::unordered_set &propagated (unsigned int l) const { - return m_propagated; + typename std::map >::const_iterator i = m_propagated.find (l); + if (i != m_propagated.end ()) { + return i->second; + } else { + static std::unordered_set s_empty; + return s_empty; + } } size_t size () const @@ -174,7 +180,7 @@ public: } private: - std::unordered_set m_propagated; + std::map > m_propagated; std::vector > m_drops; tl::Mutex m_lock; }; @@ -183,7 +189,7 @@ template class DB_PUBLIC local_processor_cell_contexts { public: - typedef std::pair, std::set > context_key_type; + typedef std::pair, std::map > > context_key_type; typedef std::unordered_map > context_map_type; typedef typename context_map_type::const_iterator iterator; @@ -192,7 +198,7 @@ public: db::local_processor_cell_context *find_context (const context_key_type &intruders); db::local_processor_cell_context *create (const context_key_type &intruders); - void compute_results (const local_processor_contexts &contexts, db::Cell *cell, const local_operation *op, unsigned int output_layer, const local_processor *proc); + void compute_results (const local_processor_contexts &contexts, db::Cell *cell, const local_operation *op, const std::vector &output_layer, const local_processor *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 &l) { - m_intruder_layer = l; + m_intruder_layers = l; } - unsigned int intruder_layer () const + const std::vector &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 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 *proc, local_processor_contexts &contexts, db::Cell *cell, local_processor_cell_contexts *cell_contexts, const local_operation *op, unsigned int output_layer); + local_processor_result_computation_task (const local_processor *proc, local_processor_contexts &contexts, db::Cell *cell, local_processor_cell_contexts *cell_contexts, const local_operation *op, const std::vector &output_layers); void perform (); private: @@ -344,7 +351,7 @@ private: db::Cell *mp_cell; local_processor_cell_contexts *mp_cell_contexts; const local_operation *mp_op; - unsigned int m_output_layer; + std::vector m_output_layers; }; template @@ -370,9 +377,11 @@ class DB_PUBLIC local_processor public: local_processor (db::Layout *layout, db::Cell *top, const std::set *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 *subject_breakout_cells = 0, const std::set *intruder_breakout_cells = 0); - void run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer); - void compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, unsigned int intruder_layer) const; - void compute_results (local_processor_contexts &contexts, const local_operation *op, unsigned int output_layer) const; + void run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layers); + void run (local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers, const std::vector &output_layers); + void run (local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers, unsigned int output_layer); + void compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers) const; + void compute_results (local_processor_contexts &contexts, const local_operation *op, const std::vector &output_layers) const; void set_description (const std::string &d) { @@ -445,8 +454,8 @@ private: void do_compute_contexts (db::local_processor_cell_context *cell_context, const db::local_processor_contexts &contexts, db::local_processor_cell_context *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::context_key_type &intruders, db::Coord dist) const; void issue_compute_contexts (db::local_processor_contexts &contexts, db::local_processor_cell_context *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::context_key_type &intruders, db::Coord dist) const; void push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set &result) const; - void compute_local_cell (const db::local_processor_contexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation *op, const typename local_processor_cell_contexts::context_key_type &intruders, std::unordered_set &result) const; - std::pair effective_instance (local_processor_contexts &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 &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation *op, const typename local_processor_cell_contexts::context_key_type &intruders, std::vector > &result) const; + std::pair 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 { diff --git a/src/db/db/dbLocalOperation.cc b/src/db/db/dbLocalOperation.cc index 444c1838c..20a77e6f4 100644 --- a/src/db/db/dbLocalOperation.cc +++ b/src/db/db/dbLocalOperation.cc @@ -59,8 +59,11 @@ BoolAndOrNotLocalOperation::description () const } void -BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const +BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { + tl_assert (results.size () == 1); + std::unordered_set &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 others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const +void +SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const +EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + EdgeBooleanClusterCollector > cluster_collector (&result, m_op); db::box_scanner scanner; @@ -213,7 +223,7 @@ EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const sh std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::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 &interactions, std::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const +EdgeToPolygonLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + tl_assert (results.size () == 1); + std::unordered_set &result = results.front (); + db::EdgeProcessor ep; std::set others; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { - others.insert (interactions.intruder_shape (*j)); + others.insert (interactions.intruder_shape (*j).second); } } diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index 890d1f0d1..5cb21d691 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -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 &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const = 0; + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &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 &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const; + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &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 &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const; + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &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 &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const; + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &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 &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const; + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &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; diff --git a/src/db/unit_tests/dbHierProcessorTests.cc b/src/db/unit_tests/dbHierProcessorTests.cc index de0508386..4d589411c 100644 --- a/src/db/unit_tests/dbHierProcessorTests.cc +++ b/src/db/unit_tests/dbHierProcessorTests.cc @@ -55,18 +55,19 @@ public: // .. nothing yet .. } - virtual void compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const + virtual void compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { db::shape_interactions sized_interactions = interactions; for (db::shape_interactions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { for (db::shape_interactions::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 &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 &interactions, std::unordered_set &result, size_t max_vertex_count, double area_ratio) const + virtual void compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { db::shape_interactions sized_interactions = interactions; for (db::shape_interactions::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::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::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 >::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 contexts; - proc.compute_contexts (contexts, lop, l1, l2); + std::vector 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 contexts; - proc.compute_contexts (contexts, lop, l1, l2); + std::vector 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); } }