From 37334d40b973151156de1865e4f10ca4a07f57ca Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 18 Nov 2023 11:09:31 +0100 Subject: [PATCH] WIP --- src/db/db/dbCompoundOperation.cc | 34 ++++- src/db/db/dbCompoundOperation.h | 216 ++++++++++++++++++++++++++++--- src/db/db/dbDeepEdges.cc | 33 ++++- src/db/db/dbDeepRegion.cc | 20 +++ src/db/db/dbHierProcessor.cc | 2 +- src/db/db/dbHierProcessor.h | 5 + src/db/db/dbRegionUtils.h | 3 + 7 files changed, 287 insertions(+), 26 deletions(-) diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index a9c232ed0..64a31a17b 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -1298,6 +1298,16 @@ CompoundRegionProcessingOperationNode::processed (db::Layout *layout, const db:: } } +void +CompoundRegionProcessingOperationNode::processed (db::Layout *layout, const db::polygon_ref &p, std::vector &res) const +{ + std::vector poly; + mp_proc->process (p.obj ().transformed (p.trans ()), poly); + for (std::vector::const_iterator p = poly.begin (); p != poly.end (); ++p) { + res.push_back (db::PolygonRef (*p, layout->shape_repository ())); + } +} + // --------------------------------------------------------------------------------------------- CompoundRegionToEdgeProcessingOperationNode::CompoundRegionToEdgeProcessingOperationNode (PolygonToEdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) @@ -1338,6 +1348,12 @@ CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db:: mp_proc->process (p.obj ().transformed (p.trans ()), res); } +void +CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::polygon_ref &p, std::vector &res) const +{ + mp_proc->process (p.obj ().transformed (p.trans ()), res); +} + // --------------------------------------------------------------------------------------------- CompoundRegionEdgeProcessingOperationNode::CompoundRegionEdgeProcessingOperationNode (EdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) @@ -1456,6 +1472,12 @@ CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const mp_proc->process (p.obj ().transformed (p.trans ()), res); } +void +CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const db::polygon_ref &p, std::vector &res) const +{ + mp_proc->process (p.obj ().transformed (p.trans ()), res); +} + // --------------------------------------------------------------------------------------------- CompoundRegionEdgePairToPolygonProcessingOperationNode::CompoundRegionEdgePairToPolygonProcessingOperationNode (EdgePairToPolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) @@ -1593,9 +1615,13 @@ CompoundRegionCheckOperationNode::computed_dist () const void CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase *proc) const { + // consider magnification variants + db::EdgeRelationFilter check = m_check; + check.set_distance (proc->dist_for_cell (cell, check.distance ())); + // TODO: needs a concept to deal with merged/non-merged inputs bool is_merged = true; - db::check_local_operation op (m_check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options); + db::check_local_operation op (check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options); tl_assert (results.size () == 1); if (results.front ().empty ()) { @@ -1611,9 +1637,13 @@ CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache void CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase *proc) const { + // consider magnification variants + db::EdgeRelationFilter check = m_check; + check.set_distance (proc->dist_for_cell (cell, check.distance ())); + // TODO: needs a concept to deal with merged/non-merged inputs bool is_merged = true; - db::check_local_operation op (m_check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options); + db::check_local_operation op (check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options); tl_assert (results.size () == 1); if (results.front ().empty ()) { diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index d65b96ec7..04872fa9e 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -1138,6 +1138,7 @@ private: void processed (db::Layout *, const db::Polygon &p, std::vector &res) const; void processed (db::Layout *, const db::PolygonRef &p, std::vector &res) const; + void processed (db::Layout *, const db::polygon_ref &p, std::vector &res) const; template void implement_compute_local (db::CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase *proc) const @@ -1149,9 +1150,33 @@ private: std::vector res; for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + res.clear (); - processed (layout, *p, res); - results.front ().insert (res.begin (), res.end ()); + + if (proc->vars ()) { + + // in the presence of variants, handle the object in top level space + + const std::map &vv = proc->vars ()->variants (cell->cell_index ()); + tl_assert (vv.size () == 1); + const db::ICplxTrans &tr = vv.begin ()->first; + processed (layout, tr * *p, res); + + if (! res.empty ()) { + db::ICplxTrans tri = tr.inverted (); + for (auto r = res.begin (); r != res.end (); ++r) { + results.front ().insert (tri * *r); + } + } + + } else { + + processed (layout, *p, res); + + results.front ().insert (res.begin (), res.end ()); + + } + } } }; @@ -1175,7 +1200,6 @@ public: private: db::PolygonSizer m_proc; - CompoundTransformationReducer m_vars; }; class DB_PUBLIC CompoundRegionMergeOperationNode @@ -1286,9 +1310,33 @@ private: std::vector res; for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + res.clear (); - processed (layout, *p, res); - results.front ().insert (res.begin (), res.end ()); + + if (proc->vars ()) { + + // in the presence of variants, handle the object in top level space + + const std::map &vv = proc->vars ()->variants (cell->cell_index ()); + tl_assert (vv.size () == 1); + const db::ICplxTrans &tr = vv.begin ()->first; + processed (layout, tr * *p, res); + + if (! res.empty ()) { + db::ICplxTrans tri = tr.inverted (); + for (auto r = res.begin (); r != res.end (); ++r) { + results.front ().insert (tri * *r); + } + } + + } else { + + processed (layout, *p, res); + + results.front ().insert (res.begin (), res.end ()); + + } + } } }; @@ -1331,9 +1379,33 @@ private: std::vector res; for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + res.clear (); - processed (layout, *p, res); - results.front ().insert (res.begin (), res.end ()); + + if (proc->vars ()) { + + // in the presence of variants, handle the object in top level space + + const std::map &vv = proc->vars ()->variants (cell->cell_index ()); + tl_assert (vv.size () == 1); + const db::ICplxTrans &tr = vv.begin ()->first; + processed (layout, tr * *p, res); + + if (! res.empty ()) { + db::ICplxTrans tri = tr.inverted (); + for (auto r = res.begin (); r != res.end (); ++r) { + results.front ().insert (tri * *r); + } + } + + } else { + + processed (layout, *p, res); + + results.front ().insert (res.begin (), res.end ()); + + } + } } }; @@ -1377,9 +1449,33 @@ private: std::vector res; for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + res.clear (); - processed (layout, *p, res); - results.front ().insert (res.begin (), res.end ()); + + if (proc->vars ()) { + + // in the presence of variants, handle the object in top level space + + const std::map &vv = proc->vars ()->variants (cell->cell_index ()); + tl_assert (vv.size () == 1); + const db::ICplxTrans &tr = vv.begin ()->first; + processed (layout, tr * *p, res); + + if (! res.empty ()) { + db::ICplxTrans tri = tr.inverted (); + for (auto r = res.begin (); r != res.end (); ++r) { + results.front ().insert (tri * *r); + } + } + + } else { + + processed (layout, *p, res); + + results.front ().insert (res.begin (), res.end ()); + + } + } } }; @@ -1420,9 +1516,33 @@ private: std::vector res; for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + res.clear (); - mp_proc->process (*p, res); - results.front ().insert (res.begin (), res.end ()); + + if (proc->vars ()) { + + // in the presence of variants, handle the object in top level space + + const std::map &vv = proc->vars ()->variants (cell->cell_index ()); + tl_assert (vv.size () == 1); + const db::ICplxTrans &tr = vv.begin ()->first; + mp_proc->process (tr * *p, res); + + if (! res.empty ()) { + db::ICplxTrans tri = tr.inverted (); + for (auto r = res.begin (); r != res.end (); ++r) { + results.front ().insert (tri * *r); + } + } + + } else { + + mp_proc->process (*p, res); + + results.front ().insert (res.begin (), res.end ()); + + } + } } }; @@ -1455,6 +1575,7 @@ private: void processed (db::Layout *, const db::Polygon &p, std::vector &res) const; void processed (db::Layout *layout, const db::PolygonRef &p, std::vector &res) const; + void processed (db::Layout *, const db::polygon_ref &p, std::vector &res) const; template void implement_compute_local (db::CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase *proc) const @@ -1466,9 +1587,33 @@ private: std::vector res; for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + res.clear (); - processed (layout, *p, res); - results.front ().insert (res.begin (), res.end ()); + + if (proc->vars ()) { + + // in the presence of variants, handle the object in top level space + + const std::map &vv = proc->vars ()->variants (cell->cell_index ()); + tl_assert (vv.size () == 1); + const db::ICplxTrans &tr = vv.begin ()->first; + processed (layout, tr * *p, res); + + if (! res.empty ()) { + db::ICplxTrans tri = tr.inverted (); + for (auto r = res.begin (); r != res.end (); ++r) { + results.front ().insert (tri * *r); + } + } + + } else { + + processed (layout, *p, res); + + results.front ().insert (res.begin (), res.end ()); + + } + } } }; @@ -1506,11 +1651,12 @@ public: virtual void do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions & /*interactions*/, std::vector > & /*results*/, const db::LocalProcessorBase * /*proc*/) const { } private: - PolygonToEdgePairProcessorBase *mp_proc; + PolygonToEdgePairProcessorBase *mp_proc; bool m_owns_proc; void processed (db::Layout *, const db::Polygon &p, std::vector &res) const; void processed (db::Layout *layout, const db::PolygonRef &p, std::vector &res) const; + void processed (db::Layout *, const db::polygon_ref &p, std::vector &res) const; template void implement_compute_local (db::CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase *proc) const @@ -1522,9 +1668,33 @@ private: std::vector res; for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + res.clear (); - processed (layout, *p, res); - results.front ().insert (res.begin (), res.end ()); + + if (proc->vars ()) { + + // in the presence of variants, handle the object in top level space + + const std::map &vv = proc->vars ()->variants (cell->cell_index ()); + tl_assert (vv.size () == 1); + const db::ICplxTrans &tr = vv.begin ()->first; + processed (layout, tr * *p, res); + + if (! res.empty ()) { + db::ICplxTrans tri = tr.inverted (); + for (auto r = res.begin (); r != res.end (); ++r) { + results.front ().insert (tri * *r); + } + } + + } else { + + processed (layout, *p, res); + + results.front ().insert (res.begin (), res.end ()); + + } + } } }; @@ -1560,6 +1730,9 @@ public: virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual db::Coord computed_dist () const; + virtual const TransformationReducer *vars () const { return &m_vars; } + virtual bool wants_variants () const { return true; } + virtual void do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const LocalProcessorBase *proc) const; virtual void do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const LocalProcessorBase *proc) const; @@ -1575,6 +1748,7 @@ private: db::RegionCheckOptions m_options; bool m_has_other; bool m_is_other_merged; + db::MagnificationReducer m_vars; }; @@ -1599,6 +1773,9 @@ public: : mp_node (node) { } + const TransformationReducer *vars () const { return mp_node->vars (); } + bool wants_variants () const { return mp_node->wants_variants (); } + protected: virtual void do_compute_local (db::Layout *layout, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase *proc) const { @@ -1611,8 +1788,6 @@ protected: virtual bool requests_single_subjects () const { return true; } virtual std::string description () const { return mp_node->description (); } - const TransformationReducer *vars () const { return mp_node->vars (); } - bool wants_variants () const { return mp_node->wants_variants (); } std::vector inputs () const { return mp_node->inputs (); } private: @@ -1645,6 +1820,9 @@ public: } } + const TransformationReducer *vars () const { return mp_node->vars (); } + bool wants_variants () const { return mp_node->wants_variants (); } + protected: virtual void do_compute_local (db::Layout *layout, db::Cell *cell, const shape_interactions, db::object_with_properties > &interactions, std::vector > > &results, const db::LocalProcessorBase *proc) const { @@ -1671,8 +1849,6 @@ protected: virtual bool requests_single_subjects () const { return true; } virtual std::string description () const { return mp_node->description (); } - const TransformationReducer *vars () const { return mp_node->vars (); } - bool wants_variants () const { return mp_node->wants_variants (); } std::vector inputs () const { return mp_node->inputs (); } private: diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 38428d3fc..ae584c443 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -1941,12 +1941,16 @@ public: // .. nothing yet .. } - virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase * /*proc*/) const + virtual void do_compute_local (db::Layout * /*layout*/, db::Cell *cell, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase *proc) const { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); - edge2edge_check_for_edges > edge_check (m_check, result, m_has_other); + // implement check in local coordinates in the presence of magnification variants + EdgeRelationFilter check = m_check; + check.set_distance (proc->dist_for_cell (cell, check.distance ())); + + edge2edge_check_for_edges > edge_check (check, result, m_has_other); db::box_scanner scanner; std::set others; @@ -1989,7 +1993,7 @@ public: } - scanner.process (edge_check, m_check.distance (), db::box_convert ()); + scanner.process (edge_check, check.distance (), db::box_convert ()); } virtual db::Coord dist () const @@ -2028,6 +2032,28 @@ DeepEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Coord const db::DeepLayer &edges = merged_deep_layer (); + // create cell variants for magnification if needed + + db::cell_variants_collector vars; + vars.collect (edges.layout (), edges.initial_cell ()); + + // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? + const_cast (edges).separate_variants (vars); + + if (other_deep && &other_deep->deep_layer ().layout () != &edges.layout ()) { + + // create cell variants for magnification for the other input if needed + + const db::DeepLayer &other_layer = other_deep->deep_layer (); + + db::cell_variants_collector vars; + vars.collect (other_layer.layout (), other_layer.initial_cell ()); + + // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? + const_cast (other_layer).separate_variants (vars); + + } + EdgeRelationFilter check (rel, d, options.metrics); check.set_include_zero (false); check.set_whole_edges (options.whole_edges); @@ -2045,6 +2071,7 @@ DeepEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Coord other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast (&edges.initial_cell ())); proc.set_base_verbosity (base_verbosity ()); + proc.set_vars (&vars); proc.set_threads (edges.store ()->threads ()); proc.run (&op, edges.layer (), other_deep ? other_deep->deep_layer ().layer () : edges.layer (), res->deep_layer ().layer ()); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index e33e40468..cb8510e93 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1799,6 +1799,16 @@ Output *region_cop_impl (DeepRegion *region, db::CompoundRegionOperationNode &no } compound_local_operation op (&node); + + // Prepare cell variants if needed + db::VariantsCollectorBase vc (op.vars ()); + if (op.wants_variants ()) { + vc.collect (polygons.layout (), polygons.initial_cell ()); + // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? + const_cast (polygons).separate_variants (vc); + proc.set_vars (&vc); + } + proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); return res.release (); @@ -1852,6 +1862,16 @@ Output *region_cop_with_properties_impl (DeepRegion *region, db::CompoundRegionO } compound_local_operation_with_properties op (&node, prop_constraint, res->properties_repository (), subject_pr, intruder_prs); + + // Prepare cell variants if needed + db::VariantsCollectorBase vc (op.vars ()); + if (op.wants_variants ()) { + vc.collect (polygons.layout (), polygons.initial_cell ()); + // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? + const_cast (polygons).separate_variants (vc); + proc.set_vars (&vc); + } + proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); return res.release (); diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 3529db310..b93f96f35 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1143,7 +1143,7 @@ public: db::Box ref_box = db::box_convert () (*ref); for (db::CellInstArray::iterator n = inst->begin_touching (safe_box_enlarged (ref_box, m_dist - 1, m_dist - 1), inst_bc); !n.at_end (); ++n) { db::ICplxTrans tn = inst->complex_trans (*n); - db::Box region = ref_box.transformed (tn.inverted ()).enlarged (db::Vector (m_dist, m_dist)) & intruder_cell.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist)); + db::Box region = ref_box.enlarged (db::Vector (m_dist, m_dist)).transformed (tn.inverted ()) & intruder_cell.bbox (m_intruder_layer) /*.enlarged (db::Vector (m_dist, m_dist))@@@*/; if (! region.empty ()) { add_shapes_from_intruder_inst (id1, intruder_cell, tn, inst_id, region); } diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 416b2612f..e0f6a9778 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -490,6 +490,11 @@ public: mp_vars = vars; } + const db::VariantsCollectorBase *vars () const + { + return mp_vars; + } + db::Coord dist_for_cell (db::cell_index_type cell_index, db::Coord dist) const; db::Coord dist_for_cell (const db::Cell *cell, db::Coord dist) const; diff --git a/src/db/db/dbRegionUtils.h b/src/db/db/dbRegionUtils.h index cd423fc0f..a213f26c2 100644 --- a/src/db/db/dbRegionUtils.h +++ b/src/db/db/dbRegionUtils.h @@ -593,11 +593,14 @@ public: SinglePolygonCheck (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options); virtual void process (const db::Polygon &polygon, std::vector &res) const; + virtual const TransformationReducer *vars () const { return &m_vars; } + virtual bool wants_variants () const { return true; } private: db::edge_relation_type m_relation; db::Coord m_d; db::RegionCheckOptions m_options; + db::MagnificationReducer m_vars; }; } // namespace db