mirror of https://github.com/KLayout/klayout.git
WIP: some performance improvements, cronology debugging support (experimental)
This commit is contained in:
parent
62224b0d91
commit
17f53cf54e
|
|
@ -97,6 +97,12 @@ equals(HAVE_RUBY, "1") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
equals(HAVE_CRONOLOGY, "1") {
|
||||||
|
DEFINES += HAVE_CRONOLOGY
|
||||||
|
LIBS += $$CRONOLOGY_LIB
|
||||||
|
INCLUDEPATH += $$CRONOLOGY_INCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
msvc {
|
msvc {
|
||||||
|
|
||||||
QMAKE_CXXFLAGS += \
|
QMAKE_CXXFLAGS += \
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,33 @@
|
||||||
#include "tlTimer.h"
|
#include "tlTimer.h"
|
||||||
#include "tlInternational.h"
|
#include "tlInternational.h"
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
// Cronology debugging support (TODO: experimental)
|
||||||
|
|
||||||
|
#if defined(HAVE_CRONOLOGY)
|
||||||
|
|
||||||
|
#include <cronology/events.hpp>
|
||||||
|
|
||||||
|
CRONOLOGY_MAKE_EVENT(event_compute_contexts, "Compute contexts")
|
||||||
|
CRONOLOGY_MAKE_EVENT(event_compute_contexts_unlocked, "Compute contexts (unlocked)")
|
||||||
|
|
||||||
|
cronology::events::event_collection<event_compute_contexts, event_compute_contexts_unlocked> collect_events;
|
||||||
|
|
||||||
|
#define CRONOLOGY_COLLECTION_BRACKET(event_name) cronology::EventBracket __bracket##event_name (collect_events.threadwise ()->event<event_name> ().event ());
|
||||||
|
|
||||||
|
CRONOLOGY_MAKE_EVENT(event_compute_results, "Compute results")
|
||||||
|
CRONOLOGY_MAKE_EVENT(event_compute_local_cell, "Compute local cell results")
|
||||||
|
CRONOLOGY_MAKE_EVENT(event_propagate, "Propagate local cell results")
|
||||||
|
|
||||||
|
cronology::events::event_collection<event_compute_results, event_compute_local_cell, event_propagate> compute_events;
|
||||||
|
|
||||||
|
#define CRONOLOGY_COMPUTE_BRACKET(event_name) cronology::EventBracket __bracket##event_name (compute_events.threadwise ()->event<event_name> ().event ());
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define CRONOLOGY_COLLECTION_BRACKET(event_name)
|
||||||
|
#define CRONOLOGY_COMPUTE_BRACKET(event_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -42,6 +69,7 @@ class shape_reference_translator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename Ref::shape_type shape_type;
|
typedef typename Ref::shape_type shape_type;
|
||||||
|
typedef typename Ref::trans_type ref_trans_type;
|
||||||
|
|
||||||
shape_reference_translator (db::Layout *target_layout)
|
shape_reference_translator (db::Layout *target_layout)
|
||||||
: mp_layout (target_layout)
|
: mp_layout (target_layout)
|
||||||
|
|
@ -51,21 +79,102 @@ public:
|
||||||
|
|
||||||
Ref operator() (const Ref &ref) const
|
Ref operator() (const Ref &ref) const
|
||||||
{
|
{
|
||||||
tl::MutexLocker locker (&mp_layout->lock ());
|
typename std::unordered_map<const shape_type *, const shape_type *>::const_iterator m = m_cache.find (ref.ptr ());
|
||||||
shape_type sh = ref.obj ().transformed (ref.trans ());
|
if (m != m_cache.end ()) {
|
||||||
return Ref (sh, mp_layout->shape_repository ());
|
|
||||||
|
return Ref (m->second, ref.trans ());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const shape_type *ptr;
|
||||||
|
{
|
||||||
|
tl::MutexLocker locker (&mp_layout->lock ());
|
||||||
|
ptr = mp_layout->shape_repository ().repository (typename shape_type::tag ()).insert (ref.obj ());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cache[ref.ptr ()] = ptr;
|
||||||
|
return Ref (ptr, ref.trans ());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Trans>
|
template <class Trans>
|
||||||
Ref operator() (const Ref &ref, const Trans &tr) const
|
Ref operator() (const Ref &ref, const Trans &tr) const
|
||||||
{
|
{
|
||||||
tl::MutexLocker locker (&mp_layout->lock ());
|
shape_type sh = ref.obj ().transformed (Trans (ref_trans_type (tr).inverted ()) * tr);
|
||||||
shape_type sh = ref.obj ().transformed (tr * Trans (ref.trans ()));
|
ref_trans_type red_trans;
|
||||||
return Ref (sh, mp_layout->shape_repository ());
|
sh.reduce (red_trans);
|
||||||
|
|
||||||
|
typename std::unordered_map<shape_type, std::pair<const shape_type *, ref_trans_type> >::const_iterator m = m_cache_by_shape.find (sh);
|
||||||
|
if (m != m_cache_by_shape.end ()) {
|
||||||
|
|
||||||
|
return Ref (m->second.first, ref_trans_type (tr * Trans (ref.trans ())) * m->second.second);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const shape_type *ptr;
|
||||||
|
{
|
||||||
|
tl::MutexLocker locker (&mp_layout->lock ());
|
||||||
|
ptr = mp_layout->shape_repository ().repository (typename shape_type::tag ()).insert (sh);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cache_by_shape[sh] = std::make_pair (ptr, red_trans);
|
||||||
|
return Ref (ptr, ref_trans_type (tr * Trans (ref.trans ())) * red_trans);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
db::Layout *mp_layout;
|
db::Layout *mp_layout;
|
||||||
|
mutable std::unordered_map<const shape_type *, const shape_type *> m_cache;
|
||||||
|
mutable std::unordered_map<shape_type, std::pair<const shape_type *, ref_trans_type> > m_cache_by_shape;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Ref, class Trans>
|
||||||
|
class shape_reference_translator_with_trans
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Ref::shape_type shape_type;
|
||||||
|
typedef typename Ref::trans_type ref_trans_type;
|
||||||
|
|
||||||
|
shape_reference_translator_with_trans (db::Layout *target_layout, const Trans &trans)
|
||||||
|
: mp_layout (target_layout), m_trans (trans), m_ref_trans (trans), m_bare_trans (Trans (m_ref_trans.inverted ()) * trans)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref operator() (const Ref &ref) const
|
||||||
|
{
|
||||||
|
typename std::unordered_map<const shape_type *, std::pair<const shape_type *, ref_trans_type> >::const_iterator m = m_cache.find (ref.ptr ());
|
||||||
|
if (m != m_cache.end ()) {
|
||||||
|
|
||||||
|
return Ref (m->second.first, ref_trans_type (m_trans * Trans (ref.trans ())) * m->second.second);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
shape_type sh = ref.obj ().transformed (m_bare_trans);
|
||||||
|
ref_trans_type red_trans;
|
||||||
|
sh.reduce (red_trans);
|
||||||
|
|
||||||
|
const shape_type *ptr;
|
||||||
|
{
|
||||||
|
tl::MutexLocker locker (&mp_layout->lock ());
|
||||||
|
ptr = mp_layout->shape_repository ().repository (typename shape_type::tag ()).insert (sh);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cache[ref.ptr ()] = std::make_pair (ptr, red_trans);
|
||||||
|
|
||||||
|
return Ref (ptr, ref_trans_type (m_trans * Trans (ref.trans ())) * red_trans);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
db::Layout *mp_layout;
|
||||||
|
Trans m_trans;
|
||||||
|
ref_trans_type m_ref_trans;
|
||||||
|
Trans m_bare_trans;
|
||||||
|
mutable std::unordered_map<const shape_type *, std::pair<const shape_type *, ref_trans_type> > m_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
|
@ -83,7 +192,7 @@ LocalProcessorCellContext::add (db::LocalProcessorCellContext *parent_context, d
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LocalProcessorCellContext::propagate (const std::set<db::PolygonRef> &res)
|
LocalProcessorCellContext::propagate (const std::unordered_set<db::PolygonRef> &res)
|
||||||
{
|
{
|
||||||
if (res.empty ()) {
|
if (res.empty ()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -95,13 +204,19 @@ LocalProcessorCellContext::propagate (const std::set<db::PolygonRef> &res)
|
||||||
tl_assert (d->parent != 0);
|
tl_assert (d->parent != 0);
|
||||||
|
|
||||||
db::Layout *subject_layout = d->parent->layout ();
|
db::Layout *subject_layout = d->parent->layout ();
|
||||||
shape_reference_translator<db::PolygonRef> rt (subject_layout);
|
shape_reference_translator_with_trans<db::PolygonRef, db::ICplxTrans> rt (subject_layout, d->cell_inst);
|
||||||
for (std::set<db::PolygonRef>::const_iterator r = res.begin (); r != res.end (); ++r) {
|
std::vector<db::PolygonRef> new_refs;
|
||||||
d->parent_context->propagated ().insert (rt (*r, d->cell_inst));
|
new_refs.reserve (res.size ());
|
||||||
|
for (std::unordered_set<db::PolygonRef>::const_iterator r = res.begin (); r != res.end (); ++r) {
|
||||||
|
new_refs.push_back (rt (*r));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::MutexLocker locker (&d->parent_context->lock ());
|
||||||
|
d->parent_context->propagated ().insert (new_refs.begin (), new_refs.end ());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
|
@ -122,7 +237,7 @@ LocalProcessorCellContexts::LocalProcessorCellContexts (const db::Cell *intruder
|
||||||
db::LocalProcessorCellContext *
|
db::LocalProcessorCellContext *
|
||||||
LocalProcessorCellContexts::find_context (const key_type &intruders)
|
LocalProcessorCellContexts::find_context (const key_type &intruders)
|
||||||
{
|
{
|
||||||
std::map<key_type, db::LocalProcessorCellContext>::iterator c = m_contexts.find (intruders);
|
std::unordered_map<key_type, db::LocalProcessorCellContext>::iterator c = m_contexts.find (intruders);
|
||||||
return c != m_contexts.end () ? &c->second : 0;
|
return c != m_contexts.end () ? &c->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,12 +250,14 @@ LocalProcessorCellContexts::create (const key_type &intruders)
|
||||||
void
|
void
|
||||||
LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &contexts, db::Cell *cell, const LocalOperation *op, unsigned int output_layer, const LocalProcessor *proc)
|
LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &contexts, db::Cell *cell, const LocalOperation *op, unsigned int output_layer, const LocalProcessor *proc)
|
||||||
{
|
{
|
||||||
|
CRONOLOGY_COMPUTE_BRACKET(event_compute_results)
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
std::set<db::PolygonRef> common;
|
std::unordered_set<db::PolygonRef> common;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int total = int (m_contexts.size ());
|
int total = int (m_contexts.size ());
|
||||||
for (std::map<key_type, db::LocalProcessorCellContext>::iterator c = m_contexts.begin (); c != m_contexts.end (); ++c) {
|
for (std::unordered_map<key_type, db::LocalProcessorCellContext>::iterator c = m_contexts.begin (); c != m_contexts.end (); ++c) {
|
||||||
|
|
||||||
++index;
|
++index;
|
||||||
|
|
||||||
|
|
@ -151,54 +268,68 @@ LocalProcessorCellContexts::compute_results (const LocalProcessorContexts &conte
|
||||||
if (first) {
|
if (first) {
|
||||||
|
|
||||||
{
|
{
|
||||||
tl::MutexLocker locker (&contexts.lock ());
|
tl::MutexLocker locker (&c->second.lock ());
|
||||||
common = c->second.propagated ();
|
common = c->second.propagated ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRONOLOGY_COMPUTE_BRACKET(event_compute_local_cell)
|
||||||
proc->compute_local_cell (contexts, cell, mp_intruder_cell, op, c->first, common);
|
proc->compute_local_cell (contexts, cell, mp_intruder_cell, op, c->first, common);
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
std::set<db::PolygonRef> res;
|
std::unordered_set<db::PolygonRef> res;
|
||||||
{
|
{
|
||||||
tl::MutexLocker locker (&contexts.lock ());
|
tl::MutexLocker locker (&c->second.lock ());
|
||||||
res = c->second.propagated ();
|
res = c->second.propagated ();
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->compute_local_cell (contexts, cell, mp_intruder_cell, op, c->first, res);
|
{
|
||||||
|
CRONOLOGY_COMPUTE_BRACKET(event_compute_local_cell)
|
||||||
|
proc->compute_local_cell (contexts, cell, mp_intruder_cell, op, c->first, res);
|
||||||
|
}
|
||||||
|
|
||||||
if (common.empty ()) {
|
if (common.empty ()) {
|
||||||
|
|
||||||
tl::MutexLocker locker (&contexts.lock ());
|
CRONOLOGY_COMPUTE_BRACKET(event_propagate)
|
||||||
c->second.propagate (res);
|
c->second.propagate (res);
|
||||||
|
|
||||||
} else if (res != common) {
|
} else if (res != common) {
|
||||||
|
|
||||||
std::set<db::PolygonRef> lost;
|
CRONOLOGY_COMPUTE_BRACKET(event_propagate)
|
||||||
std::set_difference (common.begin (), common.end (), res.begin (), res.end (), std::inserter (lost, lost.end ()));
|
|
||||||
|
std::unordered_set<db::PolygonRef> lost;
|
||||||
|
for (std::unordered_set<db::PolygonRef>::const_iterator i = common.begin (); i != common.end (); ++i) {
|
||||||
|
if (res.find (*i) == res.end ()) {
|
||||||
|
lost.insert (*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (! lost.empty ()) {
|
if (! lost.empty ()) {
|
||||||
|
|
||||||
std::set<db::PolygonRef> new_common;
|
std::unordered_set<db::PolygonRef> new_common;
|
||||||
std::set_intersection (common.begin (), common.end (), res.begin (), res.end (), std::inserter (new_common, new_common.end ()));
|
for (std::unordered_set<db::PolygonRef>::const_iterator i = common.begin (); i != common.end (); ++i) {
|
||||||
|
if (res.find (*i) != res.end ()) {
|
||||||
|
new_common.insert (*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
common.swap (new_common);
|
common.swap (new_common);
|
||||||
|
|
||||||
for (std::map<key_type, db::LocalProcessorCellContext>::iterator cc = m_contexts.begin (); cc != c; ++cc) {
|
for (std::unordered_map<key_type, db::LocalProcessorCellContext>::iterator cc = m_contexts.begin (); cc != c; ++cc) {
|
||||||
tl::MutexLocker locker (&contexts.lock ());
|
|
||||||
cc->second.propagate (lost);
|
cc->second.propagate (lost);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<db::PolygonRef> gained;
|
std::unordered_set<db::PolygonRef> gained;
|
||||||
std::set_difference (res.begin (), res.end (), common.begin (), common.end (), std::inserter (gained, gained.end ()));
|
for (std::unordered_set<db::PolygonRef>::const_iterator i = res.begin (); i != res.end (); ++i) {
|
||||||
|
if (common.find (*i) == common.end ()) {
|
||||||
{
|
gained.insert (*i);
|
||||||
tl::MutexLocker locker (&contexts.lock ());
|
}
|
||||||
c->second.propagate (gained);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c->second.propagate (gained);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +387,7 @@ ShapeInteractions::intruders_for (unsigned int subject_id) const
|
||||||
const db::PolygonRef &
|
const db::PolygonRef &
|
||||||
ShapeInteractions::shape (unsigned int id) const
|
ShapeInteractions::shape (unsigned int id) const
|
||||||
{
|
{
|
||||||
std::map<unsigned int, db::PolygonRef>::const_iterator i = m_shapes.find (id);
|
std::unordered_map<unsigned int, db::PolygonRef>::const_iterator i = m_shapes.find (id);
|
||||||
if (i == m_shapes.end ()) {
|
if (i == m_shapes.end ()) {
|
||||||
static db::PolygonRef s;
|
static db::PolygonRef s;
|
||||||
return s;
|
return s;
|
||||||
|
|
@ -363,7 +494,7 @@ private:
|
||||||
unsigned int m_intruder_layer;
|
unsigned int m_intruder_layer;
|
||||||
db::Coord m_dist;
|
db::Coord m_dist;
|
||||||
ShapeInteractions *mp_result;
|
ShapeInteractions *mp_result;
|
||||||
std::map<std::pair<unsigned int, const db::PolygonRef *>, unsigned int> m_inst_shape_ids;
|
std::unordered_map<std::pair<unsigned int, const db::PolygonRef *>, unsigned int> 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)
|
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)
|
||||||
{
|
{
|
||||||
|
|
@ -380,7 +511,7 @@ private:
|
||||||
|
|
||||||
// reuse the same id for shapes from the same instance -> this avoid duplicates with different IDs on
|
// reuse the same id for shapes from the same instance -> this avoid duplicates with different IDs on
|
||||||
// the intruder side.
|
// the intruder side.
|
||||||
std::map<std::pair<unsigned int, const db::PolygonRef *>, unsigned int>::const_iterator k = m_inst_shape_ids.find (std::make_pair (inst_id, ref2));
|
std::unordered_map<std::pair<unsigned int, const db::PolygonRef *>, unsigned int>::const_iterator k = m_inst_shape_ids.find (std::make_pair (inst_id, ref2));
|
||||||
if (k == m_inst_shape_ids.end ()) {
|
if (k == m_inst_shape_ids.end ()) {
|
||||||
|
|
||||||
k = m_inst_shape_ids.insert (std::make_pair (std::make_pair (inst_id, ref2), mp_result->next_id ())).first;
|
k = m_inst_shape_ids.insert (std::make_pair (std::make_pair (inst_id, ref2), mp_result->next_id ())).first;
|
||||||
|
|
@ -408,7 +539,7 @@ instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, u
|
||||||
const db::Cell &cell2 = layout2->cell (inst2->object ().cell_index ());
|
const db::Cell &cell2 = layout2->cell (inst2->object ().cell_index ());
|
||||||
db::box_convert <db::CellInst, true> inst2_bc (*layout2, layer2);
|
db::box_convert <db::CellInst, true> inst2_bc (*layout2, layer2);
|
||||||
|
|
||||||
std::set<db::ICplxTrans> relative_trans_seen;
|
std::unordered_set<db::ICplxTrans> relative_trans_seen;
|
||||||
|
|
||||||
for (db::CellInstArray::iterator n = inst1->begin (); ! n.at_end (); ++n) {
|
for (db::CellInstArray::iterator n = inst1->begin (); ! n.at_end (); ++n) {
|
||||||
|
|
||||||
|
|
@ -465,9 +596,9 @@ struct InteractionRegistrationInst2Inst
|
||||||
: db::box_scanner_receiver2<db::CellInstArray, unsigned int, db::CellInstArray, unsigned int>
|
: db::box_scanner_receiver2<db::CellInstArray, unsigned int, db::CellInstArray, unsigned int>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > interaction_value_type;
|
typedef std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<db::PolygonRef> > 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::map<const db::CellInstArray *, interaction_value_type> *result)
|
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<const db::CellInstArray *, interaction_value_type> *result)
|
||||||
: mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), m_subject_layer (subject_layer), m_intruder_layer (intruder_layer), m_dist (dist), mp_result (result)
|
: 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 ..
|
// nothing yet ..
|
||||||
|
|
@ -500,8 +631,8 @@ private:
|
||||||
const db::Layout *mp_subject_layout, *mp_intruder_layout;
|
const db::Layout *mp_subject_layout, *mp_intruder_layout;
|
||||||
unsigned int m_subject_layer, m_intruder_layer;
|
unsigned int m_subject_layer, m_intruder_layer;
|
||||||
db::Coord m_dist;
|
db::Coord m_dist;
|
||||||
std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *mp_result;
|
std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<db::PolygonRef> > > *mp_result;
|
||||||
std::set<std::pair<unsigned int, unsigned int> > m_interactions;
|
std::unordered_set<std::pair<unsigned int, unsigned int> > m_interactions;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -537,7 +668,7 @@ struct InteractionRegistrationInst2Shape
|
||||||
: db::box_scanner_receiver2<db::CellInstArray, unsigned int, db::PolygonRef, unsigned int>
|
: db::box_scanner_receiver2<db::CellInstArray, unsigned int, db::PolygonRef, unsigned int>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InteractionRegistrationInst2Shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *result)
|
InteractionRegistrationInst2Shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<db::PolygonRef> > > *result)
|
||||||
: mp_subject_layout (subject_layout), m_subject_layer (subject_layer), m_dist (dist), mp_result (result)
|
: mp_subject_layout (subject_layout), m_subject_layer (subject_layer), m_dist (dist), mp_result (result)
|
||||||
{
|
{
|
||||||
// nothing yet ..
|
// nothing yet ..
|
||||||
|
|
@ -554,7 +685,7 @@ private:
|
||||||
const db::Layout *mp_subject_layout;
|
const db::Layout *mp_subject_layout;
|
||||||
unsigned int m_subject_layer;
|
unsigned int m_subject_layer;
|
||||||
db::Coord m_dist;
|
db::Coord m_dist;
|
||||||
std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *mp_result;
|
std::unordered_map<const db::CellInstArray *, std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<db::PolygonRef> > > *mp_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -562,7 +693,7 @@ private:
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// LocalProcessorContextComputationTask implementation
|
// 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, std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders, db::Coord dist)
|
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, std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > &intruders, db::Coord dist)
|
||||||
: tl::Task (),
|
: tl::Task (),
|
||||||
mp_proc (proc), mp_contexts (&contexts), mp_parent_context (parent_context),
|
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_subject_parent (subject_parent), mp_subject_cell (subject_cell), m_subject_cell_inst (subject_cell_inst),
|
||||||
|
|
@ -630,7 +761,7 @@ void LocalProcessor::run (LocalOperation *op, unsigned int subject_layer, unsign
|
||||||
compute_results (contexts, op, output_layer);
|
compute_results (contexts, op, output_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalProcessor::push_results (db::Cell *cell, unsigned int output_layer, const std::set<db::PolygonRef> &result) const
|
void LocalProcessor::push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set<db::PolygonRef> &result) const
|
||||||
{
|
{
|
||||||
if (! result.empty ()) {
|
if (! result.empty ()) {
|
||||||
tl::MutexLocker locker (&cell->layout ()->lock ());
|
tl::MutexLocker locker (&cell->layout ()->lock ());
|
||||||
|
|
@ -654,7 +785,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const L
|
||||||
contexts.set_intruder_layer (intruder_layer);
|
contexts.set_intruder_layer (intruder_layer);
|
||||||
contexts.set_subject_layer (subject_layer);
|
contexts.set_subject_layer (subject_layer);
|
||||||
|
|
||||||
std::pair<std::set<db::CellInstArray>, std::set<db::PolygonRef> > intruders;
|
std::pair<std::unordered_set<db::CellInstArray>, std::unordered_set<db::PolygonRef> > 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 ());
|
||||||
|
|
||||||
if (mp_cc_job.get ()) {
|
if (mp_cc_job.get ()) {
|
||||||
|
|
@ -674,7 +805,7 @@ void LocalProcessor::issue_compute_contexts (LocalProcessorContexts &contexts,
|
||||||
db::Cell *subject_cell,
|
db::Cell *subject_cell,
|
||||||
const db::ICplxTrans &subject_cell_inst,
|
const db::ICplxTrans &subject_cell_inst,
|
||||||
const db::Cell *intruder_cell,
|
const db::Cell *intruder_cell,
|
||||||
std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders,
|
std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > &intruders,
|
||||||
db::Coord dist) const
|
db::Coord dist) const
|
||||||
{
|
{
|
||||||
bool is_small_job = subject_cell->begin ().at_end ();
|
bool is_small_job = subject_cell->begin ().at_end ();
|
||||||
|
|
@ -692,9 +823,11 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
||||||
db::Cell *subject_cell,
|
db::Cell *subject_cell,
|
||||||
const db::ICplxTrans &subject_cell_inst,
|
const db::ICplxTrans &subject_cell_inst,
|
||||||
const db::Cell *intruder_cell,
|
const db::Cell *intruder_cell,
|
||||||
const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders,
|
const std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > &intruders,
|
||||||
db::Coord dist) const
|
db::Coord dist) const
|
||||||
{
|
{
|
||||||
|
CRONOLOGY_COLLECTION_BRACKET(event_compute_contexts)
|
||||||
|
|
||||||
if (tl::verbosity () >= 30) {
|
if (tl::verbosity () >= 30) {
|
||||||
if (! subject_parent) {
|
if (! subject_parent) {
|
||||||
tl::log << tr ("Computing context for top cell ") << mp_subject_layout->cell_name (subject_cell->cell_index ());
|
tl::log << tr ("Computing context for top cell ") << mp_subject_layout->cell_name (subject_cell->cell_index ());
|
||||||
|
|
@ -726,6 +859,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
||||||
|
|
||||||
// perform the actual task ..
|
// perform the actual task ..
|
||||||
|
|
||||||
|
CRONOLOGY_COLLECTION_BRACKET(event_compute_contexts_unlocked)
|
||||||
const db::Shapes *intruder_shapes = 0;
|
const db::Shapes *intruder_shapes = 0;
|
||||||
if (intruder_cell) {
|
if (intruder_cell) {
|
||||||
intruder_shapes = &intruder_cell->shapes (contexts.intruder_layer ());
|
intruder_shapes = &intruder_cell->shapes (contexts.intruder_layer ());
|
||||||
|
|
@ -740,9 +874,9 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
||||||
|
|
||||||
if (! subject_cell->begin ().at_end ()) {
|
if (! subject_cell->begin ().at_end ()) {
|
||||||
|
|
||||||
typedef std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > interaction_value_type;
|
typedef std::pair<std::unordered_set<const db::CellInstArray *>, std::unordered_set<db::PolygonRef> > interaction_value_type;
|
||||||
|
|
||||||
std::map<const db::CellInstArray *, interaction_value_type> interactions;
|
std::unordered_map<const db::CellInstArray *, interaction_value_type> interactions;
|
||||||
|
|
||||||
// insert dummy interactions to handle at least the child cell vs. itself
|
// insert dummy interactions to handle at least the child cell vs. itself
|
||||||
// - this is important so we will always handle the instances unless they are
|
// - this is important so we will always handle the instances unless they are
|
||||||
|
|
@ -792,7 +926,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<db::CellInstArray>::const_iterator i = intruders.first.begin (); i != intruders.first.end (); ++i) {
|
for (std::unordered_set<db::CellInstArray>::const_iterator i = intruders.first.begin (); i != intruders.first.end (); ++i) {
|
||||||
if (! inst_bci (*i).empty ()) {
|
if (! inst_bci (*i).empty ()) {
|
||||||
scanner.insert2 (i.operator-> (), ++id);
|
scanner.insert2 (i.operator-> (), ++id);
|
||||||
}
|
}
|
||||||
|
|
@ -811,7 +945,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<db::PolygonRef>::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) {
|
for (std::unordered_set<db::PolygonRef>::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) {
|
||||||
scanner.insert2 (i.operator-> (), 0);
|
scanner.insert2 (i.operator-> (), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -824,10 +958,9 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
||||||
scanner.process (rec, dist, inst_bcs, db::box_convert<db::PolygonRef> ());
|
scanner.process (rec, dist, inst_bcs, db::box_convert<db::PolygonRef> ());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::map<const db::CellInstArray *, interaction_value_type>::const_iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
for (std::unordered_map<const db::CellInstArray *, interaction_value_type>::const_iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||||
|
|
||||||
db::Cell &subject_child_cell = mp_subject_layout->cell (i->first->object ().cell_index ());
|
db::Cell &subject_child_cell = mp_subject_layout->cell (i->first->object ().cell_index ());
|
||||||
db::shape_reference_translator<db::PolygonRef> rt (mp_subject_layout);
|
|
||||||
|
|
||||||
for (db::CellInstArray::iterator n = i->first->begin (); ! n.at_end (); ++n) {
|
for (db::CellInstArray::iterator n = i->first->begin (); ! n.at_end (); ++n) {
|
||||||
|
|
||||||
|
|
@ -837,17 +970,19 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts,
|
||||||
|
|
||||||
if (! nbox.empty ()) {
|
if (! nbox.empty ()) {
|
||||||
|
|
||||||
std::pair<std::set<db::CellInstArray>, std::set<db::PolygonRef> > intruders_below;
|
std::pair<std::unordered_set<db::CellInstArray>, std::unordered_set<db::PolygonRef> > intruders_below;
|
||||||
|
|
||||||
for (std::set<db::PolygonRef>::const_iterator p = i->second.second.begin (); p != i->second.second.end (); ++p) {
|
db::shape_reference_translator_with_trans<db::PolygonRef, db::ICplxTrans> rt (mp_subject_layout, tni);
|
||||||
|
|
||||||
|
for (std::unordered_set<db::PolygonRef>::const_iterator p = i->second.second.begin (); p != i->second.second.end (); ++p) {
|
||||||
if (nbox.overlaps (p->box ())) {
|
if (nbox.overlaps (p->box ())) {
|
||||||
intruders_below.second.insert (rt (*p, tni));
|
intruders_below.second.insert (rt (*p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: in some cases, it may be possible to optimize this for arrays
|
// TODO: in some cases, it may be possible to optimize this for arrays
|
||||||
|
|
||||||
for (std::set<const db::CellInstArray *>::const_iterator j = i->second.first.begin (); j != i->second.first.end (); ++j) {
|
for (std::unordered_set<const db::CellInstArray *>::const_iterator j = i->second.first.begin (); j != i->second.first.end (); ++j) {
|
||||||
for (db::CellInstArray::iterator k = (*j)->begin_touching (nbox.enlarged (db::Vector (-1, -1)), inst_bcii); ! k.at_end (); ++k) {
|
for (db::CellInstArray::iterator k = (*j)->begin_touching (nbox.enlarged (db::Vector (-1, -1)), inst_bcii); ! k.at_end (); ++k) {
|
||||||
db::ICplxTrans tk = (*j)->complex_trans (*k);
|
db::ICplxTrans tk = (*j)->complex_trans (*k);
|
||||||
// NOTE: no self-interactions
|
// NOTE: no self-interactions
|
||||||
|
|
@ -899,7 +1034,7 @@ LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOp
|
||||||
tl::SelfTimer timer (tl::verbosity () >= 21, tl::sprintf (tl::to_string (tr ("Computing results iteration #%d")), iter));
|
tl::SelfTimer timer (tl::verbosity () >= 21, tl::sprintf (tl::to_string (tr ("Computing results iteration #%d")), iter));
|
||||||
|
|
||||||
bool any = false;
|
bool any = false;
|
||||||
std::set<db::cell_index_type> later;
|
std::unordered_set<db::cell_index_type> later;
|
||||||
|
|
||||||
std::vector<db::cell_index_type> next_cells_bu;
|
std::vector<db::cell_index_type> next_cells_bu;
|
||||||
next_cells_bu.reserve (cells_bu.size ());
|
next_cells_bu.reserve (cells_bu.size ());
|
||||||
|
|
@ -954,7 +1089,7 @@ LocalProcessor::compute_results (LocalProcessorContexts &contexts, const LocalOp
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LocalProcessor::compute_local_cell (const LocalProcessorContexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const db::LocalOperation *op, const std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > &intruders, std::set<db::PolygonRef> &result) const
|
LocalProcessor::compute_local_cell (const LocalProcessorContexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const db::LocalOperation *op, const std::pair<std::unordered_set<CellInstArray>, std::unordered_set<db::PolygonRef> > &intruders, std::unordered_set<db::PolygonRef> &result) const
|
||||||
{
|
{
|
||||||
const db::Shapes *subject_shapes = &subject_cell->shapes (contexts.subject_layer ());
|
const db::Shapes *subject_shapes = &subject_cell->shapes (contexts.subject_layer ());
|
||||||
|
|
||||||
|
|
@ -1001,7 +1136,7 @@ LocalProcessor::compute_local_cell (const LocalProcessorContexts &contexts, db::
|
||||||
scanner.insert (ref, id++);
|
scanner.insert (ref, id++);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<db::PolygonRef>::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) {
|
for (std::unordered_set<db::PolygonRef>::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) {
|
||||||
scanner.insert (i.operator-> (), interactions.next_id ());
|
scanner.insert (i.operator-> (), interactions.next_id ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1018,7 +1153,7 @@ LocalProcessor::compute_local_cell (const LocalProcessorContexts &contexts, db::
|
||||||
scanner.insert1 (ref, id++);
|
scanner.insert1 (ref, id++);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<db::PolygonRef>::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) {
|
for (std::unordered_set<db::PolygonRef>::const_iterator i = intruders.second.begin (); i != intruders.second.end (); ++i) {
|
||||||
scanner.insert2 (i.operator-> (), interactions.next_id ());
|
scanner.insert2 (i.operator-> (), interactions.next_id ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1060,7 +1195,7 @@ LocalProcessor::compute_local_cell (const LocalProcessorContexts &contexts, db::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<db::CellInstArray>::const_iterator i = intruders.first.begin (); i != intruders.first.end (); ++i) {
|
for (std::unordered_set<db::CellInstArray>::const_iterator i = intruders.first.begin (); i != intruders.first.end (); ++i) {
|
||||||
if (! inst_bci (*i).empty ()) {
|
if (! inst_bci (*i).empty ()) {
|
||||||
scanner.insert2 (i.operator-> (), ++inst_id);
|
scanner.insert2 (i.operator-> (), ++inst_id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,46 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
// @@@ should go into dbHash.h
|
||||||
|
#include "dbHash.h"
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <class C>
|
||||||
|
struct hash <db::disp_trans<C> >
|
||||||
|
{
|
||||||
|
size_t operator() (const db::disp_trans<C> &t) const
|
||||||
|
{
|
||||||
|
return hfunc (t.disp ());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Polygon, class Trans>
|
||||||
|
struct hash<db::polygon_ref<Polygon, Trans> >
|
||||||
|
{
|
||||||
|
size_t operator() (const db::polygon_ref<Polygon, Trans> &o) const
|
||||||
|
{
|
||||||
|
return hfunc (size_t (o.ptr ()), std::hash<Trans> () (o.trans ()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct hash<std::unordered_set<T> >
|
||||||
|
{
|
||||||
|
size_t operator() (const std::unordered_set<T> &o) const
|
||||||
|
{
|
||||||
|
size_t hf = 0;
|
||||||
|
for (typename std::unordered_set<T>::const_iterator i = o.begin (); i != o.end (); ++i) {
|
||||||
|
hf = hfunc (hf, std::hash <T> () (*i));
|
||||||
|
}
|
||||||
|
return hf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
@ -45,7 +85,7 @@ class LocalProcessorContexts;
|
||||||
class DB_PLUGIN_PUBLIC ShapeInteractions
|
class DB_PLUGIN_PUBLIC ShapeInteractions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<unsigned int, std::vector<unsigned int> > container;
|
typedef std::unordered_map<unsigned int, std::vector<unsigned int> > container;
|
||||||
typedef container::const_iterator iterator;
|
typedef container::const_iterator iterator;
|
||||||
typedef container::value_type::second_type::const_iterator iterator2;
|
typedef container::value_type::second_type::const_iterator iterator2;
|
||||||
|
|
||||||
|
|
@ -74,8 +114,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<unsigned int, std::vector<unsigned int> > m_interactions;
|
std::unordered_map<unsigned int, std::vector<unsigned int> > m_interactions;
|
||||||
std::map<unsigned int, db::PolygonRef> m_shapes;
|
std::unordered_map<unsigned int, db::PolygonRef> m_shapes;
|
||||||
unsigned int m_id;
|
unsigned int m_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -102,14 +142,14 @@ public:
|
||||||
LocalProcessorCellContext ();
|
LocalProcessorCellContext ();
|
||||||
|
|
||||||
void add (db::LocalProcessorCellContext *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst);
|
void add (db::LocalProcessorCellContext *parent_context, db::Cell *parent, const db::ICplxTrans &cell_inst);
|
||||||
void propagate (const std::set<db::PolygonRef> &res);
|
void propagate (const std::unordered_set<db::PolygonRef> &res);
|
||||||
|
|
||||||
std::set<db::PolygonRef> &propagated ()
|
std::unordered_set<db::PolygonRef> &propagated ()
|
||||||
{
|
{
|
||||||
return m_propagated;
|
return m_propagated;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::set<db::PolygonRef> &propagated () const
|
const std::unordered_set<db::PolygonRef> &propagated () const
|
||||||
{
|
{
|
||||||
return m_propagated;
|
return m_propagated;
|
||||||
}
|
}
|
||||||
|
|
@ -119,16 +159,22 @@ public:
|
||||||
return m_drops.size ();
|
return m_drops.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tl::Mutex &lock ()
|
||||||
|
{
|
||||||
|
return m_lock;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<db::PolygonRef> m_propagated;
|
std::unordered_set<db::PolygonRef> m_propagated;
|
||||||
std::vector<LocalProcessorCellDrop> m_drops;
|
std::vector<LocalProcessorCellDrop> m_drops;
|
||||||
|
tl::Mutex m_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DB_PLUGIN_PUBLIC LocalProcessorCellContexts
|
class DB_PLUGIN_PUBLIC LocalProcessorCellContexts
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > key_type;
|
typedef std::pair<std::unordered_set<CellInstArray>, std::unordered_set<db::PolygonRef> > key_type;
|
||||||
typedef std::map<key_type, db::LocalProcessorCellContext> map_type;
|
typedef std::unordered_map<key_type, db::LocalProcessorCellContext> map_type;
|
||||||
typedef map_type::const_iterator iterator;
|
typedef map_type::const_iterator iterator;
|
||||||
|
|
||||||
LocalProcessorCellContexts ();
|
LocalProcessorCellContexts ();
|
||||||
|
|
@ -150,13 +196,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const db::Cell *mp_intruder_cell;
|
const db::Cell *mp_intruder_cell;
|
||||||
std::map<key_type, db::LocalProcessorCellContext> m_contexts;
|
std::unordered_map<key_type, db::LocalProcessorCellContext> m_contexts;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DB_PLUGIN_PUBLIC LocalProcessorContexts
|
class DB_PLUGIN_PUBLIC LocalProcessorContexts
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<db::Cell *, LocalProcessorCellContexts> contexts_per_cell_type;
|
typedef std::unordered_map<db::Cell *, LocalProcessorCellContexts> contexts_per_cell_type;
|
||||||
typedef contexts_per_cell_type::iterator iterator;
|
typedef contexts_per_cell_type::iterator iterator;
|
||||||
|
|
||||||
LocalProcessorContexts ()
|
LocalProcessorContexts ()
|
||||||
|
|
@ -229,7 +275,7 @@ class DB_PLUGIN_PUBLIC LocalProcessorContextComputationTask
|
||||||
: public tl::Task
|
: public tl::Task
|
||||||
{
|
{
|
||||||
public:
|
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, std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders, db::Coord dist);
|
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, std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > &intruders, db::Coord dist);
|
||||||
void perform ();
|
void perform ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -240,7 +286,7 @@ private:
|
||||||
db::Cell *mp_subject_cell;
|
db::Cell *mp_subject_cell;
|
||||||
db::ICplxTrans m_subject_cell_inst;
|
db::ICplxTrans m_subject_cell_inst;
|
||||||
const db::Cell *mp_intruder_cell;
|
const db::Cell *mp_intruder_cell;
|
||||||
std::pair<std::set<CellInstArray>, std::set<PolygonRef> > m_intruders;
|
std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > m_intruders;
|
||||||
db::Coord m_dist;
|
db::Coord m_dist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -324,11 +370,11 @@ private:
|
||||||
mutable std::auto_ptr<tl::Job<LocalProcessorContextComputationWorker> > mp_cc_job;
|
mutable std::auto_ptr<tl::Job<LocalProcessorContextComputationWorker> > mp_cc_job;
|
||||||
|
|
||||||
std::string description (const LocalOperation *op) const;
|
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 std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders, db::Coord dist) 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 std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > &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 std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &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 std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > &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, std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &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, std::pair<std::unordered_set<CellInstArray>, std::unordered_set<PolygonRef> > &intruders, db::Coord dist) const;
|
||||||
void push_results (db::Cell *cell, unsigned int output_layer, const std::set<db::PolygonRef> &result) const;
|
void push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set<db::PolygonRef> &result) const;
|
||||||
void compute_local_cell (const db::LocalProcessorContexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const LocalOperation *op, const std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > &intruders, std::set<db::PolygonRef> &result) const;
|
void compute_local_cell (const db::LocalProcessorContexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const LocalOperation *op, const std::pair<std::unordered_set<CellInstArray>, std::unordered_set<db::PolygonRef> > &intruders, std::unordered_set<db::PolygonRef> &result) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor specifying an external vector for storing the polygons
|
* @brief Constructor specifying an external vector for storing the polygons
|
||||||
*/
|
*/
|
||||||
PolygonRefGenerator (db::Layout *layout, std::set<db::PolygonRef> &polyrefs)
|
PolygonRefGenerator (db::Layout *layout, std::unordered_set<db::PolygonRef> &polyrefs)
|
||||||
: PolygonSink (), mp_layout (layout), mp_polyrefs (&polyrefs)
|
: PolygonSink (), mp_layout (layout), mp_polyrefs (&polyrefs)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
db::Layout *mp_layout;
|
db::Layout *mp_layout;
|
||||||
std::set<db::PolygonRef> *mp_polyrefs;
|
std::unordered_set<db::PolygonRef> *mp_polyrefs;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +88,7 @@ BoolAndOrNotLocalOperation::description () const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::set<db::PolygonRef> &result) const
|
BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::unordered_set<db::PolygonRef> &result) const
|
||||||
{
|
{
|
||||||
db::EdgeProcessor ep;
|
db::EdgeProcessor ep;
|
||||||
|
|
||||||
|
|
@ -147,7 +147,7 @@ SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wra
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::set<db::PolygonRef> &result) const
|
void SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::unordered_set<db::PolygonRef> &result) const
|
||||||
{
|
{
|
||||||
if (m_wrap_count == 0) {
|
if (m_wrap_count == 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@
|
||||||
#include "dbLayout.h"
|
#include "dbLayout.h"
|
||||||
#include "dbPluginCommon.h"
|
#include "dbPluginCommon.h"
|
||||||
|
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
|
|
@ -87,7 +87,7 @@ public:
|
||||||
* @param interactions The interaction set
|
* @param interactions The interaction set
|
||||||
* @param result The container to which the results are written
|
* @param result The container to which the results are written
|
||||||
*/
|
*/
|
||||||
virtual void compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::set<db::PolygonRef> &result) const = 0;
|
virtual void compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::unordered_set<db::PolygonRef> &result) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Indicates the desired behaviour when a shape does not have an intruder
|
* @brief Indicates the desired behaviour when a shape does not have an intruder
|
||||||
|
|
@ -115,7 +115,7 @@ class DB_PLUGIN_PUBLIC BoolAndOrNotLocalOperation
|
||||||
public:
|
public:
|
||||||
BoolAndOrNotLocalOperation (bool is_and);
|
BoolAndOrNotLocalOperation (bool is_and);
|
||||||
|
|
||||||
virtual void compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::set<db::PolygonRef> &result) const;
|
virtual void compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::unordered_set<db::PolygonRef> &result) const;
|
||||||
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
|
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
|
||||||
virtual std::string description () const;
|
virtual std::string description () const;
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ class DB_PLUGIN_PUBLIC SelfOverlapMergeLocalOperation
|
||||||
public:
|
public:
|
||||||
SelfOverlapMergeLocalOperation (unsigned int wrap_count);
|
SelfOverlapMergeLocalOperation (unsigned int wrap_count);
|
||||||
|
|
||||||
virtual void compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::set<db::PolygonRef> &result) const;
|
virtual void compute_local (db::Layout *layout, const ShapeInteractions &interactions, std::unordered_set<db::PolygonRef> &result) const;
|
||||||
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
|
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
|
||||||
virtual std::string description () const;
|
virtual std::string description () const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public:
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compute_local (db::Layout *layout, const db::ShapeInteractions &interactions, std::set<db::PolygonRef> &result) const
|
virtual void compute_local (db::Layout *layout, const db::ShapeInteractions &interactions, std::unordered_set<db::PolygonRef> &result) const
|
||||||
{
|
{
|
||||||
db::ShapeInteractions sized_interactions = interactions;
|
db::ShapeInteractions sized_interactions = interactions;
|
||||||
for (db::ShapeInteractions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
|
for (db::ShapeInteractions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
|
||||||
|
|
@ -91,7 +91,7 @@ public:
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compute_local (db::Layout *layout, const db::ShapeInteractions &interactions, std::set<db::PolygonRef> &result) const
|
virtual void compute_local (db::Layout *layout, const db::ShapeInteractions &interactions, std::unordered_set<db::PolygonRef> &result) const
|
||||||
{
|
{
|
||||||
db::ShapeInteractions sized_interactions = interactions;
|
db::ShapeInteractions sized_interactions = interactions;
|
||||||
for (db::ShapeInteractions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
|
for (db::ShapeInteractions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue