diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 26cc7608e..9399cebc2 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -622,21 +622,28 @@ public: typedef typename local_processor_cell_contexts::context_key_type interactions_value_type; typedef std::unordered_map, interactions_value_type> interactions_type; - interaction_registration_inst2shape (db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, interactions_type *result) - : mp_subject_layout (subject_layout), m_subject_layer (subject_layer), m_dist (dist), mp_result (result), m_rt (subject_layout) + interaction_registration_inst2shape (db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, const std::map &override_distance, interactions_type *result) + : mp_subject_layout (subject_layout), m_subject_layer (subject_layer), m_dist (dist), m_override_distance (override_distance), mp_result (result), m_rt (subject_layout) { // nothing yet .. } void add (const db::CellInstArray *inst, unsigned int, const TI *ref, unsigned int layer) { - collect_instance_shape_interactions (inst, layer, *ref, m_dist); + db::Coord d = m_dist; + auto od = m_override_distance.find (layer); + if (od != m_override_distance.end ()) { + d = std::min (d, od->second); + } + + collect_instance_shape_interactions (inst, layer, *ref, d); } private: db::Layout *mp_subject_layout; unsigned int m_subject_layer; db::Coord m_dist; + std::map m_override_distance; interactions_type *mp_result; db::shape_reference_translator_with_trans m_rt; @@ -681,11 +688,11 @@ private: // LocalProcessorContextComputationTask implementation template -local_processor_context_computation_task::local_processor_context_computation_task (const local_processor *proc, 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) +local_processor_context_computation_task::local_processor_context_computation_task (const local_processor *proc, 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 std::map &override_distance) : tl::Task (), mp_proc (proc), mp_contexts (&contexts), mp_parent_context (parent_context), mp_subject_parent (subject_parent), mp_subject_cell (subject_cell), m_subject_cell_inst (subject_cell_inst), - mp_intruder_cell (intruder_cell), m_dist (dist) + mp_intruder_cell (intruder_cell), m_dist (dist), m_override_distance (override_distance) { // This is quick, but will take away the intruders from the caller m_intruders.swap (intruders); @@ -695,7 +702,7 @@ template void local_processor_context_computation_task::perform () { - mp_proc->compute_contexts (*mp_contexts, mp_parent_context, mp_subject_parent, mp_subject_cell, m_subject_cell_inst, mp_intruder_cell, m_intruders, m_dist); + mp_proc->compute_contexts (*mp_contexts, mp_parent_context, mp_subject_parent, mp_subject_cell, m_subject_cell_inst, mp_intruder_cell, m_intruders, m_dist, m_override_distance); } // --------------------------------------------------------------------------------------------- @@ -900,8 +907,18 @@ void local_processor::compute_contexts (local_processor_contextsoverride_distance (); + std::map override_distance; + for (auto il = intruder_layers.begin (); il != intruder_layers.end (); ++il) { + auto o = od.find ((unsigned int) (il - intruder_layers.begin ())); + if (o != od.end ()) { + override_distance [*il] = o->second; + } + } + typename local_processor_cell_contexts::context_key_type intruders; - issue_compute_contexts (contexts, 0, 0, mp_subject_top, db::ICplxTrans (), mp_intruder_top, intruders, op->dist ()); + issue_compute_contexts (contexts, 0, 0, mp_subject_top, db::ICplxTrans (), mp_intruder_top, intruders, op->dist (), override_distance); if (mp_cc_job.get ()) { mp_cc_job->start (); @@ -922,14 +939,15 @@ void local_processor::issue_compute_contexts (local_processor_contex const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, typename local_processor_cell_contexts::context_key_type &intruders, - db::Coord dist) const + db::Coord dist, + const std::map &override_distance) const { bool is_small_job = subject_cell->begin ().at_end (); if (! is_small_job && mp_cc_job.get ()) { - mp_cc_job->schedule (new local_processor_context_computation_task (this, contexts, parent_context, subject_parent, subject_cell, subject_cell_inst, intruder_cell, intruders, dist)); + mp_cc_job->schedule (new local_processor_context_computation_task (this, contexts, parent_context, subject_parent, subject_cell, subject_cell_inst, intruder_cell, intruders, dist, override_distance)); } else { - compute_contexts (contexts, parent_context, subject_parent, subject_cell, subject_cell_inst, intruder_cell, intruders, dist); + compute_contexts (contexts, parent_context, subject_parent, subject_cell, subject_cell_inst, intruder_cell, intruders, dist, override_distance); } } @@ -941,7 +959,8 @@ void local_processor::compute_contexts (local_processor_contexts::context_key_type &intruders, - db::Coord dist_top) const + db::Coord dist_top, + const std::map &override_distance) const { CRONOLOGY_COLLECTION_BRACKET(event_compute_contexts) @@ -1041,10 +1060,16 @@ void local_processor::compute_contexts (local_processor_contexts::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) { + auto od = override_distance.find (*il); + db::Coord d = dist; + if (od != override_distance.end ()) { + d = std::min (d, od->second); + } + db::box_convert inst_bci (*mp_intruder_layout, contexts.actual_intruder_layer (*il)); db::box_scanner2 scanner; - interaction_registration_inst2inst rec (mp_subject_layout, contexts.subject_layer (), mp_intruder_layout, contexts.actual_intruder_layer (*il), contexts.is_foreign (*il), dist, &interactions); + interaction_registration_inst2inst rec (mp_subject_layout, contexts.subject_layer (), mp_intruder_layout, contexts.actual_intruder_layer (*il), contexts.is_foreign (*il), d, &interactions); unsigned int id = 0; @@ -1095,7 +1120,7 @@ void local_processor::compute_contexts (local_processor_contexts scanner; db::addressable_object_from_shape heap; - interaction_registration_inst2shape rec (mp_subject_layout, contexts.subject_layer (), dist, &interactions); + interaction_registration_inst2shape rec (mp_subject_layout, contexts.subject_layer (), dist, override_distance, &interactions); for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) { if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) { @@ -1127,7 +1152,7 @@ void local_processor::compute_contexts (local_processor_contextscell (i->first.first); db::Cell *intruder_child_cell = (subject_cell == intruder_cell ? subject_child_cell : 0); - issue_compute_contexts (contexts, cell_context, subject_cell, subject_child_cell, i->first.second, intruder_child_cell, i->second, dist); + issue_compute_contexts (contexts, cell_context, subject_cell, subject_child_cell, i->first.second, intruder_child_cell, i->second, dist, override_distance); } @@ -1386,7 +1411,8 @@ 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::vector > &result) const { - db::Coord dist = dist_for_cell (subject_cell->cell_index (), op->dist ()); + auto override_distance = op->override_distance (); + db::Coord dist_global = dist_for_cell (subject_cell->cell_index (), op->dist ()); const db::Shapes *subject_shapes = &subject_cell->shapes (contexts.subject_layer ()); db::shape_to_object s2o; @@ -1412,6 +1438,13 @@ local_processor::compute_local_cell (const db::local_processor_conte unsigned int il_index = 0; for (std::vector::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il, ++il_index) { + // compute effective distance + db::Coord dist = dist_global; + auto od = override_distance.find (il_index); + if (od != override_distance.end ()) { + dist = std::min (dist, dist_for_cell (subject_cell->cell_index (), od->second)); + } + unsigned int ail = contexts.actual_intruder_layer (*il); bool foreign = contexts.is_foreign (*il); @@ -1633,15 +1666,16 @@ local_processor::run_flat (const generic_shape_iterator &subject // build the subjects in the intruders list - db::Coord dist = op->dist (); + db::Coord dist_global = op->dist (); + auto override_distance = op->override_distance (); - db::Box subjects_box = safe_box_enlarged (subjects.bbox (), dist, dist); + db::Box subjects_box = safe_box_enlarged (subjects.bbox (), dist_global, dist_global); db::Box intruders_box; for (typename std::vector >::const_iterator il = intruders.begin (); il != intruders.end (); ++il) { intruders_box += il->bbox (); } - intruders_box = safe_box_enlarged (intruders_box, dist, dist); + intruders_box = safe_box_enlarged (intruders_box, dist_global, dist_global); db::Box common_box = intruders_box & subjects_box; if (common_box.empty () || common_box.width () == 0 || common_box.height () == 0) { @@ -1670,6 +1704,12 @@ local_processor::run_flat (const generic_shape_iterator &subject bool ff = foreign.size () > il_index && foreign [il_index]; + db::Coord dist = dist_global; + auto od = override_distance.find (il_index); + if (od != override_distance.end ()) { + dist = std::min (dist, od->second); + } + if (*il == subjects && ! ff) { interaction_registration_shape1_scanner_combo scanner (&interactions, il_index, report_progress (), scan_description); @@ -1736,6 +1776,12 @@ local_processor::run_flat (const generic_shape_iterator &subject bool ff = foreign.size () > il_index && foreign [il_index]; + db::Coord dist = dist_global; + auto od = override_distance.find (il_index); + if (od != override_distance.end ()) { + dist = std::min (dist, od->second); + } + if (*il == subjects && ! ff) { interaction_registration_shape1_scanner_combo scanner (&interactions, il_index, report_progress (), scan_description); @@ -1789,6 +1835,7 @@ local_processor::run_flat (const generic_shape_iterator &subject } } + } } diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 8d446641a..a2a3d8714 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -359,7 +359,7 @@ class DB_PUBLIC local_processor_context_computation_task : public tl::Task { public: - local_processor_context_computation_task (const local_processor *proc, 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); + local_processor_context_computation_task (const local_processor *proc, 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 std::map &override_distance); void perform (); private: @@ -372,6 +372,7 @@ private: const db::Cell *mp_intruder_cell; typename local_processor_cell_contexts::context_key_type m_intruders; db::Coord m_dist; + std::map m_override_distance; }; template @@ -578,8 +579,8 @@ private: void next () const; size_t get_progress () const; - void 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, 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 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, const typename local_processor_cell_contexts::context_key_type &intruders, db::Coord dist, const std::map &override_distance) 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 std::map &override_distance) 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; bool subject_cell_is_breakout (db::cell_index_type ci) const diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index 5ce9c2db3..8f8651865 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -118,6 +118,14 @@ public: */ virtual db::Coord dist () const { return 0; } + /** + * @brief Gets a override distance for a specific input layer + * The input layers are numbered from 0 to n-1, where n is the allowed number of intruder layers + * The override distance is used insted of the global distance ("dist()") for the given + * input layer. The override distance cannot be bigger than the global distance. + */ + virtual std::map override_distance () const { return std::map (); } + /** * @brief Gets the cell variant reducer that indicates whether to build cell variants and which */ diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index f60484eb6..82c17c80e 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -813,8 +813,27 @@ check_local_operation::do_compute_local (db::Layout *layout, db::Cell *s unsigned int primary_intruder_layer = check_local_operation_base::m_has_other ? 1 : 0; + // in the case of a two-layer check, return if there is no second layer shape + if (check_local_operation_base::m_has_other) { + + bool any = false; + for (auto i = interactions.begin (); i != interactions.end () && ! any; ++i) { + for (auto ii = i->second.begin (); ii != i->second.end () && ! any; ++ii) { + const auto &is = interactions.intruder_shape (*ii); + any = (is.first != primary_intruder_layer); + } + } + + if (! any) { + return; + } + + } + for (auto i = interactions.begin (); i != interactions.end (); ++i) { + subjects.push_back (&interactions.subject_shape (i->first)); + for (auto ii = i->second.begin (); ii != i->second.end (); ++ii) { const auto &is = interactions.intruder_shape (*ii); if (is.first == primary_intruder_layer) { @@ -823,6 +842,7 @@ check_local_operation::do_compute_local (db::Layout *layout, db::Cell *s intruders.insert (&is.second); } } + } tl_assert (results.size () == 1); @@ -863,6 +883,19 @@ check_local_operation::do_compute_local (db::Layout *layout, db::Cell *s } } +template +std::map +check_local_operation::override_distance () const +{ + // makes sure, the "foreign"-type pseudo-intruder used for merging only + // does not use the full search range, but only "touching". + std::map od; + if (check_local_operation_base::m_has_other) { + od.insert (std::make_pair (1, 0)); + } + return od; +} + template db::Coord check_local_operation::dist () const diff --git a/src/db/db/dbRegionLocalOperations.h b/src/db/db/dbRegionLocalOperations.h index 1650d6fb0..cafe7419e 100644 --- a/src/db/db/dbRegionLocalOperations.h +++ b/src/db/db/dbRegionLocalOperations.h @@ -207,6 +207,7 @@ public: check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool is_merged, bool has_other, bool other_is_merged, const db::RegionCheckOptions &options); virtual db::Coord dist () const; + virtual std::map override_distance () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual bool requests_single_subjects () const { return true; } virtual std::string description () const;