From dd4fcd9e3681f04721ddf605093329cd05332396 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 10 Feb 2019 18:39:32 +0100 Subject: [PATCH] WIP: templatized local hierarchical processor. --- src/db/db/dbDeepRegion.cc | 2 +- src/db/db/dbHierProcessor.cc | 435 ++++++++++++++-------- src/db/db/dbHierProcessor.h | 160 ++++---- src/db/db/dbLocalOperation.cc | 20 +- src/db/db/dbLocalOperation.h | 19 +- src/db/unit_tests/dbHierProcessorTests.cc | 32 +- 6 files changed, 400 insertions(+), 268 deletions(-) diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 2372dc596..a10c0a99c 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -463,7 +463,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const db::BoolAndOrNotLocalOperation op (and_op); - db::LocalProcessor proc (const_cast (&m_deep_layer.layout ()), const_cast (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&m_deep_layer.layout ()), const_cast (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (m_deep_layer.store ()->threads ()); proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ()); diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 03a2fb5d6..92a2b1ed6 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -65,6 +65,9 @@ namespace db // --------------------------------------------------------------------------------------------- // Shape reference translator +template class shape_reference_translator; +template class shape_reference_translator_with_trans; + template class shape_reference_translator { @@ -131,6 +134,29 @@ private: mutable std::unordered_map m_cache_by_shape; }; +template <> +class shape_reference_translator +{ +public: + typedef typename db::Edge shape_type; + + shape_reference_translator (db::Layout * /*target_layout*/) + { + // .. nothing yet .. + } + + const shape_type &operator() (const shape_type &s) const + { + return s; + } + + template + shape_type operator() (const shape_type &s, const Trans &tr) const + { + return s.transformed (tr); + } +}; + template class shape_reference_translator_with_trans { @@ -178,43 +204,68 @@ private: mutable std::unordered_map > m_cache; }; +template +class shape_reference_translator_with_trans +{ +public: + typedef typename db::Edge shape_type; + + shape_reference_translator_with_trans (db::Layout * /*target_layout*/, const Trans &trans) + : m_trans (trans) + { + // .. nothing yet .. + } + + shape_type operator() (const shape_type &s) const + { + return s.transformed (m_trans); + } + +private: + Trans m_trans; +}; + // --------------------------------------------------------------------------------------------- // LocalProcessorCellContext implementation -LocalProcessorCellContext::LocalProcessorCellContext () +template +local_processor_cell_context::local_processor_cell_context () { // .. nothing yet .. } -LocalProcessorCellContext::LocalProcessorCellContext (const LocalProcessorCellContext &other) +template +local_processor_cell_context::local_processor_cell_context (const local_processor_cell_context &other) : m_propagated (other.m_propagated), m_drops (other.m_drops) { // .. nothing yet .. } +template void -LocalProcessorCellContext::add (db::LocalProcessorCellContext *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst) +local_processor_cell_context::add (db::local_processor_cell_context *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst) { - m_drops.push_back (LocalProcessorCellDrop (parent_context, parent, cell_inst)); + m_drops.push_back (local_processor_cell_drop (parent_context, parent, cell_inst)); } +template void -LocalProcessorCellContext::propagate (const std::unordered_set &res) +local_processor_cell_context::propagate (const std::unordered_set &res) { if (res.empty ()) { return; } - for (std::vector::const_iterator d = m_drops.begin (); d != m_drops.end (); ++d) { + for (typename std::vector >::const_iterator d = m_drops.begin (); d != m_drops.end (); ++d) { tl_assert (d->parent_context != 0); tl_assert (d->parent != 0); db::Layout *subject_layout = d->parent->layout (); - shape_reference_translator_with_trans rt (subject_layout, d->cell_inst); - std::vector new_refs; + shape_reference_translator_with_trans rt (subject_layout, d->cell_inst); + std::vector new_refs; new_refs.reserve (res.size ()); - for (std::unordered_set::const_iterator r = res.begin (); r != res.end (); ++r) { + for (typename std::unordered_set::const_iterator r = res.begin (); r != res.end (); ++r) { new_refs.push_back (rt (*r)); } @@ -226,36 +277,43 @@ LocalProcessorCellContext::propagate (const std::unordered_set & } } +template class DB_PUBLIC local_processor_cell_context; +template class DB_PUBLIC local_processor_cell_context; + // --------------------------------------------------------------------------------------------- // LocalProcessorCellContexts implementation -LocalProcessorCellContexts::LocalProcessorCellContexts () +template +local_processor_cell_contexts::local_processor_cell_contexts () : mp_intruder_cell (0) { // .. nothing yet .. } -LocalProcessorCellContexts::LocalProcessorCellContexts (const db::Cell *intruder_cell) +template +local_processor_cell_contexts::local_processor_cell_contexts (const db::Cell *intruder_cell) : mp_intruder_cell (intruder_cell) { // .. nothing yet .. } -db::LocalProcessorCellContext * -LocalProcessorCellContexts::find_context (const context_key_type &intruders) +template +db::local_processor_cell_context * +local_processor_cell_contexts::find_context (const context_key_type &intruders) { - std::unordered_map::iterator c = m_contexts.find (intruders); + typename std::unordered_map >::iterator c = m_contexts.find (intruders); return c != m_contexts.end () ? &c->second : 0; } -db::LocalProcessorCellContext * -LocalProcessorCellContexts::create (const context_key_type &intruders) +template +db::local_processor_cell_context * +local_processor_cell_contexts::create (const context_key_type &intruders) { return &m_contexts[intruders]; } static void -subtract (std::unordered_set &res, const std::unordered_set &other, db::Layout *layout, const db::LocalProcessor *proc) +subtract (std::unordered_set &res, const std::unordered_set &other, db::Layout *layout, const db::local_processor *proc) { if (other.empty ()) { return; @@ -293,11 +351,21 @@ subtract (std::unordered_set &res, const std::unordered_set &res, const std::unordered_set &other, db::Layout * /*layout*/, const db::local_processor * /*proc*/) +{ + // for edges, we don't use a boolean core but just set intersection + for (std::unordered_set::const_iterator o = other.begin (); o != other.end (); ++o) { + res.erase (*o); + } +} + namespace { +template struct context_sorter { - bool operator () (const std::pair &a, const std::pair &b) + bool operator () (const std::pair::context_key_type *, db::local_processor_cell_context *> &a, const std::pair::context_key_type *, db::local_processor_cell_context *> &b) { return *a.first < *b.first; } @@ -305,13 +373,14 @@ struct context_sorter } +template void -LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &contexts, db::Cell *cell, const LocalOperation *op, unsigned int output_layer, const LocalProcessor *proc) +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) { CRONOLOGY_COMPUTE_BRACKET(event_compute_results) bool first = true; - std::unordered_set common; + std::unordered_set common; int index = 0; int total = int (m_contexts.size ()); @@ -319,15 +388,15 @@ LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &conte // NOTE: we use the ordering provided by key_type::operator< rather than the unordered map to achieve // reproducability across different platforms. unordered_map is faster, but for processing them, // strict ordering is a more robust choice. - std::vector > sorted_contexts; + std::vector *> > sorted_contexts; sorted_contexts.reserve (m_contexts.size ()); - for (std::unordered_map::iterator c = m_contexts.begin (); c != m_contexts.end (); ++c) { + for (typename std::unordered_map >::iterator c = m_contexts.begin (); c != m_contexts.end (); ++c) { sorted_contexts.push_back (std::make_pair (&c->first, &c->second)); } - std::sort (sorted_contexts.begin (), sorted_contexts.end (), context_sorter ()); + std::sort (sorted_contexts.begin (), sorted_contexts.end (), context_sorter ()); - for (std::vector >::const_iterator c = sorted_contexts.begin (); c != sorted_contexts.end (); ++c) { + for (typename std::vector *> >::const_iterator c = sorted_contexts.begin (); c != sorted_contexts.end (); ++c) { ++index; @@ -348,7 +417,7 @@ LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &conte } else { - std::unordered_set res; + std::unordered_set res; { tl::MutexLocker locker (&c->second->lock ()); res = c->second->propagated (); @@ -368,8 +437,8 @@ LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &conte CRONOLOGY_COMPUTE_BRACKET(event_propagate) - std::unordered_set lost; - for (std::unordered_set::const_iterator i = common.begin (); i != common.end (); ++i) { + 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); } @@ -381,15 +450,15 @@ LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &conte if (! lost.empty ()) { subtract (common, lost, cell->layout (), proc); - for (std::vector >::const_iterator cc = sorted_contexts.begin (); cc != c; ++cc) { + for (typename std::vector *> >::const_iterator cc = sorted_contexts.begin (); cc != c; ++cc) { cc->second->propagate (lost); } } } - std::unordered_set gained; - for (std::unordered_set::const_iterator i = res.begin (); i != res.end (); ++i) { + 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); } @@ -414,41 +483,50 @@ LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &conte proc->push_results (cell, output_layer, common); } +template class DB_PUBLIC local_processor_cell_contexts; +template class DB_PUBLIC local_processor_cell_contexts; + // --------------------------------------------------------------------------------------------- -ShapeInteractions::ShapeInteractions () +template +shape_interactions::shape_interactions () : m_id (0) { // .. nothing yet .. } +template bool -ShapeInteractions::has_shape_id (unsigned int id) const +shape_interactions::has_shape_id (unsigned int id) const { return m_shapes.find (id) != m_shapes.end (); } +template void -ShapeInteractions::add_shape (unsigned int id, const db::PolygonRef &shape) +shape_interactions::add_shape (unsigned int id, const T &shape) { m_shapes [id] = shape; } +template void -ShapeInteractions::add_subject (unsigned int id, const db::PolygonRef &shape) +shape_interactions::add_subject (unsigned int id, const T &shape) { add_shape (id, shape); m_interactions.insert (std::make_pair (id, container::value_type::second_type ())); } +template void -ShapeInteractions::add_interaction (unsigned int subject_id, unsigned int intruder_id) +shape_interactions::add_interaction (unsigned int subject_id, unsigned int intruder_id) { m_interactions [subject_id].push_back (intruder_id); } +template const std::vector & -ShapeInteractions::intruders_for (unsigned int subject_id) const +shape_interactions::intruders_for (unsigned int subject_id) const { iterator i = m_interactions.find (subject_id); if (i == m_interactions.end ()) { @@ -459,40 +537,54 @@ ShapeInteractions::intruders_for (unsigned int subject_id) const } } -const db::PolygonRef & -ShapeInteractions::shape (unsigned int id) const +template +const T & +shape_interactions::shape (unsigned int id) const { - std::unordered_map::const_iterator i = m_shapes.find (id); + typename std::unordered_map::const_iterator i = m_shapes.find (id); if (i == m_shapes.end ()) { - static db::PolygonRef s; + static T s; return s; } else { return i->second; } } +template class DB_PUBLIC shape_interactions; +template class DB_PUBLIC shape_interactions; + // --------------------------------------------------------------------------------------------- // Helper classes for the LocalProcessor namespace { -inline unsigned int polygon_ref_flags () +template unsigned int shape_flags (); + +template <> +inline unsigned int shape_flags () { return 1 << db::ShapeIterator::PolygonRef; } -struct InteractionRegistrationShape2Shape - : db::box_scanner_receiver2 +template <> +inline unsigned int shape_flags () +{ + return db::ShapeIterator::Edges; +} + +template +struct interaction_registration_shape2shape + : db::box_scanner_receiver2 { public: - InteractionRegistrationShape2Shape (db::Layout *layout, ShapeInteractions *result) + interaction_registration_shape2shape (db::Layout *layout, shape_interactions *result) : mp_result (result), mp_layout (layout) { // nothing yet .. } - void add (const db::PolygonRef *ref1, unsigned int id1, const db::PolygonRef *ref2, unsigned int id2) + void add (const T *ref1, unsigned int id1, const T *ref2, unsigned int id2) { mp_result->add_shape (id1, *ref1); @@ -500,7 +592,7 @@ public: // In order to guarantee the refs come from the subject layout, we'd need to // rewrite them if (!mp_result->has_shape_id (id2)) { - db::shape_reference_translator rt (mp_layout); + db::shape_reference_translator rt (mp_layout); mp_result->add_shape (id2, rt (*ref2)); } } else { @@ -511,21 +603,22 @@ public: } private: - ShapeInteractions *mp_result; + shape_interactions *mp_result; db::Layout *mp_layout; }; -struct InteractionRegistrationShape1 - : db::box_scanner_receiver +template +struct interaction_registration_shape1 + : db::box_scanner_receiver { public: - InteractionRegistrationShape1 (ShapeInteractions *result) + interaction_registration_shape1 (shape_interactions *result) : mp_result (result) { // nothing yet .. } - void add (const db::PolygonRef *ref1, unsigned int id1, const db::PolygonRef *ref2, unsigned int id2) + void add (const T *ref1, unsigned int id1, const T *ref2, unsigned int id2) { mp_result->add_shape (id1, *ref1); mp_result->add_shape (id2, *ref2); @@ -533,20 +626,21 @@ public: } private: - ShapeInteractions *mp_result; + shape_interactions *mp_result; }; -struct InteractionRegistrationShape2Inst - : db::box_scanner_receiver2 +template +struct interaction_registration_shape2inst + : db::box_scanner_receiver2 { public: - InteractionRegistrationShape2Inst (db::Layout *subject_layout, const db::Layout *intruder_layout, unsigned int intruder_layer, db::Coord dist, ShapeInteractions *result) + interaction_registration_shape2inst (db::Layout *subject_layout, const db::Layout *intruder_layout, unsigned int intruder_layer, db::Coord dist, shape_interactions *result) : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), m_intruder_layer (intruder_layer), m_dist (dist), mp_result (result) { // nothing yet .. } - void add (const db::PolygonRef *ref, unsigned int id1, const db::CellInstArray *inst, unsigned int inst_id) + void add (const T *ref, unsigned int id1, const db::CellInstArray *inst, unsigned int inst_id) { const db::Cell &intruder_cell = mp_intruder_layout->cell (inst->object ().cell_index ()); db::box_convert inst_bc (*mp_intruder_layout, m_intruder_layer); @@ -554,9 +648,10 @@ public: // Find all instance array members that potentially interact with the shape and use // add_shapes_from_intruder_inst on them - for (db::CellInstArray::iterator n = inst->begin_touching (ref->box ().enlarged (db::Vector (m_dist - 1, m_dist - 1)), inst_bc); !n.at_end (); ++n) { + db::Box ref_box = db::box_convert () (*ref); + for (db::CellInstArray::iterator n = inst->begin_touching (ref_box.enlarged (db::Vector (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.transformed (tn.inverted ()).enlarged (db::Vector (m_dist, m_dist)) & 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); } @@ -568,27 +663,27 @@ private: const db::Layout *mp_intruder_layout; unsigned int m_intruder_layer; db::Coord m_dist; - ShapeInteractions *mp_result; - std::unordered_map m_inst_shape_ids; + shape_interactions *mp_result; + std::unordered_map m_inst_shape_ids; void add_shapes_from_intruder_inst (unsigned int id1, const db::Cell &intruder_cell, const db::ICplxTrans &tn, unsigned int /*inst_id*/, const db::Box ®ion) { - db::shape_reference_translator rt (mp_subject_layout); + db::shape_reference_translator rt (mp_subject_layout); // Look up all shapes from the intruder instance which interact with the subject shape // (given through region) // TODO: should be lighter, cache, handle arrays .. db::RecursiveShapeIterator si (*mp_intruder_layout, intruder_cell, m_intruder_layer, region); - si.shape_flags (polygon_ref_flags ()); + si.shape_flags (shape_flags ()); while (! si.at_end ()) { // NOTE: we intentionally rewrite to the *subject* layout - this way polygon refs in the context come from the // subject, not from the intruder. - db::PolygonRef ref2 = rt (*si.shape ().basic_ptr (db::PolygonRef::tag ()), tn * si.trans ()); + T ref2 = rt (*si.shape ().basic_ptr (typename T::tag ()), tn * si.trans ()); // reuse the same id for shapes from the same instance -> this avoid duplicates with different IDs on // the intruder side. - std::unordered_map::const_iterator k = m_inst_shape_ids.find (ref2); + typename std::unordered_map::const_iterator k = m_inst_shape_ids.find (ref2); if (k == m_inst_shape_ids.end ()) { k = m_inst_shape_ids.insert (std::make_pair (ref2, mp_result->next_id ())).first; @@ -666,13 +761,14 @@ instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, u return false; } -struct InteractionRegistrationInst2Inst +template +struct interaction_registration_inst2inst : db::box_scanner_receiver2 { public: - typedef std::pair, std::unordered_set > interaction_value_type; + typedef std::pair, std::unordered_set > interaction_value_type; - InteractionRegistrationInst2Inst (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) + 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) { // nothing yet .. @@ -705,16 +801,17 @@ 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::unordered_set > > *mp_result; std::unordered_set > m_interactions; }; +template static bool -instance_shape_interacts (const db::Layout *layout, const db::CellInstArray *inst, unsigned int layer, const db::PolygonRef &ref, db::Coord dist) +instance_shape_interacts (const db::Layout *layout, const db::CellInstArray *inst, unsigned int layer, const T &ref, db::Coord dist) { const db::Cell &cell = layout->cell (inst->object ().cell_index ()); db::box_convert inst_bc (*layout, layer); - db::Box rbox = ref.box (); + db::Box rbox = db::box_convert () (ref); for (db::CellInstArray::iterator n = inst->begin_touching (rbox.enlarged (db::Vector (dist - 1, dist - 1)), inst_bc); ! n.at_end (); ++n) { @@ -738,17 +835,18 @@ instance_shape_interacts (const db::Layout *layout, const db::CellInstArray *ins return false; } -struct InteractionRegistrationInst2Shape - : db::box_scanner_receiver2 +template +struct interaction_registration_inst2shape + : db::box_scanner_receiver2 { public: - InteractionRegistrationInst2Shape (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::unordered_set > > *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 db::PolygonRef *ref, unsigned int) + void add (const db::CellInstArray *inst, unsigned int, const T *ref, unsigned int) { if (instance_shape_interacts (mp_subject_layout, inst, m_subject_layer, *ref, m_dist)) { (*mp_result) [inst].second.insert (*ref); @@ -759,7 +857,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::unordered_set > > *mp_result; }; } @@ -767,7 +865,8 @@ private: // --------------------------------------------------------------------------------------------- // LocalProcessorContextComputationTask implementation -LocalProcessorContextComputationTask::LocalProcessorContextComputationTask (const LocalProcessor *proc, LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, LocalProcessorCellContexts::context_key_type &intruders, db::Coord dist) +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) : 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), @@ -777,23 +876,29 @@ LocalProcessorContextComputationTask::LocalProcessorContextComputationTask (cons m_intruders.swap (intruders); } +template void -LocalProcessorContextComputationTask::perform () +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); } +template class DB_PUBLIC local_processor_context_computation_task; +template class DB_PUBLIC local_processor_context_computation_task; + // --------------------------------------------------------------------------------------------- // LocalProcessorResultComputationTask implementation -LocalProcessorResultComputationTask::LocalProcessorResultComputationTask (const LocalProcessor *proc, LocalProcessorContexts &contexts, db::Cell *cell, LocalProcessorCellContexts *cell_contexts, const LocalOperation *op, unsigned int output_layer) +template +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) { // .. nothing yet .. } +template void -LocalProcessorResultComputationTask::perform () +local_processor_result_computation_task::perform () { mp_cell_contexts->compute_results (*mp_contexts, mp_cell, mp_op, m_output_layer, mp_proc); @@ -802,13 +907,13 @@ LocalProcessorResultComputationTask::perform () tl::MutexLocker locker (& mp_contexts->lock ()); #if defined(ENABLE_DB_HP_SANITY_ASSERTIONS) - std::set td; - for (db::LocalProcessorCellContexts::iterator i = mp_cell_contexts->begin (); i != mp_cell_contexts->end (); ++i) { + std::set *> td; + for (typename db::local_processor_cell_contexts::iterator i = mp_cell_contexts->begin (); i != mp_cell_contexts->end (); ++i) { td.insert (&i->second); } - for (db::LocalProcessorContexts::contexts_per_cell_type::iterator pcc = mp_contexts->context_map ().begin (); pcc != mp_contexts->context_map ().end (); ++pcc) { - for (db::LocalProcessorCellContexts::iterator i = pcc->second.begin (); i != pcc->second.end (); ++i) { - for (db::LocalProcessorCellContext::drop_iterator j = i->second.begin_drops (); j != i->second.end_drops (); ++j) { + for (typename db::local_processor_cell_contexts::contexts_per_cell_type::iterator pcc = mp_contexts->context_map ().begin (); pcc != mp_contexts->context_map ().end (); ++pcc) { + for (typename db::local_processor_cell_contexts::iterator i = pcc->second.begin (); i != pcc->second.end (); ++i) { + for (typename db::local_processor_cell_context::drop_iterator j = i->second.begin_drops (); j != i->second.end_drops (); ++j) { if (td.find (j->parent_context) != td.end ()) { tl_assert (false); } @@ -821,22 +926,28 @@ LocalProcessorResultComputationTask::perform () } } +template class DB_PUBLIC local_processor_result_computation_task; +template class DB_PUBLIC local_processor_result_computation_task; + // --------------------------------------------------------------------------------------------- // LocalProcessor implementation -LocalProcessor::LocalProcessor (db::Layout *layout, db::Cell *top) +template +local_processor::local_processor (db::Layout *layout, db::Cell *top) : mp_subject_layout (layout), mp_intruder_layout (layout), mp_subject_top (top), mp_intruder_top (top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30) { // .. nothing yet .. } -LocalProcessor::LocalProcessor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top) +template +local_processor::local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top) : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), mp_subject_top (subject_top), mp_intruder_top (intruder_top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30) { // .. nothing yet .. } -std::string LocalProcessor::description (const LocalOperation *op) const +template +std::string local_processor::description (const local_operation *op) const { if (op && m_description.empty ()) { return op->description (); @@ -845,16 +956,18 @@ std::string LocalProcessor::description (const LocalOperation *op) const } } -void LocalProcessor::run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer) +template +void local_processor::run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer) { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Executing ")) + description (op)); - LocalProcessorContexts contexts; + local_processor_contexts contexts; compute_contexts (contexts, op, subject_layer, intruder_layer); compute_results (contexts, op, output_layer); } -void LocalProcessor::push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set &result) const +template +void local_processor::push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set &result) const { if (! result.empty ()) { tl::MutexLocker locker (&cell->layout ()->lock ()); @@ -862,14 +975,15 @@ void LocalProcessor::push_results (db::Cell *cell, unsigned int output_layer, co } } -void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer) const +template +void local_processor::compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, unsigned int intruder_layer) const { try { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::to_string (tr ("Computing contexts for ")) + description (op)); if (m_nthreads > 0) { - mp_cc_job.reset (new tl::Job (m_nthreads)); + mp_cc_job.reset (new tl::Job > (m_nthreads)); } else { mp_cc_job.reset (0); } @@ -878,7 +992,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const L contexts.set_intruder_layer (intruder_layer); contexts.set_subject_layer (subject_layer); - LocalProcessorCellContexts::context_key_type intruders; + 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 ()); if (mp_cc_job.get ()) { @@ -892,32 +1006,34 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const L } } -void LocalProcessor::issue_compute_contexts (LocalProcessorContexts &contexts, - db::LocalProcessorCellContext *parent_context, - db::Cell *subject_parent, - db::Cell *subject_cell, - const db::ICplxTrans &subject_cell_inst, - const db::Cell *intruder_cell, - LocalProcessorCellContexts::context_key_type &intruders, - db::Coord dist) const +template +void local_processor::issue_compute_contexts (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 { bool is_small_job = subject_cell->begin ().at_end (); if (! is_small_job && mp_cc_job.get ()) { - mp_cc_job->schedule (new LocalProcessorContextComputationTask (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)); } else { compute_contexts (contexts, parent_context, subject_parent, subject_cell, subject_cell_inst, intruder_cell, intruders, dist); } } -void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, - db::LocalProcessorCellContext *parent_context, - db::Cell *subject_parent, - db::Cell *subject_cell, - const db::ICplxTrans &subject_cell_inst, - const db::Cell *intruder_cell, - const LocalProcessorCellContexts::context_key_type &intruders, - db::Coord dist) const +template +void local_processor::compute_contexts (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 { CRONOLOGY_COLLECTION_BRACKET(event_compute_contexts) @@ -929,7 +1045,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, } } - db::LocalProcessorCellContext *cell_context = 0; + db::local_processor_cell_context *cell_context = 0; // prepare a new cell context: this has to happen in a thread-safe way as we share the contexts // object between threads @@ -937,17 +1053,17 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, { tl::MutexLocker locker (& contexts.lock ()); - db::LocalProcessorCellContexts &cell_contexts = contexts.contexts_per_cell (subject_cell, intruder_cell); + db::local_processor_cell_contexts &cell_contexts = contexts.contexts_per_cell (subject_cell, intruder_cell); #if defined(ENABLE_DB_HP_SANITY_ASSERTIONS) if (subject_parent) { - db::LocalProcessorContexts::contexts_per_cell_type::iterator pcc = contexts.context_map ().find (subject_parent); + typename db::local_processor_cell_contexts::contexts_per_cell_type::iterator pcc = contexts.context_map ().find (subject_parent); if (pcc == contexts.context_map ().end ()) { tl_assert (false); } tl_assert (pcc->first == subject_parent); bool any = false; - for (db::LocalProcessorCellContexts::iterator pcci = pcc->second.begin (); pcci != pcc->second.end () && !any; ++pcci) { + for (typename db::local_processor_cell_contexts::iterator pcci = pcc->second.begin (); pcci != pcc->second.end () && !any; ++pcci) { any = (&pcci->second == parent_context); } if (!any) { @@ -984,7 +1100,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, if (! subject_cell->begin ().at_end ()) { - typedef std::pair, std::unordered_set > interaction_value_type; + typedef std::pair, std::unordered_set > interaction_value_type; std::unordered_map interactions; @@ -1000,7 +1116,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, // TODO: can we shortcut this if interactions is empty? { db::box_scanner2 scanner; - InteractionRegistrationInst2Inst 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, contexts.intruder_layer (), dist, &interactions); unsigned int id = 0; @@ -1048,8 +1164,8 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, // TODO: can we shortcut this if interactions is empty? { - db::box_scanner2 scanner; - InteractionRegistrationInst2Shape rec (mp_subject_layout, contexts.subject_layer (), dist, &interactions); + db::box_scanner2 scanner; + interaction_registration_inst2shape rec (mp_subject_layout, contexts.subject_layer (), dist, &interactions); for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) { if (! inst_bcs (i->cell_inst ()).empty ()) { @@ -1057,20 +1173,20 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, } } - for (std::set::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) { + for (typename std::set::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) { scanner.insert2 (i.operator-> (), 0); } if (intruder_shapes) { - for (db::Shapes::shape_iterator i = intruder_shapes->begin (polygon_ref_flags ()); !i.at_end (); ++i) { - scanner.insert2 (i->basic_ptr (db::PolygonRef::tag ()), 0); + for (db::Shapes::shape_iterator i = intruder_shapes->begin (shape_flags ()); !i.at_end (); ++i) { + scanner.insert2 (i->basic_ptr (typename T::tag ()), 0); } } - scanner.process (rec, dist, inst_bcs, db::box_convert ()); + scanner.process (rec, dist, inst_bcs, db::box_convert ()); } - for (std::unordered_map::const_iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (typename std::unordered_map::const_iterator i = interactions.begin (); i != interactions.end (); ++i) { db::Cell &subject_child_cell = mp_subject_layout->cell (i->first->object ().cell_index ()); @@ -1082,12 +1198,12 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, if (! nbox.empty ()) { - LocalProcessorCellContexts::context_key_type intruders_below; + typename local_processor_cell_contexts::context_key_type intruders_below; - db::shape_reference_translator_with_trans rt (mp_subject_layout, tni); + db::shape_reference_translator_with_trans rt (mp_subject_layout, tni); - for (std::unordered_set::const_iterator p = i->second.second.begin (); p != i->second.second.end (); ++p) { - if (nbox.overlaps (p->box ())) { + 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)); } } @@ -1116,8 +1232,9 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, } } +template void -LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int output_layer) const +local_processor::compute_results (local_processor_contexts &contexts, const local_operation *op, unsigned int output_layer) const { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::to_string (tr ("Computing results for ")) + description (op)); @@ -1127,7 +1244,7 @@ LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOp if (m_nthreads > 0) { - std::auto_ptr > rc_job (new tl::Job (m_nthreads)); + std::auto_ptr > > rc_job (new tl::Job > (m_nthreads)); // schedule computation jobs in "waves": we need to make sure they are executed // bottom-up. So we identify a new bunch of cells each time we pass through the cell set @@ -1153,12 +1270,12 @@ LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOp for (std::vector::const_iterator bu = cells_bu.begin (); bu != cells_bu.end (); ++bu) { - LocalProcessorContexts::iterator cpc = contexts.context_map ().find (&mp_subject_layout->cell (*bu)); + typename local_processor_contexts::iterator cpc = contexts.context_map ().find (&mp_subject_layout->cell (*bu)); if (cpc != contexts.context_map ().end ()) { if (later.find (*bu) == later.end ()) { - rc_job->schedule (new LocalProcessorResultComputationTask (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_layer)); any = true; } else { @@ -1190,7 +1307,7 @@ LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOp for (db::Layout::bottom_up_const_iterator bu = mp_subject_layout->begin_bottom_up (); bu != mp_subject_layout->end_bottom_up (); ++bu) { - LocalProcessorContexts::iterator cpc = contexts.context_map ().find (&mp_subject_layout->cell (*bu)); + typename 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); contexts.context_map ().erase (cpc); @@ -1201,8 +1318,9 @@ LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOp } } +template void -LocalProcessor::compute_local_cell (const db::LocalProcessorContexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const LocalOperation *op, const LocalProcessorCellContexts::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::unordered_set &result) const { const db::Shapes *subject_shapes = &subject_cell->shapes (contexts.subject_layer ()); @@ -1216,21 +1334,21 @@ LocalProcessor::compute_local_cell (const db::LocalProcessorContexts &contexts, // local shapes vs. child cell - ShapeInteractions interactions; - db::box_convert inst_bci (*mp_intruder_layout, contexts.intruder_layer ()); + 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 (polygon_ref_flags ()); !i.at_end (); ++i) { + for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags ()); !i.at_end (); ++i) { unsigned int id = interactions.next_id (); if (subject_id0 == 0) { subject_id0 = id; } - if (op->on_empty_intruder_hint () != LocalOperation::Drop) { - const db::PolygonRef *ref = i->basic_ptr (db::PolygonRef::tag ()); + if (op->on_empty_intruder_hint () != local_operation::Drop) { + const T *ref = i->basic_ptr (typename T::tag ()); interactions.add_subject (id, *ref); } @@ -1240,46 +1358,46 @@ LocalProcessor::compute_local_cell (const db::LocalProcessorContexts &contexts, if (subject_cell == intruder_cell && contexts.subject_layer () == contexts.intruder_layer ()) { - db::box_scanner scanner; - InteractionRegistrationShape1 rec (&interactions); + db::box_scanner scanner; + interaction_registration_shape1 rec (&interactions); unsigned int id = subject_id0; - for (db::Shapes::shape_iterator i = subject_shapes->begin (polygon_ref_flags ()); !i.at_end (); ++i) { - const db::PolygonRef *ref = i->basic_ptr (db::PolygonRef::tag ()); + for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags ()); !i.at_end (); ++i) { + const T *ref = i->basic_ptr (typename T::tag ()); scanner.insert (ref, id++); } // TODO: TODO: can we confine this search to the subject's (sized) bounding box? - for (std::set::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) { + for (typename std::set::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) { scanner.insert (i.operator-> (), interactions.next_id ()); } - scanner.process (rec, op->dist (), db::box_convert ()); + scanner.process (rec, op->dist (), db::box_convert ()); } else { - db::box_scanner2 scanner; - InteractionRegistrationShape2Shape rec (mp_subject_layout == mp_intruder_layout ? 0 : mp_subject_layout, &interactions); + db::box_scanner2 scanner; + interaction_registration_shape2shape rec (mp_subject_layout == mp_intruder_layout ? 0 : mp_subject_layout, &interactions); unsigned int id = subject_id0; - for (db::Shapes::shape_iterator i = subject_shapes->begin (polygon_ref_flags ()); !i.at_end (); ++i) { - const db::PolygonRef *ref = i->basic_ptr (db::PolygonRef::tag ()); + for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags ()); !i.at_end (); ++i) { + const T *ref = i->basic_ptr (typename T::tag ()); scanner.insert1 (ref, id++); } // TODO: can we confine this search to the subject's (sized) bounding box? - for (std::set::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) { + for (typename std::set::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) { scanner.insert2 (i.operator-> (), interactions.next_id ()); } if (intruder_shapes) { // TODO: can we confine this search to the subject's (sized) bounding box? - for (db::Shapes::shape_iterator i = intruder_shapes->begin (polygon_ref_flags ()); !i.at_end (); ++i) { - scanner.insert2 (i->basic_ptr (db::PolygonRef::tag ()), interactions.next_id ()); + for (db::Shapes::shape_iterator i = intruder_shapes->begin (shape_flags ()); !i.at_end (); ++i) { + scanner.insert2 (i->basic_ptr (typename T::tag ()), interactions.next_id ()); } } - scanner.process (rec, op->dist (), db::box_convert (), db::box_convert ()); + scanner.process (rec, op->dist (), db::box_convert (), db::box_convert ()); } @@ -1287,12 +1405,12 @@ LocalProcessor::compute_local_cell (const db::LocalProcessorContexts &contexts, if (! subject_shapes->empty () && ! ((! intruder_cell || intruder_cell->begin ().at_end ()) && intruders.first.empty ())) { - db::box_scanner2 scanner; - InteractionRegistrationShape2Inst rec (mp_subject_layout, mp_intruder_layout, contexts.intruder_layer (), op->dist (), &interactions); + 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; - for (db::Shapes::shape_iterator i = subject_shapes->begin (polygon_ref_flags ()); !i.at_end (); ++i) { - scanner.insert1 (i->basic_ptr (db::PolygonRef::tag ()), id++); + for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags ()); !i.at_end (); ++i) { + scanner.insert1 (i->basic_ptr (typename T::tag ()), id++); } unsigned int inst_id = 0; @@ -1319,12 +1437,15 @@ LocalProcessor::compute_local_cell (const db::LocalProcessorContexts &contexts, } } - scanner.process (rec, op->dist (), db::box_convert (), inst_bci); + scanner.process (rec, op->dist (), db::box_convert (), inst_bci); } op->compute_local (mp_subject_layout, interactions, result, m_max_vertex_count, m_area_ratio); } +template class DB_PUBLIC local_processor; +template class DB_PUBLIC local_processor; + } diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 720897bd2..a823705b4 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -42,19 +42,20 @@ namespace db { -class LocalProcessor; -class LocalProcessorCellContext; -class LocalProcessorContexts; +template class local_processor; +template class local_processor_cell_context; +template class local_processor_contexts; // TODO: move this somewhere else? -class DB_PUBLIC ShapeInteractions +template +class DB_PUBLIC shape_interactions { public: typedef std::unordered_map > container; typedef container::const_iterator iterator; typedef container::value_type::second_type::const_iterator iterator2; - ShapeInteractions (); + shape_interactions (); iterator begin () const { @@ -67,11 +68,11 @@ public: } bool has_shape_id (unsigned int id) const; - void add_shape (unsigned int id, const db::PolygonRef &shape); - void add_subject (unsigned int id, const db::PolygonRef &shape); + void add_shape (unsigned int id, const T &shape); + void add_subject (unsigned int id, const T &shape); void add_interaction (unsigned int subject_id, unsigned int intruder_id); const std::vector &intruders_for (unsigned int subject_id) const; - const db::PolygonRef &shape (unsigned int id) const; + const T &shape (unsigned int id) const; unsigned int next_id () { @@ -80,43 +81,45 @@ public: private: std::unordered_map > m_interactions; - std::unordered_map m_shapes; + std::unordered_map m_shapes; unsigned int m_id; }; // TODO: should be hidden (private data?) -struct DB_PUBLIC LocalProcessorCellDrop +template +struct DB_PUBLIC local_processor_cell_drop { - LocalProcessorCellDrop (db::LocalProcessorCellContext *_parent_context, db::Cell *_parent, const db::ICplxTrans &_cell_inst) + local_processor_cell_drop (db::local_processor_cell_context *_parent_context, db::Cell *_parent, const db::ICplxTrans &_cell_inst) : parent_context (_parent_context), parent (_parent), cell_inst (_cell_inst) { // .. nothing yet .. } - db::LocalProcessorCellContext *parent_context; + db::local_processor_cell_context *parent_context; db::Cell *parent; db::ICplxTrans cell_inst; }; // TODO: should be hidden (private data?) -class DB_PUBLIC LocalProcessorCellContext +template +class DB_PUBLIC local_processor_cell_context { public: typedef std::pair parent_inst_type; - typedef std::vector::const_iterator drop_iterator; + typedef typename std::vector >::const_iterator drop_iterator; - LocalProcessorCellContext (); - LocalProcessorCellContext (const LocalProcessorCellContext &other); + local_processor_cell_context (); + local_processor_cell_context (const local_processor_cell_context &other); - void add (db::LocalProcessorCellContext *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst); - void propagate (const std::unordered_set &res); + void add (db::local_processor_cell_context *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst); + void propagate (const std::unordered_set &res); - std::unordered_set &propagated () + std::unordered_set &propagated () { return m_propagated; } - const std::unordered_set &propagated () const + const std::unordered_set &propagated () const { return m_propagated; } @@ -144,24 +147,25 @@ public: } private: - std::unordered_set m_propagated; - std::vector m_drops; + std::unordered_set m_propagated; + std::vector > m_drops; tl::Mutex m_lock; }; -class DB_PUBLIC LocalProcessorCellContexts +template +class DB_PUBLIC local_processor_cell_contexts { public: - typedef std::pair, std::set > context_key_type; - typedef std::unordered_map context_map_type; - typedef context_map_type::const_iterator iterator; + typedef std::pair, std::set > context_key_type; + typedef std::unordered_map > context_map_type; + typedef typename context_map_type::const_iterator iterator; - LocalProcessorCellContexts (); - LocalProcessorCellContexts (const db::Cell *intruder_cell); + local_processor_cell_contexts (); + local_processor_cell_contexts (const db::Cell *intruder_cell); - db::LocalProcessorCellContext *find_context (const context_key_type &intruders); - db::LocalProcessorCellContext *create (const context_key_type &intruders); - void compute_results (const LocalProcessorContexts &contexts, db::Cell *cell, const LocalOperation *op, unsigned int output_layer, const LocalProcessor *proc); + 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); iterator begin () const { @@ -175,22 +179,23 @@ public: private: const db::Cell *mp_intruder_cell; - std::unordered_map m_contexts; + std::unordered_map > m_contexts; }; -class DB_PUBLIC LocalProcessorContexts +template +class DB_PUBLIC local_processor_contexts { public: - typedef std::unordered_map contexts_per_cell_type; - typedef contexts_per_cell_type::iterator iterator; + typedef std::unordered_map > contexts_per_cell_type; + typedef typename contexts_per_cell_type::iterator iterator; - LocalProcessorContexts () + local_processor_contexts () : m_subject_layer (0), m_intruder_layer (0) { // .. nothing yet .. } - LocalProcessorContexts (const LocalProcessorContexts &other) + 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) { // .. nothing yet .. @@ -201,11 +206,11 @@ public: m_contexts_per_cell.clear (); } - LocalProcessorCellContexts &contexts_per_cell (db::Cell *subject_cell, const db::Cell *intruder_cell) + local_processor_cell_contexts &contexts_per_cell (db::Cell *subject_cell, const db::Cell *intruder_cell) { - contexts_per_cell_type::iterator ctx = m_contexts_per_cell.find (subject_cell); + typename contexts_per_cell_type::iterator ctx = m_contexts_per_cell.find (subject_cell); if (ctx == m_contexts_per_cell.end ()) { - ctx = m_contexts_per_cell.insert (std::make_pair (subject_cell, LocalProcessorCellContexts (intruder_cell))).first; + ctx = m_contexts_per_cell.insert (std::make_pair (subject_cell, local_processor_cell_contexts (intruder_cell))).first; } return ctx->second; } @@ -256,30 +261,32 @@ private: mutable tl::Mutex m_lock; }; -class DB_PUBLIC LocalProcessorContextComputationTask +template +class DB_PUBLIC local_processor_context_computation_task : public tl::Task { public: - LocalProcessorContextComputationTask (const LocalProcessor *proc, LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, LocalProcessorCellContexts::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); void perform (); private: - const LocalProcessor *mp_proc; - LocalProcessorContexts *mp_contexts; - db::LocalProcessorCellContext *mp_parent_context; + const local_processor *mp_proc; + local_processor_contexts *mp_contexts; + db::local_processor_cell_context *mp_parent_context; db::Cell *mp_subject_parent; db::Cell *mp_subject_cell; db::ICplxTrans m_subject_cell_inst; const db::Cell *mp_intruder_cell; - LocalProcessorCellContexts::context_key_type m_intruders; + typename local_processor_cell_contexts::context_key_type m_intruders; db::Coord m_dist; }; -class DB_PUBLIC LocalProcessorContextComputationWorker +template +class DB_PUBLIC local_processor_context_computation_worker : public tl::Worker { public: - LocalProcessorContextComputationWorker () + local_processor_context_computation_worker () : tl::Worker () { // .. nothing yet .. @@ -287,31 +294,33 @@ public: void perform_task (tl::Task *task) { - static_cast (task)->perform (); + static_cast *> (task)->perform (); } }; -class DB_PUBLIC LocalProcessorResultComputationTask +template +class DB_PUBLIC local_processor_result_computation_task : public tl::Task { public: - LocalProcessorResultComputationTask (const LocalProcessor *proc, LocalProcessorContexts &contexts, db::Cell *cell, LocalProcessorCellContexts *cell_contexts, const LocalOperation *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, unsigned int output_layer); void perform (); private: - const LocalProcessor *mp_proc; - LocalProcessorContexts *mp_contexts; + const local_processor *mp_proc; + local_processor_contexts *mp_contexts; db::Cell *mp_cell; - LocalProcessorCellContexts *mp_cell_contexts; - const LocalOperation *mp_op; + local_processor_cell_contexts *mp_cell_contexts; + const local_operation *mp_op; unsigned int m_output_layer; }; -class DB_PUBLIC LocalProcessorResultComputationWorker +template +class DB_PUBLIC local_processor_result_computation_worker : public tl::Worker { public: - LocalProcessorResultComputationWorker () + local_processor_result_computation_worker () : tl::Worker () { // .. nothing yet .. @@ -319,18 +328,19 @@ public: void perform_task (tl::Task *task) { - static_cast (task)->perform (); + static_cast *> (task)->perform (); } }; -class DB_PUBLIC LocalProcessor +template +class DB_PUBLIC local_processor { public: - LocalProcessor (db::Layout *layout, db::Cell *top); - LocalProcessor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell); - void run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer); - void compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer) const; - void compute_results (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int output_layer) const; + local_processor (db::Layout *layout, db::Cell *top); + local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell); + 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 set_description (const std::string &d) { @@ -378,8 +388,8 @@ public: } private: - friend class LocalProcessorCellContexts; - friend class LocalProcessorContextComputationTask; + template friend class local_processor_cell_contexts; + template friend class local_processor_context_computation_task; db::Layout *mp_subject_layout; const db::Layout *mp_intruder_layout; @@ -390,14 +400,14 @@ private: size_t m_max_vertex_count; double m_area_ratio; int m_base_verbosity; - mutable std::auto_ptr > mp_cc_job; + mutable std::auto_ptr > > mp_cc_job; - std::string description (const LocalOperation *op) const; - void compute_contexts (db::LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, const LocalProcessorCellContexts::context_key_type &intruders, db::Coord dist) const; - void do_compute_contexts (db::LocalProcessorCellContext *cell_context, const db::LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, const LocalProcessorCellContexts::context_key_type &intruders, db::Coord dist) const; - void issue_compute_contexts (db::LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, LocalProcessorCellContexts::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::LocalProcessorContexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const LocalOperation *op, const LocalProcessorCellContexts::context_key_type &intruders, std::unordered_set &result) const; + std::string description (const local_operation *op) 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 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; }; } @@ -405,8 +415,8 @@ private: namespace tl { -template <> -struct type_traits : public tl::type_traits +template +struct type_traits > : public tl::type_traits { // mark "LocalProcessor" as not having a default ctor and no copy ctor typedef tl::false_tag has_default_constructor; diff --git a/src/db/db/dbLocalOperation.cc b/src/db/db/dbLocalOperation.cc index 739d0fab4..3545ce3b3 100644 --- a/src/db/db/dbLocalOperation.cc +++ b/src/db/db/dbLocalOperation.cc @@ -45,10 +45,10 @@ BoolAndOrNotLocalOperation::BoolAndOrNotLocalOperation (bool is_and) // .. nothing yet .. } -LocalOperation::on_empty_intruder_mode +local_operation::on_empty_intruder_mode BoolAndOrNotLocalOperation::on_empty_intruder_hint () const { - return m_is_and ? LocalOperation::Drop : LocalOperation::Copy; + return m_is_and ? local_operation::Drop : local_operation::Copy; } std::string @@ -58,20 +58,20 @@ BoolAndOrNotLocalOperation::description () const } void -BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const ShapeInteractions &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::unordered_set &result, size_t max_vertex_count, double area_ratio) const { db::EdgeProcessor ep; size_t p1 = 0, p2 = 1; std::set others; - for (ShapeInteractions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - for (ShapeInteractions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + 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.shape (*j)); } } - for (ShapeInteractions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { const db::PolygonRef &subject = interactions.shape (i->first); if (others.find (subject) != others.end ()) { @@ -119,7 +119,7 @@ SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wra // .. nothing yet .. } -void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const ShapeInteractions &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::unordered_set &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const { if (m_wrap_count == 0) { return; @@ -130,7 +130,7 @@ void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const Sh size_t p1 = 0, p2 = 1; std::set seen; - for (ShapeInteractions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { if (seen.find (i->first) == seen.end ()) { seen.insert (i->first); @@ -141,7 +141,7 @@ void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const Sh p1 += 2; } - for (db::ShapeInteractions::iterator2 o = i->second.begin (); o != i->second.end (); ++o) { + for (db::shape_interactions::iterator2 o = i->second.begin (); o != i->second.end (); ++o) { // don't take the same (really the same, not an identical one) shape twice - the interaction // set does not take care to list just one copy of the same item on the intruder side. if (seen.find (*o) == seen.end ()) { @@ -165,7 +165,7 @@ void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const Sh SelfOverlapMergeLocalOperation::on_empty_intruder_mode SelfOverlapMergeLocalOperation::on_empty_intruder_hint () const { - return m_wrap_count > 1 ? LocalOperation::Drop : LocalOperation::Copy; + return m_wrap_count > 1 ? local_operation::Drop : local_operation::Copy; } std::string SelfOverlapMergeLocalOperation::description () const diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index 0ce915e83..b0bba3458 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -36,7 +36,7 @@ namespace db { -class ShapeInteractions; +template class shape_interactions; /** * @brief A base class for "local operations" @@ -49,7 +49,8 @@ class ShapeInteractions; * This class implements the actual operation. It receives a * cluster of subject shapes vs. corresponding intruder shapes. */ -class DB_PUBLIC LocalOperation +template +class DB_PUBLIC local_operation { public: /** @@ -75,12 +76,12 @@ public: /** * @brief Constructor */ - LocalOperation () { } + local_operation () { } /** * @brief Destructor */ - virtual ~LocalOperation () { } + virtual ~local_operation () { } /** * @brief Computes the results from a given set of interacting shapes @@ -88,7 +89,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 ShapeInteractions &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::unordered_set &result, size_t max_vertex_count, double area_ratio) const = 0; /** * @brief Indicates the desired behaviour when a shape does not have an intruder @@ -111,12 +112,12 @@ public: * @brief Implements a boolean AND or NOT operation */ class DB_PUBLIC BoolAndOrNotLocalOperation - : public LocalOperation + : public local_operation { public: BoolAndOrNotLocalOperation (bool is_and); - virtual void compute_local (db::Layout *layout, const ShapeInteractions &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::unordered_set &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; @@ -130,12 +131,12 @@ private: * the original shapes overlap at least "wrap_count" times. */ class DB_PUBLIC SelfOverlapMergeLocalOperation - : public LocalOperation + : public local_operation { public: SelfOverlapMergeLocalOperation (unsigned int wrap_count); - virtual void compute_local (db::Layout *layout, const ShapeInteractions &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::unordered_set &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 060611d8c..5369eb73a 100644 --- a/src/db/unit_tests/dbHierProcessorTests.cc +++ b/src/db/unit_tests/dbHierProcessorTests.cc @@ -55,11 +55,11 @@ public: // .. nothing yet .. } - virtual void compute_local (db::Layout *layout, const db::ShapeInteractions &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::unordered_set &result, size_t max_vertex_count, double area_ratio) const { - db::ShapeInteractions sized_interactions = interactions; - for (db::ShapeInteractions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { - for (db::ShapeInteractions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + 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.shape (*j); db::Polygon poly = ref.obj ().transformed (ref.trans ()); poly.size (m_dist, m_dist); @@ -91,17 +91,17 @@ public: // .. nothing yet .. } - virtual void compute_local (db::Layout *layout, const db::ShapeInteractions &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::unordered_set &result, size_t max_vertex_count, double area_ratio) const { - db::ShapeInteractions sized_interactions = interactions; - for (db::ShapeInteractions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { + 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.shape (i->first); db::Polygon poly = ref.obj ().transformed (ref.trans ()); poly.size (m_dist / 2, m_dist / 2); sized_interactions.add_shape (i->first, db::PolygonRef (poly, layout->shape_repository ())); - for (db::ShapeInteractions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + for (db::shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { const db::PolygonRef &ref = interactions.shape (*j); db::Polygon poly = ref.obj ().transformed (ref.trans ()); poly.size (m_dist / 2, m_dist / 2); @@ -140,15 +140,15 @@ static void normalize_layer (db::Layout &layout, unsigned int layer) } -static std::string contexts_to_s (db::Layout *layout, db::LocalProcessorContexts &contexts) +static std::string contexts_to_s (db::Layout *layout, db::local_processor_contexts &contexts) { std::string res; for (db::Layout::top_down_const_iterator i = layout->begin_top_down (); i != layout->end_top_down(); ++i) { - db::LocalProcessorContexts::iterator cc = contexts.context_map ().find (&layout->cell (*i)); + db::local_processor_contexts::iterator cc = contexts.context_map ().find (&layout->cell (*i)); if (cc != contexts.context_map ().end ()) { int index = 1; - for (db::LocalProcessorCellContexts::iterator j = cc->second.begin (); j != cc->second.end (); ++j) { + 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 ())); index += 1; } @@ -203,7 +203,7 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m normalize_layer (layout_org, l2); } - db::LocalOperation *lop = 0; + db::local_operation *lop = 0; db::BoolAndOrNotLocalOperation bool_op (mode == TMAnd || mode == TMAndSwapped); db::SelfOverlapMergeLocalOperation self_intersect_op (2); BoolAndOrNotWithSizedLocalOperation sized_bool_op (mode == TMAnd || mode == TMAndSwapped, dist); @@ -224,7 +224,7 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m if (single) { - db::LocalProcessor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ())); + db::local_processor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ())); proc.set_threads (nthreads); proc.set_area_ratio (3.0); proc.set_max_vertex_count (16); @@ -232,7 +232,7 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m if (! context_doc) { proc.run (lop, l1, l2, lout); } else { - db::LocalProcessorContexts contexts; + db::local_processor_contexts contexts; proc.compute_contexts (contexts, lop, l1, l2); *context_doc = contexts_to_s (&layout_org, contexts); proc.compute_results (contexts, lop, lout); @@ -242,7 +242,7 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m db::Layout layout_org2 = layout_org; - db::LocalProcessor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ()), &layout_org2, &layout_org2.cell (*layout_org2.begin_top_down ())); + db::local_processor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ()), &layout_org2, &layout_org2.cell (*layout_org2.begin_top_down ())); proc.set_threads (nthreads); proc.set_area_ratio (3.0); proc.set_max_vertex_count (16); @@ -250,7 +250,7 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m if (! context_doc) { proc.run (lop, l1, l2, lout); } else { - db::LocalProcessorContexts contexts; + db::local_processor_contexts contexts; proc.compute_contexts (contexts, lop, l1, l2); *context_doc = contexts_to_s (&layout_org, contexts); proc.compute_results (contexts, lop, lout);