Merge branch 'master' of github.com:KLayout/klayout

This commit is contained in:
Matthias Koefferlein 2023-11-19 09:06:19 +01:00
commit c9ddfbe4e3
66 changed files with 1965 additions and 871 deletions

View File

@ -43,6 +43,11 @@ db::Trans OrientationReducer::reduce (const db::Trans &trans) const
return db::Trans (trans.fp_trans ());
}
bool OrientationReducer::equals (const TransformationReducer *other) const
{
return dynamic_cast<const OrientationReducer *> (other) != 0;
}
// ------------------------------------------------------------------------------------------
db::ICplxTrans OrthogonalTransformationReducer::reduce (const db::ICplxTrans &trans) const
@ -63,6 +68,11 @@ db::Trans OrthogonalTransformationReducer::reduce (const db::Trans &) const
return db::Trans ();
}
bool OrthogonalTransformationReducer::equals (const TransformationReducer *other) const
{
return dynamic_cast<const OrthogonalTransformationReducer *> (other) != 0;
}
// ------------------------------------------------------------------------------------------
db::ICplxTrans MagnificationReducer::reduce (const db::ICplxTrans &trans) const
@ -75,6 +85,11 @@ db::Trans MagnificationReducer::reduce (const db::Trans &) const
return db::Trans ();
}
bool MagnificationReducer::equals (const TransformationReducer *other) const
{
return dynamic_cast<const MagnificationReducer *> (other) != 0;
}
// ------------------------------------------------------------------------------------------
db::ICplxTrans XYAnisotropyAndMagnificationReducer::reduce (const db::ICplxTrans &trans) const
@ -91,6 +106,11 @@ db::Trans XYAnisotropyAndMagnificationReducer::reduce (const db::Trans &trans) c
return db::Trans (trans.angle () % 2, false, db::Vector ());
}
bool XYAnisotropyAndMagnificationReducer::equals (const TransformationReducer *other) const
{
return dynamic_cast<const XYAnisotropyAndMagnificationReducer *> (other) != 0;
}
// ------------------------------------------------------------------------------------------
db::ICplxTrans MagnificationAndOrientationReducer::reduce (const db::ICplxTrans &trans) const
@ -105,6 +125,11 @@ db::Trans MagnificationAndOrientationReducer::reduce (const db::Trans &trans) co
return db::Trans (trans.fp_trans ());
}
bool MagnificationAndOrientationReducer::equals (const TransformationReducer *other) const
{
return dynamic_cast<const MagnificationAndOrientationReducer *> (other) != 0;
}
// ------------------------------------------------------------------------------------------
GridReducer::GridReducer (db::Coord grid)
@ -130,6 +155,12 @@ db::Trans GridReducer::reduce (const db::Trans &trans) const
return res;
}
bool GridReducer::equals (const TransformationReducer *other) const
{
const GridReducer *red = dynamic_cast<const GridReducer *> (other);
return red != 0 && red->m_grid == m_grid;
}
// ------------------------------------------------------------------------------------------
ScaleAndGridReducer::ScaleAndGridReducer (db::Coord grid, db::Coord mult, db::Coord div)
@ -174,6 +205,12 @@ db::Trans ScaleAndGridReducer::reduce (const db::Trans &trans) const
return res;
}
bool ScaleAndGridReducer::equals (const TransformationReducer *other) const
{
const ScaleAndGridReducer *red = dynamic_cast<const ScaleAndGridReducer *> (other);
return red != 0 && red->m_grid == m_grid && red->m_mult == m_mult;
}
// ------------------------------------------------------------------------------------------
VariantsCollectorBase::VariantsCollectorBase ()
@ -183,57 +220,67 @@ VariantsCollectorBase::VariantsCollectorBase ()
}
VariantsCollectorBase::VariantsCollectorBase (const TransformationReducer *red)
: mp_red (red)
: mp_red (red), mp_layout (0)
{
// .. nothing yet ..
}
void
VariantsCollectorBase::collect (const db::Layout &layout, const db::Cell &top_cell)
VariantsCollectorBase::collect (Layout *layout, db::cell_index_type initial_cell)
{
tl_assert (mp_red != 0);
mp_layout = layout;
// The top cell gets a "variant" with unit transformation
m_variants [top_cell.cell_index ()].insert (std::make_pair (db::ICplxTrans (), 1));
m_called.clear ();
m_called.insert (initial_cell);
std::set<db::cell_index_type> called;
top_cell.collect_called_cells (called);
layout->cell (initial_cell).collect_called_cells (m_called);
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
for (db::Layout::top_down_const_iterator c = layout->begin_top_down (); c != layout->end_top_down (); ++c) {
if (called.find (*c) == called.end ()) {
if (m_called.find (*c) == m_called.end ()) {
continue;
}
// collect the parent variants per parent cell
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> > variants_per_parent_cell;
for (db::Cell::parent_inst_iterator pi = layout.cell (*c).begin_parent_insts (); ! pi.at_end (); ++pi) {
std::map<db::ICplxTrans, size_t> &variants = variants_per_parent_cell [pi->inst ().object ().cell_index ()];
std::map<db::cell_index_type, std::set<db::ICplxTrans> > variants_per_parent_cell;
for (db::Cell::parent_inst_iterator pi = layout->cell (*c).begin_parent_insts (); ! pi.at_end (); ++pi) {
std::set<db::ICplxTrans> &variants = variants_per_parent_cell [pi->inst ().object ().cell_index ()];
add_variant (variants, pi->child_inst ().cell_inst (), mp_red->is_translation_invariant ());
}
// compute the resulting variants
std::map<db::ICplxTrans, size_t> &new_variants = m_variants [*c];
std::set<db::ICplxTrans> new_variants;
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> >::const_iterator pv = variants_per_parent_cell.begin (); pv != variants_per_parent_cell.end (); ++pv) {
product (variants (pv->first), pv->second, new_variants);
auto vc = m_variants.find (*c);
if (vc != m_variants.end ()) {
new_variants = vc->second;
}
for (auto pv = variants_per_parent_cell.begin (); pv != variants_per_parent_cell.end (); ++pv) {
auto v = m_variants.find (pv->first);
if (v != m_variants.end ()) {
product (v->second, pv->second, new_variants);
} else {
new_variants.insert (pv->second.begin (), pv->second.end ());
}
}
if (new_variants.size () > 1 || (new_variants.size () == 1 && ! new_variants.begin ()->is_unity ())) {
m_variants [*c] = std::move (new_variants);
}
}
}
void
VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_table)
VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_table)
{
tl_assert (mp_red != 0);
db::LayoutLocker locker (&layout);
std::set<db::cell_index_type> called;
top_cell.collect_called_cells (called);
called.insert (top_cell.cell_index ());
db::LayoutLocker locker (mp_layout);
// create new cells for the variants
@ -242,16 +289,16 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell
var_table = &var_table_intern;
}
for (db::Layout::bottom_up_const_iterator c = layout.begin_bottom_up (); c != layout.end_bottom_up (); ++c) {
for (db::Layout::bottom_up_const_iterator c = mp_layout->begin_bottom_up (); c != mp_layout->end_bottom_up (); ++c) {
if (called.find (*c) == called.end ()) {
if (m_called.find (*c) == m_called.end ()) {
continue;
}
db::Cell &cell = layout.cell (*c);
db::Cell &cell = mp_layout->cell (*c);
std::map<db::ICplxTrans, size_t> &vv = m_variants [*c];
if (vv.size () > 1) {
auto vc = m_variants.find (*c);
if (vc != m_variants.end () && vc->second.size () > 1) {
std::map<db::ICplxTrans, db::cell_index_type> &vt = (*var_table) [*c];
@ -265,35 +312,42 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell
cell.clear_insts ();
int index = 0;
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v, ++index) {
for (auto v = vc->second.begin (); v != vc->second.end (); ++v, ++index) {
db::cell_index_type ci_var;
if (v != vv.begin ()) {
if (v != vc->second.begin ()) {
std::string var_name = layout.cell_name (*c);
std::string var_name = mp_layout->cell_name (*c);
var_name += "$VAR" + tl::to_string (index);
ci_var = layout.add_cell (var_name.c_str ());
layout.add_meta_info (ci_var, layout.begin_meta (*c), layout.end_meta (*c));
copy_shapes (layout, ci_var, *c);
ci_var = mp_layout->add_cell (var_name.c_str ());
m_called.insert (ci_var);
mp_layout->add_meta_info (ci_var, mp_layout->begin_meta (*c), mp_layout->end_meta (*c));
copy_shapes (*mp_layout, ci_var, *c);
// a new entry for the variant
m_variants [ci_var].insert (*v);
if (! v->is_unity ()) {
m_variants [ci_var].insert (*v);
}
} else {
ci_var = *c;
}
vt.insert (std::make_pair (v->first, ci_var));
create_var_instances (layout.cell (ci_var), inst, v->first, *var_table, mp_red->is_translation_invariant ());
vt.insert (std::make_pair (*v, ci_var));
create_var_instances (mp_layout->cell (ci_var), inst, *v, *var_table, mp_red->is_translation_invariant ());
}
// correct the first (remaining) entry
std::pair<db::ICplxTrans, size_t> v1 = *vt.begin ();
vv.clear ();
vv.insert (v1);
if (! vt.begin ()->first.is_unity ()) {
std::set<db::ICplxTrans> &tv = m_variants [*c];
tv.clear ();
tv.insert (vt.begin ()->first);
} else {
m_variants.erase (*c);
}
} else {
@ -315,17 +369,24 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell
}
cell.clear_insts ();
create_var_instances (cell, inst, vv.begin ()->first, *var_table, mp_red->is_translation_invariant ());
if (vc != m_variants.end ()) {
create_var_instances (cell, inst, *vc->second.begin (), *var_table, mp_red->is_translation_invariant ());
} else {
create_var_instances (cell, inst, db::ICplxTrans (), *var_table, mp_red->is_translation_invariant ());
}
}
}
}
mp_layout->variants_created_event (var_table);
}
void
VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, unsigned int layer, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_commit)
VariantsCollectorBase::commit_shapes (unsigned int layer, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_commit)
{
tl_assert (mp_red != 0);
@ -336,28 +397,24 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
// NOTE: this implementation suffers from accumulation of propagated shapes: we add more levels of propagated
// shapes if required. We don't clean up, because we do not know when a shape collection stops being required.
db::LayoutLocker locker (&layout);
db::LayoutLocker locker (mp_layout);
std::set<db::cell_index_type> called;
top_cell.collect_called_cells (called);
called.insert (top_cell.cell_index ());
for (db::Layout::bottom_up_const_iterator c = mp_layout->begin_bottom_up (); c != mp_layout->end_bottom_up (); ++c) {
for (db::Layout::bottom_up_const_iterator c = layout.begin_bottom_up (); c != layout.end_bottom_up (); ++c) {
if (called.find (*c) == called.end ()) {
if (m_called.find (*c) == m_called.end ()) {
continue;
}
db::Cell &cell = layout.cell (*c);
db::Cell &cell = mp_layout->cell (*c);
std::map<db::ICplxTrans, size_t> &vvc = m_variants [*c];
if (vvc.size () > 1) {
auto vvc = m_variants.find (*c);
if (vvc != m_variants.end () && vvc->second.size () > 1) {
for (std::map<db::ICplxTrans, size_t>::const_iterator vc = vvc.begin (); vc != vvc.end (); ++vc) {
for (auto vc = vvc->second.begin (); vc != vvc->second.end (); ++vc) {
for (db::Cell::const_iterator i = cell.begin (); ! i.at_end (); ++i) {
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> >::const_iterator tc = to_commit.find (i->cell_index ());
auto tc = to_commit.find (i->cell_index ());
if (tc != to_commit.end ()) {
const std::map<db::ICplxTrans, db::Shapes> &vt = tc->second;
@ -369,11 +426,11 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
db::ICplxTrans t = i->complex_trans (*ia);
db::ICplxTrans rt = mp_red->reduce (vc->first * mp_red->reduce_trans (t));
db::ICplxTrans rt = mp_red->reduce (*vc * mp_red->reduce_trans (t));
std::map<db::ICplxTrans, db::Shapes>::const_iterator v = vt.find (rt);
if (v != vt.end ()) {
db::Shapes &ps = propagated [vc->first];
db::Shapes &ps = propagated [*vc];
tl::ident_map<db::Layout::properties_id_type> pm;
for (db::Shapes::shape_iterator si = v->second.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
@ -394,7 +451,7 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
// single variant -> we can commit any shapes we have kept for this cell directly to the cell
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> >::iterator l = to_commit.find (*c);
auto l = to_commit.find (*c);
if (l != to_commit.end ()) {
tl_assert (l->second.size () == 1);
cell.shapes (layer).insert (l->second.begin ()->second);
@ -405,7 +462,7 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
for (db::Cell::const_iterator i = cell.begin (); ! i.at_end (); ++i) {
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> >::const_iterator tc = to_commit.find (i->cell_index ());
auto tc = to_commit.find (i->cell_index ());
if (tc != to_commit.end ()) {
const std::map<db::ICplxTrans, db::Shapes> &vt = tc->second;
@ -413,7 +470,10 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
db::ICplxTrans t = i->complex_trans (*ia);
db::ICplxTrans rt = mp_red->reduce (vvc.begin ()->first * mp_red->reduce_trans (t));
db::ICplxTrans rt = mp_red->reduce_trans (t);
if (vvc != m_variants.end ()) {
rt = mp_red->reduce (*vvc->second.begin () * rt);
}
std::map<db::ICplxTrans, db::Shapes>::const_iterator v = vt.find (rt);
if (v != vt.end ()) {
@ -437,22 +497,49 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
}
}
const std::map<db::ICplxTrans, size_t> &
static std::set<db::ICplxTrans> make_once ()
{
std::set<db::ICplxTrans> res;
res.insert (db::ICplxTrans ());
return res;
}
static std::set<db::ICplxTrans> s_once (make_once ());
const std::set<db::ICplxTrans> &
VariantsCollectorBase::variants (db::cell_index_type ci) const
{
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> >::const_iterator v = m_variants.find (ci);
static std::map<db::ICplxTrans, size_t> empty_set;
if (m_called.find (ci) == m_called.end ()) {
static std::set<db::ICplxTrans> empty;
return empty;
}
auto v = m_variants.find (ci);
if (v == m_variants.end ()) {
return empty_set;
return s_once;
} else {
return v->second;
}
}
const db::ICplxTrans &
VariantsCollectorBase::single_variant_transformation (db::cell_index_type ci) const
{
auto v = m_variants.find (ci);
if (v == m_variants.end ()) {
static db::ICplxTrans tr1;
return tr1;
} else {
tl_assert (v->second.size () == 1);
return *v->second.begin ();
}
}
bool
VariantsCollectorBase::has_variants () const
{
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> >::const_iterator i = m_variants.begin (); i != m_variants.end (); ++i) {
for (auto i = m_variants.begin (); i != m_variants.end (); ++i) {
if (i->second.size () > 1) {
return true;
}
@ -461,7 +548,7 @@ VariantsCollectorBase::has_variants () const
}
void
VariantsCollectorBase::add_variant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst, bool tl_invariant) const
VariantsCollectorBase::add_variant (std::set<db::ICplxTrans> &variants, const db::CellInstArray &inst, bool tl_invariant) const
{
if (tl_invariant) {
add_variant_tl_invariant (variants, inst);
@ -471,35 +558,35 @@ VariantsCollectorBase::add_variant (std::map<db::ICplxTrans, size_t> &variants,
}
void
VariantsCollectorBase::add_variant_non_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const
VariantsCollectorBase::add_variant_non_tl_invariant (std::set<db::ICplxTrans> &variants, const db::CellInstArray &inst) const
{
if (inst.is_complex ()) {
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
variants [mp_red->reduce_trans (inst.complex_trans (*i))] += 1;
variants.insert (mp_red->reduce_trans (inst.complex_trans (*i)));
}
} else {
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
variants [db::ICplxTrans (mp_red->reduce_trans (*i))] += 1;
variants.insert (db::ICplxTrans (mp_red->reduce_trans (*i)));
}
}
}
void
VariantsCollectorBase::add_variant_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const
VariantsCollectorBase::add_variant_tl_invariant (std::set<db::ICplxTrans> &variants, const db::CellInstArray &inst) const
{
if (inst.is_complex ()) {
variants [mp_red->reduce_trans (inst.complex_trans ())] += inst.size ();
variants.insert (mp_red->reduce_trans (inst.complex_trans ()));
} else {
variants [db::ICplxTrans (mp_red->reduce_trans (inst.front ()))] += inst.size ();
variants.insert (db::ICplxTrans (mp_red->reduce_trans (inst.front ())));
}
}
void
VariantsCollectorBase::product (const std::map<db::ICplxTrans, size_t> &v1, const std::map<db::ICplxTrans, size_t> &v2, std::map<db::ICplxTrans, size_t> &prod) const
VariantsCollectorBase::product (const std::set<db::ICplxTrans> &v1, const std::set<db::ICplxTrans> &v2, std::set<db::ICplxTrans> &prod) const
{
for (std::map<db::ICplxTrans, size_t>::const_iterator i = v1.begin (); i != v1.end (); ++i) {
for (std::map<db::ICplxTrans, size_t>::const_iterator j = v2.begin (); j != v2.end (); ++j) {
prod [mp_red->reduce (i->first * j->first)] += i->second * j->second;
for (auto i = v1.begin (); i != v1.end (); ++i) {
for (auto j = v2.begin (); j != v2.end (); ++j) {
prod.insert (mp_red->reduce (*i * *j));
}
}
}
@ -527,9 +614,9 @@ VariantsCollectorBase::create_var_instances (db::Cell &in_cell, std::vector<db::
void
VariantsCollectorBase::create_var_instances_non_tl_invariant (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table) const
{
for (std::vector<db::CellInstArrayWithProperties>::const_iterator i = inst.begin (); i != inst.end (); ++i) {
for (auto i = inst.begin (); i != inst.end (); ++i) {
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> >::const_iterator f = var_table.find (i->object ().cell_index ());
auto f = var_table.find (i->object ().cell_index ());
if (f == var_table.end ()) {
in_cell.insert (*i);
@ -589,9 +676,9 @@ VariantsCollectorBase::create_var_instances_non_tl_invariant (db::Cell &in_cell,
void
VariantsCollectorBase::create_var_instances_tl_invariant (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table) const
{
for (std::vector<db::CellInstArrayWithProperties>::const_iterator i = inst.begin (); i != inst.end (); ++i) {
for (auto i = inst.begin (); i != inst.end (); ++i) {
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> >::const_iterator f = var_table.find (i->object ().cell_index ());
auto f = var_table.find (i->object ().cell_index ());
if (f == var_table.end ()) {
in_cell.insert (*i);
@ -615,5 +702,122 @@ VariantsCollectorBase::create_var_instances_tl_invariant (db::Cell &in_cell, std
}
}
// ------------------------------------------------------------------------------------------
VariantStatistics::VariantStatistics ()
: mp_red ()
{
// .. nothing yet ..
}
VariantStatistics::VariantStatistics (const TransformationReducer *red)
: mp_red (red)
{
// .. nothing yet ..
}
void
VariantStatistics::collect (const db::Layout *layout, db::cell_index_type initial_cell)
{
tl_assert (mp_red != 0);
// The top cell gets a "variant" with unit transformation
m_variants [initial_cell].insert (std::make_pair (db::ICplxTrans (), 1));
std::set<db::cell_index_type> called;
layout->cell (initial_cell).collect_called_cells (called);
for (db::Layout::top_down_const_iterator c = layout->begin_top_down (); c != layout->end_top_down (); ++c) {
if (called.find (*c) == called.end ()) {
continue;
}
// collect the parent variants per parent cell
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> > variants_per_parent_cell;
for (db::Cell::parent_inst_iterator pi = layout->cell (*c).begin_parent_insts (); ! pi.at_end (); ++pi) {
std::map<db::ICplxTrans, size_t> &variants = variants_per_parent_cell [pi->inst ().object ().cell_index ()];
add_variant (variants, pi->child_inst ().cell_inst (), mp_red->is_translation_invariant ());
}
// compute the resulting variants
std::map<db::ICplxTrans, size_t> &new_variants = m_variants [*c];
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> >::const_iterator pv = variants_per_parent_cell.begin (); pv != variants_per_parent_cell.end (); ++pv) {
product (variants (pv->first), pv->second, new_variants);
}
}
}
const std::map<db::ICplxTrans, size_t> &
VariantStatistics::variants (db::cell_index_type ci) const
{
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> >::const_iterator v = m_variants.find (ci);
static std::map<db::ICplxTrans, size_t> empty_set;
if (v == m_variants.end ()) {
return empty_set;
} else {
return v->second;
}
}
bool
VariantStatistics::has_variants () const
{
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> >::const_iterator i = m_variants.begin (); i != m_variants.end (); ++i) {
if (i->second.size () > 1) {
return true;
}
}
return false;
}
void
VariantStatistics::add_variant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst, bool tl_invariant) const
{
if (tl_invariant) {
add_variant_tl_invariant (variants, inst);
} else {
add_variant_non_tl_invariant (variants, inst);
}
}
void
VariantStatistics::add_variant_non_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const
{
if (inst.is_complex ()) {
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
variants [mp_red->reduce_trans (inst.complex_trans (*i))] += 1;
}
} else {
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
variants [db::ICplxTrans (mp_red->reduce_trans (*i))] += 1;
}
}
}
void
VariantStatistics::add_variant_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const
{
if (inst.is_complex ()) {
variants [mp_red->reduce_trans (inst.complex_trans ())] += inst.size ();
} else {
variants [db::ICplxTrans (mp_red->reduce_trans (inst.front ()))] += inst.size ();
}
}
void
VariantStatistics::product (const std::map<db::ICplxTrans, size_t> &v1, const std::map<db::ICplxTrans, size_t> &v2, std::map<db::ICplxTrans, size_t> &prod) const
{
for (std::map<db::ICplxTrans, size_t>::const_iterator i = v1.begin (); i != v1.end (); ++i) {
for (std::map<db::ICplxTrans, size_t>::const_iterator j = v2.begin (); j != v2.end (); ++j) {
prod [mp_red->reduce (i->first * j->first)] += i->second * j->second;
}
}
}
}

View File

@ -54,6 +54,7 @@ public:
virtual db::ICplxTrans reduce_trans (const db::ICplxTrans &trans) const { return reduce (trans); }
virtual db::Trans reduce (const db::Trans &trans) const = 0;
virtual db::ICplxTrans reduce (const db::ICplxTrans &trans) const = 0;
virtual bool equals (const TransformationReducer *other) const = 0;
virtual bool is_translation_invariant () const { return true; }
};
@ -67,6 +68,7 @@ struct DB_PUBLIC OrientationReducer
{
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
db::Trans reduce (const db::Trans &trans) const;
virtual bool equals (const TransformationReducer *other) const;
};
/**
@ -77,6 +79,7 @@ struct DB_PUBLIC OrthogonalTransformationReducer
{
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
db::Trans reduce (const db::Trans &trans) const;
virtual bool equals (const TransformationReducer *other) const;
};
/**
@ -89,6 +92,7 @@ struct DB_PUBLIC MagnificationReducer
{
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
db::Trans reduce (const db::Trans &) const;
virtual bool equals (const TransformationReducer *other) const;
};
/**
@ -101,6 +105,7 @@ struct DB_PUBLIC XYAnisotropyAndMagnificationReducer
{
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
db::Trans reduce (const db::Trans &trans) const;
virtual bool equals (const TransformationReducer *other) const;
};
/**
@ -113,6 +118,7 @@ struct DB_PUBLIC MagnificationAndOrientationReducer
{
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
db::Trans reduce (const db::Trans &trans) const;
virtual bool equals (const TransformationReducer *other) const;
};
/**
@ -127,6 +133,7 @@ struct DB_PUBLIC GridReducer
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
db::Trans reduce (const db::Trans &trans) const;
virtual bool equals (const TransformationReducer *other) const;
bool is_translation_invariant () const { return false; }
@ -150,6 +157,7 @@ struct DB_PUBLIC ScaleAndGridReducer
virtual db::Trans reduce_trans (const db::Trans &trans) const;
virtual db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
virtual db::Trans reduce (const db::Trans &trans) const;
virtual bool equals (const TransformationReducer *other) const;
bool is_translation_invariant () const { return false; }
@ -180,7 +188,7 @@ public:
/**
* @brief Collects cell variants for the given layout starting from the top cell
*/
void collect (const db::Layout &layout, const db::Cell &top_cell);
void collect (Layout *layout, cell_index_type initial_cell);
/**
* @brief Creates cell variants for singularization of the different variants
@ -191,7 +199,7 @@ public:
* If given, *var_table will be filled with a map giving the new cell and variant against
* the old cell for all cells with more than one variant.
*/
void separate_variants (db::Layout &layout, db::Cell &top_cell, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_table = 0);
void separate_variants (std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_table = 0);
/**
* @brief Commits the shapes for different variants to the current cell hierarchy
@ -200,7 +208,7 @@ public:
* "to_commit" initially is a set of shapes to commit for the given cell and variant.
* This map is modified during the algorithm and should be discarded later.
*/
void commit_shapes (db::Layout &layout, db::Cell &top_cell, unsigned int layer, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_commit);
void commit_shapes (unsigned int layer, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_commit);
/**
* @brief Gets the variants for a given cell
@ -208,7 +216,15 @@ public:
* The keys of the map are the variants, the values is the instance count of the variant
* (as seen from the top cell).
*/
const std::map<db::ICplxTrans, size_t> &variants (db::cell_index_type ci) const;
const std::set<db::ICplxTrans> &variants (db::cell_index_type ci) const;
/**
* @brief Gets the transformation for a single variant
*
* This requires the cell not to be a variant (i.e. already separated).
* It returns the corresponding transformation.
*/
const db::ICplxTrans &single_variant_transformation (db::cell_index_type ci) const;
/**
* @brief Returns true, if variants have been built
@ -221,13 +237,15 @@ public:
static void copy_shapes (db::Layout &layout, db::cell_index_type ci_to, db::cell_index_type ci_from);
private:
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> > m_variants;
std::map<db::cell_index_type, std::set<db::ICplxTrans> > m_variants;
std::set<db::cell_index_type> m_called;
const TransformationReducer *mp_red;
db::Layout *mp_layout;
void add_variant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst, bool tl_invariant) const;
void add_variant_non_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const;
void add_variant_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const;
void product (const std::map<db::ICplxTrans, size_t> &v1, const std::map<db::ICplxTrans, size_t> &v2, std::map<db::ICplxTrans, size_t> &prod) const;
void add_variant (std::set<ICplxTrans> &variants, const db::CellInstArray &inst, bool tl_invariant) const;
void add_variant_non_tl_invariant (std::set<db::ICplxTrans> &variants, const db::CellInstArray &inst) const;
void add_variant_tl_invariant (std::set<ICplxTrans> &variants, const db::CellInstArray &inst) const;
void product (const std::set<db::ICplxTrans> &v1, const std::set<db::ICplxTrans> &v2, std::set<db::ICplxTrans> &prod) const;
void create_var_instances (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table, bool tl_invariant) const;
void create_var_instances_non_tl_invariant (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table) const;
void create_var_instances_tl_invariant (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table) const;
@ -265,6 +283,86 @@ private:
RED m_red;
};
/**
* @brief A class computing variants for cells with statistics
*
* This version provides detailed information about the multiplicity of a certain variant.
* It does not offer a way to seperate variants.
*/
class DB_PUBLIC VariantStatistics
{
public:
/**
* @brief Creates a variant collector without a transformation reducer
*/
VariantStatistics ();
/**
* @brief Creates a variant collector with the given reducer
*/
VariantStatistics (const TransformationReducer *red);
/**
* @brief Collects cell variants for the given layout starting from the top cell
*/
void collect (const db::Layout *layout, db::cell_index_type initial_cell);
/**
* @brief Gets the variants for a given cell
*
* The keys of the map are the variants, the values is the instance count of the variant
* (as seen from the top cell).
*/
const std::map<db::ICplxTrans, size_t> &variants (db::cell_index_type ci) const;
/**
* @brief Returns true, if variants have been built
*/
bool has_variants () const;
private:
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> > m_variants;
const TransformationReducer *mp_red;
void add_variant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst, bool tl_invariant) const;
void add_variant_non_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const;
void add_variant_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const;
void product (const std::map<db::ICplxTrans, size_t> &v1, const std::map<db::ICplxTrans, size_t> &v2, std::map<db::ICplxTrans, size_t> &prod) const;
};
/**
* @brief A template using a specific transformation reducer
*/
template <class RED>
class DB_PUBLIC_TEMPLATE cell_variants_statistics
: public VariantStatistics
{
public:
/**
* @brief Creates a variant statistics without a transformation reducer
*/
cell_variants_statistics ()
: VariantStatistics (&m_red)
{
// .. nothing yet ..
}
/**
* @brief Creates a variant statistics with the given reducer
*
* The statistics object will take ownership over the reducer
*/
cell_variants_statistics (const RED &red)
: VariantStatistics (&m_red), m_red (red)
{
// .. nothing yet ..
}
private:
RED m_red;
};
} // namespace db
#endif

View File

@ -106,20 +106,20 @@ static void translate (db::Layout *, const std::vector<std::unordered_set<db::Po
}
void
CompoundRegionOperationNode::compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionOperationNode::compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
std::vector<std::unordered_set<db::Polygon> > intermediate;
intermediate.push_back (std::unordered_set<db::Polygon> ());
implement_compute_local (cache, layout, interactions, intermediate, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, intermediate, proc);
translate (layout, intermediate, results);
}
void
CompoundRegionOperationNode::compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionOperationNode::compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *proc) const
{
std::vector<std::unordered_set<db::PolygonRef> > intermediate;
intermediate.push_back (std::unordered_set<db::PolygonRef> ());
implement_compute_local (cache, layout, interactions, intermediate, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, intermediate, proc);
translate (layout, intermediate, results);
}
@ -142,14 +142,14 @@ std::vector<db::Region *> CompoundRegionOperationPrimaryNode::inputs () const
return is;
}
void CompoundRegionOperationPrimaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t, double) const
void CompoundRegionOperationPrimaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *) const
{
for (shape_interactions<db::Polygon, db::Polygon>::subject_iterator i = interactions.begin_subjects (); i != interactions.end_subjects (); ++i) {
results.front ().insert (i->second);
}
}
void CompoundRegionOperationPrimaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t, double) const
void CompoundRegionOperationPrimaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *) const
{
for (shape_interactions<db::PolygonRef, db::PolygonRef>::subject_iterator i = interactions.begin_subjects (); i != interactions.end_subjects (); ++i) {
results.front ().insert (i->second);
@ -177,14 +177,14 @@ std::vector<db::Region *> CompoundRegionOperationSecondaryNode::inputs () const
return iv;
}
void CompoundRegionOperationSecondaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t, double) const
void CompoundRegionOperationSecondaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *) const
{
for (shape_interactions<db::Polygon, db::Polygon>::intruder_iterator i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
results.front ().insert (i->second.second);
}
}
void CompoundRegionOperationSecondaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t, double) const
void CompoundRegionOperationSecondaryNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *) const
{
for (shape_interactions<db::PolygonRef, db::PolygonRef>::intruder_iterator i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
results.front ().insert (i->second.second);
@ -211,14 +211,14 @@ std::vector<db::Region *> CompoundRegionOperationForeignNode::inputs () const
return iv;
}
void CompoundRegionOperationForeignNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t, double) const
void CompoundRegionOperationForeignNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *) const
{
for (shape_interactions<db::Polygon, db::Polygon>::intruder_iterator i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
results.front ().insert (i->second.second);
}
}
void CompoundRegionOperationForeignNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t, double) const
void CompoundRegionOperationForeignNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *) const
{
for (shape_interactions<db::PolygonRef, db::PolygonRef>::intruder_iterator i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
results.front ().insert (i->second.second);
@ -236,7 +236,16 @@ void
CompoundTransformationReducer::add (const db::TransformationReducer *reducer)
{
if (reducer) {
// do not add the same reducer twice
for (auto v = m_vars.begin (); v != m_vars.end (); ++v) {
if (reducer->equals (*v)) {
return;
}
}
m_vars.push_back (reducer);
}
}
@ -245,7 +254,7 @@ CompoundTransformationReducer::reduce_trans (const db::Trans &trans) const
{
db::Trans t = trans;
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
(*v)->reduce_trans (t);
t = (*v)->reduce_trans (t);
}
return t;
}
@ -255,7 +264,7 @@ CompoundTransformationReducer::reduce_trans (const db::ICplxTrans &trans) const
{
db::ICplxTrans t = trans;
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
(*v)->reduce_trans (t);
t = (*v)->reduce_trans (t);
}
return t;
}
@ -265,7 +274,7 @@ CompoundTransformationReducer::reduce (const db::Trans &trans) const
{
db::Trans t = trans;
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
(*v)->reduce (t);
t = (*v)->reduce (t);
}
return t;
}
@ -275,7 +284,7 @@ CompoundTransformationReducer::reduce (const db::ICplxTrans &trans) const
{
db::ICplxTrans t = trans;
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
(*v)->reduce (t);
t = (*v)->reduce (t);
}
return t;
}
@ -403,7 +412,7 @@ CompoundRegionMultiInputOperationNode::child (unsigned int index) const
const TransformationReducer *
CompoundRegionMultiInputOperationNode::vars () const
{
return (m_vars.is_empty () ? &m_vars : 0);
return (m_vars.is_empty () ? 0 : &m_vars);
}
bool
@ -446,7 +455,7 @@ std::string CompoundRegionLogicalBoolOperationNode::generated_description () con
}
template <class T>
void CompoundRegionLogicalBoolOperationNode::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const
void CompoundRegionLogicalBoolOperationNode::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, const db::LocalProcessorBase *proc) const
{
bool ok = (m_op == And ? true : false);
@ -459,7 +468,7 @@ void CompoundRegionLogicalBoolOperationNode::implement_compute_local (CompoundRe
const CompoundRegionOperationNode *node = child (ci);
bool any = node->compute_local_bool<T> (cache, layout, child_interactions, max_vertex_count, area_ratio);
bool any = node->compute_local_bool<T> (cache, layout, cell, child_interactions, proc);
if (m_op == And) {
if (! any) {
@ -743,13 +752,13 @@ static void copy_results (std::vector<std::unordered_set<R> > &, const std::vect
template <class T, class T1, class T2, class TR>
void
CompoundRegionGeometricalBoolOperationNode::implement_bool (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionGeometricalBoolOperationNode::implement_bool (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
{
std::vector<std::unordered_set<T1> > one_a;
one_a.push_back (std::unordered_set<T1> ());
shape_interactions<T, T> computed_a;
child (0)->compute_local (cache, layout, interactions_for_child (interactions, 0, computed_a), one_a, max_vertex_count, area_ratio);
child (0)->compute_local (cache, layout, cell, interactions_for_child (interactions, 0, computed_a), one_a, proc);
if (one_a.front ().empty ()) {
@ -763,7 +772,7 @@ CompoundRegionGeometricalBoolOperationNode::implement_bool (CompoundRegionOperat
one_b.push_back (std::unordered_set<T2> ());
shape_interactions<T, T> computed_b;
child (1)->compute_local (cache, layout, interactions_for_child (interactions, 1, computed_b), one_b, max_vertex_count, area_ratio);
child (1)->compute_local (cache, layout, cell, interactions_for_child (interactions, 1, computed_b), one_b, proc);
copy_results (results, one_b);
@ -775,7 +784,7 @@ CompoundRegionGeometricalBoolOperationNode::implement_bool (CompoundRegionOperat
one_b.push_back (std::unordered_set<T2> ());
shape_interactions<T, T> computed_b;
child (1)->compute_local (cache, layout, interactions_for_child (interactions, 1, computed_b), one_b, max_vertex_count, area_ratio);
child (1)->compute_local (cache, layout, cell, interactions_for_child (interactions, 1, computed_b), one_b, proc);
if (one_b.front ().empty ()) {
@ -794,44 +803,44 @@ CompoundRegionGeometricalBoolOperationNode::implement_bool (CompoundRegionOperat
template <class T, class TR>
void
CompoundRegionGeometricalBoolOperationNode::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionGeometricalBoolOperationNode::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
{
ResultType res_a = child (0)->result_type ();
ResultType res_b = child (1)->result_type ();
if (res_a == Region && res_b == Region) {
implement_bool<T, T, T, TR> (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_bool<T, T, T, TR> (cache, layout, cell, interactions, results, proc);
} else if (res_a == Region && res_b == Edges) {
implement_bool<T, T, db::Edge, TR> (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_bool<T, T, db::Edge, TR> (cache, layout, cell, interactions, results, proc);
} else if (res_a == Edges && res_b == Region) {
implement_bool<T, db::Edge, T, TR> (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_bool<T, db::Edge, T, TR> (cache, layout, cell, interactions, results, proc);
} else if (res_a == Edges && res_b == Edges) {
implement_bool<T, db::Edge, db::Edge, TR> (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_bool<T, db::Edge, db::Edge, TR> (cache, layout, cell, interactions, results, proc);
}
}
void
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionGeometricalBoolOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
// ---------------------------------------------------------------------------------------------
@ -900,7 +909,7 @@ namespace
template <class TS, class TI, class TR>
template <class TTS, class TTI, class TTR>
void compound_region_generic_operation_node<TS, TI, TR>::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<TTS, TTI> &interactions, std::vector<std::unordered_set<TTR> > &results, size_t max_vertex_count, double area_ratio) const
void compound_region_generic_operation_node<TS, TI, TR>::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<TTS, TTI> &interactions, std::vector<std::unordered_set<TTR> > &results, const db::LocalProcessorBase *proc) const
{
generic_result_adaptor <TTR> adaptor (&results);
@ -917,7 +926,7 @@ void compound_region_generic_operation_node<TS, TI, TR>::implement_compute_local
shape_interactions<TTS, TTI> self_interactions_heap;
const shape_interactions<TTS, TTI> &self_interactions = interactions_for_child (interactions, 0, self_interactions_heap);
self->compute_local (cache, layout, self_interactions, self_result, max_vertex_count, area_ratio);
self->compute_local (cache, layout, cell, self_interactions, self_result, proc);
db::generic_shape_iterator <TS> is (self_result.front ().begin (), self_result.front ().end ());
@ -934,7 +943,7 @@ void compound_region_generic_operation_node<TS, TI, TR>::implement_compute_local
shape_interactions<TTS, TTI> intruder_interactions_heap;
const shape_interactions<TTS, TTI> &intruder_interactions = interactions_for_child (interactions, ci, intruder_interactions_heap);
intruder->compute_local (cache, layout, intruder_interactions, intruder_result, max_vertex_count, area_ratio);
intruder->compute_local (cache, layout, cell, intruder_interactions, intruder_result, proc);
intruder_results.push_back (std::unordered_set<TI> ());
intruder_results.back ().swap (intruder_result.front ());
@ -943,21 +952,21 @@ void compound_region_generic_operation_node<TS, TI, TR>::implement_compute_local
}
db::local_processor <TS, TI, TR> proc (layout);
proc.run_flat (is, iiv, std::vector<bool> (), m_op, adaptor.results ());
db::local_processor <TS, TI, TR> lproc (layout);
lproc.run_flat (is, iiv, std::vector<bool> (), m_op, adaptor.results ());
adaptor.finish (layout);
}
// explicit instantiations
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::EdgePair> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Edge>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::Edge> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Edge>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, size_t, double) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, const db::LocalProcessorBase *) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, const db::LocalProcessorBase *) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, const db::LocalProcessorBase *) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Polygon, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::EdgePair> > &, const db::LocalProcessorBase *) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, const db::LocalProcessorBase *) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Polygon>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, const db::LocalProcessorBase *) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Edge>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::Edge> > &, const db::LocalProcessorBase *) const;
template DB_PUBLIC void compound_region_generic_operation_node<db::Polygon, db::Edge, db::Edge>::implement_compute_local (db::CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, const db::LocalProcessorBase *) const;
// ---------------------------------------------------------------------------------------------
@ -990,7 +999,7 @@ CompoundRegionLogicalCaseSelectOperationNode::result_type () const
}
template <class T, class TR>
void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
{
bool ok = false;
@ -1005,7 +1014,7 @@ void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::
if (ci + 1 < children ()) {
ok = node->compute_local_bool<T> (cache, layout, child_interactions, max_vertex_count, area_ratio);
ok = node->compute_local_bool<T> (cache, layout, cell, child_interactions, proc);
continue;
} else {
@ -1021,12 +1030,12 @@ void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::
std::vector<std::unordered_set<TR> > one;
one.push_back (std::unordered_set<TR> ());
node->compute_local (cache, layout, child_interactions, one, max_vertex_count, area_ratio);
node->compute_local (cache, layout, cell, child_interactions, one, proc);
results[ci / 2].swap (one.front ());
} else {
node->compute_local (cache, layout, child_interactions, results, max_vertex_count, area_ratio);
node->compute_local (cache, layout, cell, child_interactions, results, proc);
}
@ -1038,12 +1047,12 @@ void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::
}
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::Polygon, db::Polygon> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, size_t, double) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::PolygonRef, db::PolygonRef> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, size_t, double) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::Polygon, db::Edge> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, size_t, double) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::PolygonRef, db::Edge> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::Edge> > &, size_t, double) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::Polygon, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::EdgePair> > &, size_t, double) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::PolygonRef, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::EdgePair> > &, size_t, double) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::Polygon, db::Polygon> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::PolygonRef, db::PolygonRef> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::Polygon, db::Edge> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::PolygonRef, db::Edge> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::Edge> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::Polygon, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::EdgePair> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local<db::PolygonRef, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::EdgePair> > &, const db::LocalProcessorBase *) const;
// ---------------------------------------------------------------------------------------------
@ -1145,24 +1154,24 @@ CompoundRegionJoinOperationNode::result_type () const
}
template <class T, class TR>
void CompoundRegionJoinOperationNode::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
void CompoundRegionJoinOperationNode::implement_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
{
for (unsigned int ci = 0; ci < children (); ++ci) {
shape_interactions<T, T> computed;
const shape_interactions<T, T> &child_interactions = interactions_for_child<T, T> (interactions, ci, computed);
child (ci)->compute_local (cache, layout, child_interactions, results, max_vertex_count, area_ratio);
child (ci)->compute_local (cache, layout, cell, child_interactions, results, proc);
}
}
template void CompoundRegionJoinOperationNode::implement_compute_local<db::Polygon, db::Polygon> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, size_t, double) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::PolygonRef, db::PolygonRef> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, size_t, double) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::Polygon, db::Edge> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, size_t, double) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::PolygonRef, db::Edge> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::Edge> > &, size_t, double) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::Polygon, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::EdgePair> > &, size_t, double) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::PolygonRef, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::EdgePair> > &, size_t, double) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::Polygon, db::Polygon> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Polygon> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::PolygonRef, db::PolygonRef> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::PolygonRef> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::Polygon, db::Edge> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::Edge> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::PolygonRef, db::Edge> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::Edge> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::Polygon, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::Polygon, db::Polygon> &, std::vector<std::unordered_set<db::EdgePair> > &, const db::LocalProcessorBase *) const;
template void CompoundRegionJoinOperationNode::implement_compute_local<db::PolygonRef, db::EdgePair> (CompoundRegionOperationCache *, db::Layout *, db::Cell *, const shape_interactions<db::PolygonRef, db::PolygonRef> &, std::vector<std::unordered_set<db::EdgePair> > &, const db::LocalProcessorBase *) const;
// ---------------------------------------------------------------------------------------------
@ -1181,15 +1190,15 @@ CompoundRegionFilterOperationNode::~CompoundRegionFilterOperationNode ()
}
void
CompoundRegionFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
// ---------------------------------------------------------------------------------------------
@ -1209,15 +1218,15 @@ CompoundRegionEdgeFilterOperationNode::~CompoundRegionEdgeFilterOperationNode ()
}
void
CompoundRegionEdgeFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgeFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionEdgeFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgeFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
// ---------------------------------------------------------------------------------------------
@ -1237,15 +1246,15 @@ CompoundRegionEdgePairFilterOperationNode::~CompoundRegionEdgePairFilterOperatio
}
void
CompoundRegionEdgePairFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgePairFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionEdgePairFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgePairFilterOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
bool
@ -1271,15 +1280,15 @@ CompoundRegionProcessingOperationNode::~CompoundRegionProcessingOperationNode ()
}
void
CompoundRegionProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
@ -1298,6 +1307,34 @@ CompoundRegionProcessingOperationNode::processed (db::Layout *layout, const db::
}
}
void
CompoundRegionProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, const db::ICplxTrans &tr, std::vector<db::Polygon> &res) const
{
size_t n = res.size ();
mp_proc->process (tr * p, res);
if (res.size () > n) {
db::ICplxTrans tri = tr.inverted ();
for (auto p = res.begin () + n; p != res.end (); ++p) {
p->transform (tri);
}
}
}
void
CompoundRegionProcessingOperationNode::processed (db::Layout *layout, const db::PolygonRef &p, const db::ICplxTrans &tr, std::vector<db::PolygonRef> &res) const
{
std::vector<db::Polygon> poly;
mp_proc->process (p.obj ().transformed (p.trans ()).transformed (tr), poly);
if (! poly.empty ()) {
db::ICplxTrans tri = tr.inverted ();
for (std::vector<db::Polygon>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
res.push_back (db::PolygonRef (tri * *p, layout->shape_repository ()));
}
}
}
// ---------------------------------------------------------------------------------------------
CompoundRegionToEdgeProcessingOperationNode::CompoundRegionToEdgeProcessingOperationNode (PolygonToEdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc)
@ -1315,15 +1352,15 @@ CompoundRegionToEdgeProcessingOperationNode::~CompoundRegionToEdgeProcessingOper
}
void
CompoundRegionToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
@ -1338,6 +1375,34 @@ CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::
mp_proc->process (p.obj ().transformed (p.trans ()), res);
}
void
CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, const db::ICplxTrans &tr, std::vector<db::Edge> &res) const
{
size_t n = res.size ();
mp_proc->process (tr * p, res);
if (res.size () > n) {
db::ICplxTrans tri = tr.inverted ();
for (auto p = res.begin () + n; p != res.end (); ++p) {
p->transform (tri);
}
}
}
void
CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::PolygonRef &p, const db::ICplxTrans &tr, std::vector<db::Edge> &res) const
{
size_t n = res.size ();
mp_proc->process (p.obj ().transformed (p.trans ()).transformed (tr), res);
if (res.size () > n) {
db::ICplxTrans tri = tr.inverted ();
for (auto p = res.begin () + n; p != res.end (); ++p) {
p->transform (tri);
}
}
}
// ---------------------------------------------------------------------------------------------
CompoundRegionEdgeProcessingOperationNode::CompoundRegionEdgeProcessingOperationNode (EdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc)
@ -1355,15 +1420,15 @@ CompoundRegionEdgeProcessingOperationNode::~CompoundRegionEdgeProcessingOperatio
}
void
CompoundRegionEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void CompoundRegionEdgeProcessingOperationNode::processed (db::Layout *, const db::Edge &p, std::vector<db::Edge> &res) const
@ -1388,15 +1453,15 @@ CompoundRegionEdgeToPolygonProcessingOperationNode::~CompoundRegionEdgeToPolygon
}
void
CompoundRegionEdgeToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgeToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionEdgeToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgeToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
@ -1433,15 +1498,15 @@ CompoundRegionToEdgePairProcessingOperationNode::~CompoundRegionToEdgePairProces
}
void
CompoundRegionToEdgePairProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionToEdgePairProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionToEdgePairProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionToEdgePairProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
@ -1456,6 +1521,34 @@ CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const
mp_proc->process (p.obj ().transformed (p.trans ()), res);
}
void
CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, const db::ICplxTrans &tr, std::vector<db::EdgePair> &res) const
{
size_t n = res.size ();
mp_proc->process (tr * p, res);
if (res.size () > n) {
db::ICplxTrans tri = tr.inverted ();
for (auto p = res.begin () + n; p != res.end (); ++p) {
p->transform (tri);
}
}
}
void
CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const db::PolygonRef &p, const db::ICplxTrans &tr, std::vector<db::EdgePair> &res) const
{
size_t n = res.size ();
mp_proc->process (p.obj ().transformed (p.trans ()).transformed (tr), res);
if (res.size () > n) {
db::ICplxTrans tri = tr.inverted ();
for (auto p = res.begin () + n; p != res.end (); ++p) {
p->transform (tri);
}
}
}
// ---------------------------------------------------------------------------------------------
CompoundRegionEdgePairToPolygonProcessingOperationNode::CompoundRegionEdgePairToPolygonProcessingOperationNode (EdgePairToPolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc)
@ -1473,15 +1566,15 @@ CompoundRegionEdgePairToPolygonProcessingOperationNode::~CompoundRegionEdgePairT
}
void
CompoundRegionEdgePairToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgePairToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionEdgePairToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgePairToPolygonProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
@ -1518,15 +1611,15 @@ CompoundRegionEdgePairToEdgeProcessingOperationNode::~CompoundRegionEdgePairToEd
}
void
CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
void
CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (CompoundRegionOperationCache *cache, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase *proc) const
{
implement_compute_local (cache, layout, interactions, results, max_vertex_count, area_ratio);
implement_compute_local (cache, layout, cell, interactions, results, proc);
}
// ---------------------------------------------------------------------------------------------
@ -1591,37 +1684,45 @@ CompoundRegionCheckOperationNode::computed_dist () const
}
void
CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
// consider magnification variants
db::EdgeRelationFilter check = m_check;
check.set_distance (proc->dist_for_cell (cell, check.distance ()));
// TODO: needs a concept to deal with merged/non-merged inputs
bool is_merged = true;
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options);
db::check_local_operation<db::Polygon, db::Polygon> op (check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options);
tl_assert (results.size () == 1);
if (results.front ().empty ()) {
op.do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
op.do_compute_local (layout, cell, interactions, results, proc);
} else {
std::vector<std::unordered_set<db::EdgePair> > r;
r.resize (1);
op.do_compute_local (layout, interactions, r, max_vertex_count, area_ratio);
op.do_compute_local (layout, cell, interactions, r, proc);
results.front ().insert (r.front ().begin (), r.front ().end ());
}
}
void
CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
// consider magnification variants
db::EdgeRelationFilter check = m_check;
check.set_distance (proc->dist_for_cell (cell, check.distance ()));
// TODO: needs a concept to deal with merged/non-merged inputs
bool is_merged = true;
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options);
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options);
tl_assert (results.size () == 1);
if (results.front ().empty ()) {
op.do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
op.do_compute_local (layout, cell, interactions, results, proc);
} else {
std::vector<std::unordered_set<db::EdgePair> > r;
r.resize (1);
op.do_compute_local (layout, interactions, r, max_vertex_count, area_ratio);
op.do_compute_local (layout, cell, interactions, r, proc);
results.front ().insert (r.front ().begin (), r.front ().end ());
}
}

File diff suppressed because it is too large Load Diff

View File

@ -386,21 +386,21 @@ DeepEdgePairs *
DeepEdgePairs::apply_filter (const EdgePairFilterBase &filter) const
{
const db::DeepLayer &edge_pairs = deep_layer ();
db::Layout &layout = const_cast<db::Layout &> (edge_pairs.layout ());
std::unique_ptr<VariantsCollectorBase> vars;
if (filter.vars ()) {
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
vars->collect (edge_pairs.layout (), edge_pairs.initial_cell ());
vars->collect (&layout, edge_pairs.initial_cell ().cell_index ());
if (filter.wants_variants ()) {
const_cast<db::DeepLayer &> (edge_pairs).separate_variants (*vars);
vars->separate_variants ();
}
}
db::Layout &layout = const_cast<db::Layout &> (edge_pairs.layout ());
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
std::unique_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (edge_pairs.derived ()));
@ -410,17 +410,17 @@ DeepEdgePairs::apply_filter (const EdgePairFilterBase &filter) const
if (vars.get ()) {
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars->variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *st;
if (vv.size () == 1) {
st = & c->shapes (res->deep_layer ().layer ());
} else {
st = & to_commit [c->cell_index ()] [v->first];
st = & to_commit [c->cell_index ()] [*v];
}
const db::ICplxTrans &tr = v->first;
const db::ICplxTrans &tr = *v;
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::EdgePairs); ! si.at_end (); ++si) {
if (filter.selected (si->edge_pair ().transformed (tr))) {
@ -445,7 +445,7 @@ DeepEdgePairs::apply_filter (const EdgePairFilterBase &filter) const
}
if (! to_commit.empty () && vars.get ()) {
res->deep_layer ().commit_shapes (*vars, to_commit);
vars->commit_shapes (res->deep_layer ().layer (), to_commit);
}
return res.release ();

View File

@ -244,22 +244,21 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
// Plain move
db::Layout &layout = deep_layer.layout ();
// build cell variants for different orientations
db::OrientationReducer same_orientation;
db::VariantsCollectorBase vars (&same_orientation);
vars.collect (deep_layer.layout (), deep_layer.initial_cell ());
deep_layer.separate_variants (vars);
vars.collect (&layout, deep_layer.initial_cell ().cell_index ());
vars.separate_variants ();
// process the variants
db::Layout &layout = deep_layer.layout ();
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
db::Trans tr (v.begin ()->first.inverted () * t.disp ());
const db::ICplxTrans &tv = vars.single_variant_transformation (c->cell_index ());
db::ICplxTrans tr (tv.inverted () * t.disp ());
db::Shapes &shapes = c->shapes (deep_layer.layer ());
db::Shapes new_shapes (layout.manager (), c.operator-> (), layout.is_editable ());
@ -739,8 +738,8 @@ DeepEdges::length_type DeepEdges::length (const db::Box &box) const
const db::DeepLayer &edges = merged_deep_layer ();
db::MagnificationReducer red;
db::cell_variants_collector<db::MagnificationReducer> vars (red);
vars.collect (edges.layout (), edges.initial_cell ());
db::cell_variants_statistics<db::MagnificationReducer> vars (red);
vars.collect (&edges.layout (), edges.initial_cell ().cell_index ());
DeepEdges::length_type l = 0;
@ -751,7 +750,7 @@ DeepEdges::length_type DeepEdges::length (const db::Box &box) const
lc += s->edge ().length ();
}
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (*c);
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
for (auto v = vv.begin (); v != vv.end (); ++v) {
double mag = v->first.mag ();
l += v->second * lc * mag;
}
@ -812,21 +811,21 @@ DeepEdges *
DeepEdges::apply_filter (const EdgeFilterBase &filter) const
{
const db::DeepLayer &edges = filter.requires_raw_input () ? deep_layer () : merged_deep_layer ();
db::Layout &layout = const_cast<db::Layout &> (edges.layout ());
std::unique_ptr<VariantsCollectorBase> vars;
if (filter.vars ()) {
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
vars->collect (edges.layout (), edges.initial_cell ());
vars->collect (&layout, edges.initial_cell ().cell_index ());
if (filter.wants_variants ()) {
const_cast<db::DeepLayer &> (edges).separate_variants (*vars);
vars->separate_variants ();
}
}
db::Layout &layout = const_cast<db::Layout &> (edges.layout ());
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
std::unique_ptr<db::DeepEdges> res (new db::DeepEdges (edges.derived ()));
@ -836,20 +835,18 @@ DeepEdges::apply_filter (const EdgeFilterBase &filter) const
if (vars.get ()) {
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars->variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *st;
if (vv.size () == 1) {
st = & c->shapes (res->deep_layer ().layer ());
} else {
st = & to_commit [c->cell_index ()] [v->first];
st = & to_commit [c->cell_index ()] [*v];
}
const db::ICplxTrans &tr = v->first;
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
if (filter.selected (si->edge ().transformed (tr))) {
if (filter.selected (si->edge ().transformed (*v))) {
st->insert (*si);
}
}
@ -871,7 +868,7 @@ DeepEdges::apply_filter (const EdgeFilterBase &filter) const
}
if (! to_commit.empty () && vars.get ()) {
res->deep_layer ().commit_shapes (*vars, to_commit);
vars->commit_shapes (res->deep_layer ().layer (), to_commit);
}
if (! filter.requires_raw_input ()) {
@ -1262,7 +1259,7 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
// dots formally don't have an orientation, hence the interpretation is x and y.
db::MagnificationReducer red;
db::cell_variants_collector<db::MagnificationReducer> vars (red);
vars.collect (edges.layout (), edges.initial_cell ());
vars.collect (&layout, edges.initial_cell ().cell_index ());
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
@ -1279,14 +1276,14 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
// TODO: iterate only over the called cells?
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars.variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *out;
if (vv.size () == 1) {
out = & c->shapes (res->deep_layer ().layer ());
} else {
out = & to_commit [c->cell_index ()][v->first];
out = & to_commit [c->cell_index ()][*v];
}
const db::connected_clusters<db::Edge> &cc = hc.clusters_per_cell (c->cell_index ());
@ -1295,12 +1292,12 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
if (cc.is_root (*cl)) {
PolygonRefToShapesGenerator prgen (&layout, out);
polygon_transformation_filter<db::ICplxTrans> ptrans (&prgen, v->first.inverted ());
polygon_transformation_filter<db::ICplxTrans> ptrans (&prgen, v->inverted ());
JoinEdgesCluster jec (&ptrans, ext_b, ext_e, ext_o, ext_i);
std::list<db::Edge> heap;
for (db::recursive_cluster_shape_iterator<db::Edge> rcsi (hc, edges.layer (), c->cell_index (), *cl); ! rcsi.at_end (); ++rcsi) {
heap.push_back (rcsi->transformed (v->first * rcsi.trans ()));
heap.push_back (rcsi->transformed (*v * rcsi.trans ()));
jec.add (&heap.back (), 0);
}
@ -1318,20 +1315,20 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars.variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *out;
if (vv.size () == 1) {
out = & c->shapes (res->deep_layer ().layer ());
} else {
out = & to_commit [c->cell_index ()][v->first];
out = & to_commit [c->cell_index ()][*v];
}
PolygonRefToShapesGenerator prgen (&layout, out);
for (db::Shapes::shape_iterator si = c->shapes (edges.layer ()).begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
prgen.set_prop_id (si->prop_id ());
prgen.put (extended_edge (si->edge ().transformed (v->first), ext_b, ext_e, ext_o, ext_i).transformed (v->first.inverted ()));
prgen.put (extended_edge (si->edge ().transformed (*v), ext_b, ext_e, ext_o, ext_i).transformed (v->inverted ()));
}
}
@ -1341,7 +1338,7 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
}
// propagate results from variants
vars.commit_shapes (layout, top_cell, res->deep_layer ().layer (), to_commit);
vars.commit_shapes (res->deep_layer ().layer (), to_commit);
return res.release ();
}
@ -1367,7 +1364,7 @@ public:
return 1;
}
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == (m_output_mode == Both ? 2 : 1));
@ -1460,7 +1457,7 @@ public:
return 1;
}
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front ();
@ -1517,7 +1514,7 @@ public:
return 1;
}
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == size_t (m_output_mode == Both ? 2 : 1));
@ -1657,7 +1654,7 @@ public:
return 1;
}
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
@ -1941,12 +1938,16 @@ public:
// .. nothing yet ..
}
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell *cell, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::EdgePair> &result = results.front ();
edge2edge_check_for_edges<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_has_other);
// implement check in local coordinates in the presence of magnification variants
EdgeRelationFilter check = m_check;
check.set_distance (proc->dist_for_cell (cell, check.distance ()));
edge2edge_check_for_edges<std::unordered_set<db::EdgePair> > edge_check (check, result, m_has_other);
db::box_scanner<db::Edge, size_t> scanner;
std::set<db::Edge> others;
@ -1989,7 +1990,7 @@ public:
}
scanner.process (edge_check, m_check.distance (), db::box_convert<db::Edge> ());
scanner.process (edge_check, check.distance (), db::box_convert<db::Edge> ());
}
virtual db::Coord dist () const
@ -2008,9 +2009,15 @@ public:
return tl::to_string (tr ("Generic DRC check"));
}
virtual const db::TransformationReducer *vars () const
{
return &m_vars;
}
private:
EdgeRelationFilter m_check;
bool m_has_other;
db::MagnificationReducer m_vars;
};
}

View File

@ -256,18 +256,16 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
db::MagnificationAndOrientationReducer same_orientation;
db::VariantsCollectorBase vars (&same_orientation);
vars.collect (deep_layer.layout (), deep_layer.initial_cell ());
deep_layer.separate_variants (vars);
vars.collect (&deep_layer.layout (), deep_layer.initial_cell ().cell_index ());
vars.separate_variants ();
// process the variants
db::Layout &layout = deep_layer.layout ();
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
db::Trans tr (v.begin ()->first.inverted () * t.disp ());
const db::ICplxTrans &tv = vars.single_variant_transformation (c->cell_index ());
db::ICplxTrans tr (tv.inverted () * t.disp ());
db::Shapes &shapes = c->shapes (deep_layer.layer ());
db::Shapes new_shapes (layout.manager (), c.operator-> (), layout.is_editable ());
@ -1111,8 +1109,8 @@ DeepRegion::area (const db::Box &box) const
const db::DeepLayer &polygons = merged_deep_layer ();
db::cell_variants_collector<db::MagnificationReducer> vars;
vars.collect (polygons.layout (), polygons.initial_cell ());
db::cell_variants_statistics<db::MagnificationReducer> vars;
vars.collect (&polygons.layout (), polygons.initial_cell ().cell_index ());
DeepRegion::area_type a = 0;
@ -1123,7 +1121,7 @@ DeepRegion::area (const db::Box &box) const
ac += s->area ();
}
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (*c);
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
for (auto v = vv.begin (); v != vv.end (); ++v) {
double mag = v->first.mag ();
a += v->second * ac * mag * mag;
}
@ -1148,8 +1146,8 @@ DeepRegion::perimeter (const db::Box &box) const
const db::DeepLayer &polygons = merged_deep_layer ();
db::cell_variants_collector<db::MagnificationReducer> vars;
vars.collect (polygons.layout (), polygons.initial_cell ());
db::cell_variants_statistics<db::MagnificationReducer> vars;
vars.collect (&polygons.layout (), polygons.initial_cell ().cell_index ());
DeepRegion::perimeter_type p = 0;
@ -1160,7 +1158,7 @@ DeepRegion::perimeter (const db::Box &box) const
pc += s->perimeter ();
}
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (*c);
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
for (auto v = vv.begin (); v != vv.end (); ++v) {
double mag = v->first.mag ();
p += v->second * pc * mag;
}
@ -1210,7 +1208,7 @@ DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
db::cell_variants_collector<db::GridReducer> vars (gx);
vars.collect (layout, polygons.initial_cell ());
vars.collect (&layout, polygons.initial_cell ().cell_index ());
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
std::unique_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (polygons.derived ()));
@ -1219,14 +1217,14 @@ DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
const db::Shapes &shapes = c->shapes (polygons.layer ());
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars.variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *markers;
if (vv.size () == 1) {
markers = & c->shapes (res->deep_layer ().layer ());
} else {
markers = & to_commit [c->cell_index ()] [v->first];
markers = & to_commit [c->cell_index ()] [*v];
}
for (db::Shapes::shape_iterator si = shapes.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
@ -1234,7 +1232,7 @@ DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
db::Polygon poly;
si->polygon (poly);
AsIfFlatRegion::produce_markers_for_grid_check (poly, v->first, gx, gy, *markers);
AsIfFlatRegion::produce_markers_for_grid_check (poly, *v, gx, gy, *markers);
}
@ -1243,7 +1241,7 @@ DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
}
// propagate the markers with a similar algorithm used for producing the variants
res->deep_layer ().commit_shapes (vars, to_commit);
vars.commit_shapes (res->deep_layer ().layer (), to_commit);
return res.release ();
}
@ -1297,23 +1295,19 @@ DeepRegion::snapped (db::Coord gx, db::Coord gy)
}
const db::DeepLayer &polygons = merged_deep_layer ();
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
db::cell_variants_collector<db::GridReducer> vars (gx);
vars.collect (polygons.layout (), polygons.initial_cell ());
vars.collect (&layout, polygons.initial_cell ().cell_index ());
vars.separate_variants ();
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
const_cast<db::DeepLayer &> (polygons).separate_variants (vars);
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
std::vector<db::Point> heap;
std::unique_ptr<db::DeepRegion> res (new db::DeepRegion (polygons.derived ()));
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
const db::ICplxTrans &tr = v.begin ()->first;
const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ());
db::ICplxTrans trinv = tr.inverted ();
const db::Shapes &s = c->shapes (polygons.layer ());
@ -1367,27 +1361,22 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
db::PropertyMapper pm (res->properties_repository (), &polygons.layout ().properties_repository ());
std::unique_ptr<VariantsCollectorBase> vars;
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
if (filter && filter->vars ()) {
vars.reset (new db::VariantsCollectorBase (filter->vars ()));
vars->collect (polygons.layout (), polygons.initial_cell ());
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
const_cast<db::DeepLayer &> (polygons).separate_variants (*vars);
vars->collect (&layout, polygons.initial_cell ().cell_index ());
vars->separate_variants ();
}
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
db::ICplxTrans tr;
if (vars.get ()) {
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
tr = v.begin ()->first;
tr = vars->single_variant_transformation (c->cell_index ());
}
const db::Shapes &s = c->shapes (polygons.layer ());
@ -1482,21 +1471,21 @@ DeepRegion *
DeepRegion::apply_filter (const PolygonFilterBase &filter) const
{
const db::DeepLayer &polygons = filter.requires_raw_input () ? deep_layer () : merged_deep_layer ();
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
std::unique_ptr<VariantsCollectorBase> vars;
if (filter.vars ()) {
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
vars->collect (polygons.layout (), polygons.initial_cell ());
vars->collect (&layout, polygons.initial_cell ().cell_index ());
if (filter.wants_variants ()) {
const_cast<db::DeepLayer &> (polygons).separate_variants (*vars);
vars->separate_variants ();
}
}
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
std::unique_ptr<db::DeepRegion> res (new db::DeepRegion (polygons.derived ()));
@ -1506,22 +1495,20 @@ DeepRegion::apply_filter (const PolygonFilterBase &filter) const
if (vars.get ()) {
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars->variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *st;
if (vv.size () == 1) {
st = & c->shapes (res->deep_layer ().layer ());
} else {
st = & to_commit [c->cell_index ()] [v->first];
st = & to_commit [c->cell_index ()] [*v];
}
const db::ICplxTrans &tr = v->first;
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
db::Polygon poly;
si->polygon (poly);
if (filter.selected (poly.transformed (tr))) {
if (filter.selected (poly.transformed (*v))) {
st->insert (*si);
}
}
@ -1545,7 +1532,7 @@ DeepRegion::apply_filter (const PolygonFilterBase &filter) const
}
if (! to_commit.empty () && vars.get ()) {
res->deep_layer ().commit_shapes (*vars, to_commit);
vars->commit_shapes (res->deep_layer ().layer (), to_commit);
}
if (! filter.requires_raw_input ()) {
@ -1655,17 +1642,14 @@ DeepRegion::sized (coord_type d, unsigned int mode) const
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
db::cell_variants_collector<db::MagnificationReducer> vars;
vars.collect (polygons.layout (), polygons.initial_cell ());
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
const_cast<db::DeepLayer &> (polygons).separate_variants (vars);
vars.collect (&layout, polygons.initial_cell ().cell_index ());
vars.separate_variants ();
std::unique_ptr<db::DeepRegion> res (new db::DeepRegion (polygons.derived ()));
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
double mag = v.begin ()->first.mag ();
const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ());
double mag = tr.mag ();
db::Coord d_with_mag = db::coord_traits<db::Coord>::rounded (d / mag);
const db::Shapes &s = c->shapes (polygons.layer ());
@ -1711,18 +1695,15 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
db::cell_variants_collector<db::XYAnisotropyAndMagnificationReducer> vars;
vars.collect (polygons.layout (), polygons.initial_cell ());
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
const_cast<db::DeepLayer &> (polygons).separate_variants (vars);
vars.collect (&layout, polygons.initial_cell ().cell_index ());
vars.separate_variants ();
std::unique_ptr<db::DeepRegion> res (new db::DeepRegion (polygons.derived ()));
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
double mag = v.begin ()->first.mag ();
double angle = v.begin ()->first.angle ();
const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ());
double mag = tr.mag ();
double angle = tr.angle ();
db::Coord dx_with_mag = db::coord_traits<db::Coord>::rounded (dx / mag);
db::Coord dy_with_mag = db::coord_traits<db::Coord>::rounded (dy / mag);
@ -1799,7 +1780,7 @@ Output *region_cop_impl (DeepRegion *region, db::CompoundRegionOperationNode &no
}
compound_local_operation<db::PolygonRef, db::PolygonRef, TR> op (&node);
proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ());
proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer (), true /*make_variants*/);
return res.release ();
}
@ -1852,7 +1833,7 @@ Output *region_cop_with_properties_impl (DeepRegion *region, db::CompoundRegionO
}
compound_local_operation_with_properties<db::PolygonRef, db::PolygonRef, TR> op (&node, prop_constraint, res->properties_repository (), subject_pr, intruder_prs);
proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ());
proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer (), true /*make_variants*/);
return res.release ();
}
@ -2008,19 +1989,26 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c
}
const db::DeepLayer &polygons = merged_deep_layer ();
EdgeRelationFilter check (rel, d, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
db::cell_variants_collector<db::MagnificationReducer> vars;
vars.collect (&layout, polygons.initial_cell ().cell_index ());
vars.separate_variants ();
std::unique_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (polygons.derived ()));
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ());
double mag = tr.mag ();
db::Coord d_with_mag = db::coord_traits<db::Coord>::rounded (d / mag);
EdgeRelationFilter check (rel, d_with_mag, options.metrics);
check.set_include_zero (false);
check.set_whole_edges (options.whole_edges);
check.set_ignore_angle (options.ignore_angle);
check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection);
const db::Shapes &shapes = c->shapes (polygons.layer ());
db::Shapes &result = c->shapes (res->deep_layer ().layer ());

View File

@ -287,8 +287,31 @@ struct DeepShapeStore::LayoutHolder
db::LayoutToNetlist *mp_l2n;
};
class VariantsCreatedListener
: public tl::Object
{
public:
VariantsCreatedListener (DeepShapeStore::LayoutHolder *lh, db::Layout *ly)
: mp_lh (lh)
{
ly->variants_created_event.add (this, &VariantsCreatedListener::variants_created);
}
private:
void variants_created (const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_map)
{
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> >::const_iterator i = var_map->begin (); i != var_map->end (); ++i) {
for (std::map<db::ICplxTrans, db::cell_index_type>::const_iterator j = i->second.begin (); j != i->second.end (); ++j) {
mp_lh->builder.register_variant (i->first, j->second);
}
}
}
DeepShapeStore::LayoutHolder *mp_lh;
};
LayoutHolder (const db::ICplxTrans &trans)
: refs (0), layout (false), builder (&layout, trans)
: refs (0), layout (false), builder (&layout, trans), variants_created (this, &layout)
{
// .. nothing yet ..
}
@ -337,6 +360,9 @@ struct DeepShapeStore::LayoutHolder
int refs;
db::Layout layout;
db::HierarchyBuilder builder;
private:
VariantsCreatedListener variants_created;
std::map<db::LayoutToNetlist *, std::pair<L2NStatusChangedListener, db::NetBuilder> > net_builders;
std::map<unsigned int, int> layer_refs;
};
@ -1048,17 +1074,6 @@ DeepLayer DeepShapeStore::create_text_layer (const db::RecursiveShapeIterator &s
return create_custom_layer (si, &refs, trans);
}
void
DeepShapeStore::issue_variants (unsigned int layout_index, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_map)
{
db::HierarchyBuilder &builder = m_layouts [layout_index]->builder;
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> >::const_iterator i = var_map.begin (); i != var_map.end (); ++i) {
for (std::map<db::ICplxTrans, db::cell_index_type>::const_iterator j = i->second.begin (); j != i->second.end (); ++j) {
builder.register_variant (i->first, j->second);
}
}
}
const db::CellMapping &
DeepShapeStore::internal_cell_mapping (unsigned int into_layout_index, unsigned int from_layout_index)
{

View File

@ -49,6 +49,7 @@ class Texts;
class ShapeCollection;
class NetBuilder;
class LayoutToNetlist;
class VariantsCollectorBase;
/**
* @brief Represents a shape collection from the deep shape store
@ -192,25 +193,6 @@ public:
*/
void add_from (const DeepLayer &dl);
/**
* @brief Separates cell variants (see DeepShapeStore::separate_variants)
*/
template <class VarCollector>
void separate_variants (VarCollector &collector);
/**
* @brief Commits shapes for variants to the existing cell hierarchy
*
* The "to_propagate" collection is a set of shapes per cell and variant. The
* algorithm will put these shapes into the existing hierarchy putting the
* shapes into the proper parent cells to resolve variants.
*
* This map will be modified by the algorithm and should be discarded
* later.
*/
template <class VarCollector>
void commit_shapes (VarCollector &collector, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_propagate);
/**
* @brief Gets the shape store object
* This is a pure const version to prevent manipulation of the store.
@ -555,42 +537,6 @@ public:
*/
const db::CellMapping &internal_cell_mapping (unsigned int from_layout_index, unsigned int into_layout_index);
/**
* @brief Create cell variants from the given variant collector
*
* To use this method, first create a variant collector (db::cell_variant_collector) with the required
* reducer and collect the variants. Then call this method on the desired layout index to create the variants.
*/
template <class VarCollector>
void separate_variants (unsigned int layout_index, VarCollector &coll)
{
tl_assert (is_valid_layout_index (layout_index));
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > var_map;
coll.separate_variants (layout (layout_index), initial_cell (layout_index), &var_map);
if (var_map.empty ()) {
// nothing to do.
return;
}
issue_variants (layout_index, var_map);
}
/**
* @brief Commits shapes for variants to the existing cell hierarchy
*
* To use this method, first create a variant collector (db::cell_variant_collector) with the required
* reducer and collect the variants. Then call this method on the desired layout index to commit the shapes for the
* respective variants.
*/
template <class VarCollector>
void commit_shapes (unsigned int layout_index, VarCollector &coll, unsigned int layer, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_commit)
{
tl_assert (is_valid_layout_index (layout_index));
coll.commit_shapes (layout (layout_index), initial_cell (layout_index), layer, to_commit);
}
/**
* @brief For testing
*/
@ -928,20 +874,6 @@ private:
std::map<std::pair<unsigned int, unsigned int>, CellMappingWithGenerationIds> m_internal_mapping_cache;
};
template <class VarCollector>
void DeepLayer::separate_variants (VarCollector &collector)
{
check_dss ();
mp_store->separate_variants (m_layout, collector);
}
template <class VarCollector>
void DeepLayer::commit_shapes (VarCollector &collector, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_commit)
{
check_dss ();
mp_store->commit_shapes (m_layout, collector, layer (), to_commit);
}
}
#endif

View File

@ -407,21 +407,21 @@ TextsDelegate *DeepTexts::filtered (const TextFilterBase &filter) const
DeepTexts *DeepTexts::apply_filter (const TextFilterBase &filter) const
{
const db::DeepLayer &texts = deep_layer ();
db::Layout &layout = const_cast<db::Layout &> (texts.layout ());
std::unique_ptr<VariantsCollectorBase> vars;
if (filter.vars ()) {
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
vars->collect (texts.layout (), texts.initial_cell ());
vars->collect (&layout, texts.initial_cell ().cell_index ());
if (filter.wants_variants ()) {
const_cast<db::DeepLayer &> (texts).separate_variants (*vars);
vars->separate_variants ();
}
}
db::Layout &layout = const_cast<db::Layout &> (texts.layout ());
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
std::unique_ptr<db::DeepTexts> res (new db::DeepTexts (texts.derived ()));
@ -431,22 +431,20 @@ DeepTexts *DeepTexts::apply_filter (const TextFilterBase &filter) const
if (vars.get ()) {
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars->variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *st;
if (vv.size () == 1) {
st = & c->shapes (res->deep_layer ().layer ());
} else {
st = & to_commit [c->cell_index ()] [v->first];
st = & to_commit [c->cell_index ()] [*v];
}
const db::ICplxTrans &tr = v->first;
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Texts); ! si.at_end (); ++si) {
db::Text text;
si->text (text);
if (filter.selected (text.transformed (tr))) {
if (filter.selected (text.transformed (*v))) {
st->insert (*si);
}
}
@ -470,7 +468,7 @@ DeepTexts *DeepTexts::apply_filter (const TextFilterBase &filter) const
}
if (! to_commit.empty () && vars.get ()) {
res->deep_layer ().commit_shapes (*vars, to_commit);
vars->commit_shapes (res->deep_layer ().layer (), to_commit);
}
return res.release ();
@ -571,7 +569,7 @@ public:
return 1;
}
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::TextRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::TextRef> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::TextRef> &result = results.front ();
@ -670,7 +668,7 @@ public:
return 1;
}
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();

View File

@ -228,6 +228,14 @@ struct DB_PUBLIC EdgeRelationFilter
return m_max_projection;
}
/**
* @brief sets the check distance
*/
void set_distance (distance_type d)
{
m_d = d;
}
/**
* @brief Gets the check distance
*/
@ -236,6 +244,14 @@ struct DB_PUBLIC EdgeRelationFilter
return m_d;
}
/**
* @brief Sets the relation
*/
void set_relation (edge_relation_type r)
{
m_r = r;
}
/**
* @brief Gets the relation
*/

View File

@ -57,7 +57,7 @@ EdgeBoolAndOrNotLocalOperation::description () const
}
void
EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == size_t (m_op == EdgeAndNot ? 2 : 1));
@ -140,7 +140,7 @@ EdgeToPolygonLocalOperation::description () const
}
void
EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == size_t (m_op == EdgePolygonOp::Both ? 2 : 1));

View File

@ -44,7 +44,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation
public:
EdgeBoolAndOrNotLocalOperation (db::EdgeBoolOp op);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *cell, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &result, const db::LocalProcessorBase *proc) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -67,7 +67,7 @@ class DB_PUBLIC EdgeToPolygonLocalOperation
public:
EdgeToPolygonLocalOperation (EdgePolygonOp::mode_t op, bool include_borders);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *cell, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &result, const db::LocalProcessorBase *proc) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;

View File

@ -30,6 +30,7 @@
#include "dbPolygonGenerators.h"
#include "dbLocalOperationUtils.h"
#include "dbShapeFlags.h"
#include "dbCellVariants.h"
#include "tlLog.h"
#include "tlTimer.h"
#include "tlInternational.h"
@ -1142,7 +1143,7 @@ public:
db::Box ref_box = db::box_convert<TS> () (*ref);
for (db::CellInstArray::iterator n = inst->begin_touching (safe_box_enlarged (ref_box, m_dist - 1, m_dist - 1), inst_bc); !n.at_end (); ++n) {
db::ICplxTrans tn = inst->complex_trans (*n);
db::Box region = ref_box.transformed (tn.inverted ()).enlarged (db::Vector (m_dist, m_dist)) & intruder_cell.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist));
db::Box region = ref_box.enlarged (db::Vector (m_dist, m_dist)).transformed (tn.inverted ()) & intruder_cell.bbox (m_intruder_layer);
if (! region.empty ()) {
add_shapes_from_intruder_inst (id1, intruder_cell, tn, inst_id, region);
}
@ -1258,7 +1259,7 @@ private:
db::ICplxTrans tn1 = inst1->complex_trans (*n);
db::ICplxTrans tni1 = tn1.inverted ();
db::Box ibox1 = tn1 * cell1.bbox (m_subject_layer).enlarged (db::Vector (m_dist, m_dist));
db::Box ibox1 = (tn1 * cell1.bbox (m_subject_layer)).enlarged (db::Vector (m_dist, m_dist));
std::set<db::CellInstArray> *insts = 0;
@ -1276,7 +1277,7 @@ private:
db::ICplxTrans tn2 = inst2->complex_trans (*k);
// NOTE: we need to enlarge both subject *and* intruder boxes - either object comes close to intruder or the other way around
db::Box ibox2 = tn2 * cell2.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist));
db::Box ibox2 = (tn2 * cell2.bbox (m_intruder_layer)).enlarged (db::Vector (m_dist, m_dist));
db::Box cbox = ibox1 & ibox2;
if (! cbox.empty () && (cbox == ibox1 || cell1.has_shapes_touching (m_subject_layer, safe_box_enlarged (tni1 * cbox, -1, -1)))) {
@ -1332,7 +1333,7 @@ private:
db::ICplxTrans it = i->complex_trans (*ia);
db::Box ibox2 = tni2.inverted () * it * ic.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist));
db::Box ibox2 = (tni2.inverted () * it * ic.bbox (m_intruder_layer)).enlarged (db::Vector (m_dist, m_dist));
db::Box ccbox = cbox & ibox2;
if (! ccbox.empty ()) {
@ -1469,6 +1470,36 @@ local_processor_result_computation_task<TS, TI, TR>::perform ()
}
}
// ---------------------------------------------------------------------------------------------
// LocalProcessorBase implementation
LocalProcessorBase::LocalProcessorBase ()
: m_report_progress (true), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_boolean_core (false),
m_base_verbosity (30), mp_vars (0), mp_current_cell (0)
{
// .. nothing yet ..
}
db::Coord
LocalProcessorBase::dist_for_cell (const db::Cell *cell, db::Coord dist) const
{
return cell ? dist_for_cell (cell->cell_index (), dist) : dist;
}
db::Coord
LocalProcessorBase::dist_for_cell (db::cell_index_type cell_index, db::Coord dist) const
{
if (mp_vars) {
const db::ICplxTrans &tr = mp_vars->single_variant_transformation (cell_index);
double mag = tr.mag ();
return db::coord_traits<db::Coord>::rounded (dist / mag);
} else {
return dist;
}
}
// ---------------------------------------------------------------------------------------------
// LocalProcessor implementation
@ -1477,9 +1508,9 @@ local_processor<TS, TI, TR>::local_processor (db::Layout *layout, db::Cell *top,
: mp_subject_layout (layout), mp_intruder_layout (layout),
mp_subject_top (top), mp_intruder_top (top),
mp_subject_breakout_cells (breakout_cells), mp_intruder_breakout_cells (breakout_cells),
m_report_progress (true), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_boolean_core (default_boolean_core<TR> () ()), m_base_verbosity (30), m_progress (0), mp_progress (0)
m_progress (0), mp_progress (0)
{
// .. nothing yet ..
set_boolean_core (default_boolean_core<TR> () ());
}
template <class TS, class TI, class TR>
@ -1487,19 +1518,9 @@ local_processor<TS, TI, TR>::local_processor (db::Layout *subject_layout, db::Ce
: mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout),
mp_subject_top (subject_top), mp_intruder_top (intruder_top),
mp_subject_breakout_cells (subject_breakout_cells), mp_intruder_breakout_cells (intruder_breakout_cells),
m_report_progress (true), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_boolean_core (default_boolean_core<TR> () ()), m_base_verbosity (30), m_progress (0), mp_progress (0)
m_progress (0), mp_progress (0)
{
// .. nothing yet ..
}
template <class TS, class TI, class TR>
std::string local_processor<TS, TI, TR>::description (const local_operation<TS, TI, TR> *op) const
{
if (op && m_description.empty ()) {
return op->description ();
} else {
return m_description;
}
set_boolean_core (default_boolean_core<TR> () ());
}
template <class TS, class TI, class TR>
@ -1528,34 +1549,64 @@ size_t local_processor<TS, TI, TR>::get_progress () const
}
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer)
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer, bool make_variants)
{
std::vector<unsigned int> ol, il;
ol.push_back (output_layer);
il.push_back (intruder_layer);
run (op, subject_layer, il, ol);
run (op, subject_layer, il, ol, make_variants);
}
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, const std::vector<unsigned int> &output_layers)
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, const std::vector<unsigned int> &output_layers, bool make_variants)
{
std::vector<unsigned int> ol, il;
il.push_back (intruder_layer);
run (op, subject_layer, il, output_layers);
run (op, subject_layer, il, output_layers, make_variants);
}
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, unsigned int output_layer)
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, unsigned int output_layer, bool make_variants)
{
std::vector<unsigned int> ol;
ol.push_back (output_layer);
run (op, subject_layer, intruder_layers, ol);
run (op, subject_layer, intruder_layers, ol, make_variants);
}
template <class TS, class TI, class TR>
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers)
void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers, bool make_variants)
{
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Executing ")) + description (op));
tl::SelfTimer timer (tl::verbosity () > base_verbosity (), tl::to_string (tr ("Executing ")) + description (op));
set_vars_owned (0);
// Prepare cell variants if needed
if (make_variants) {
tl::SelfTimer timer (tl::verbosity () > base_verbosity () + 10, tl::to_string (tr ("Cell variant formation")));
auto op_vars = op->vars ();
if (op_vars) {
db::VariantsCollectorBase *coll = new db::VariantsCollectorBase (op_vars);
set_vars_owned (coll);
coll->collect (mp_subject_layout, mp_subject_top->cell_index ());
coll->separate_variants ();
if (mp_intruder_layout != mp_subject_layout) {
db::VariantsCollectorBase vci (op_vars);
// NOTE: we don't plan to use separate_variants, so the const cast is in order
vci.collect (const_cast<db::Layout *> (mp_intruder_layout), mp_intruder_top->cell_index ());
if (vci.has_variants ()) {
// intruder layout needs to be the same one in that case - we do not want the secondary layout to be modified
throw tl::Exception (tl::to_string (tr ("Can't modify second layout for cell variant formation - this case is not supported as of now")));
}
}
}
}
local_processor_contexts<TS, TI, TR> contexts;
compute_contexts (contexts, op, subject_layer, intruder_layers);
@ -1576,10 +1627,10 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
{
try {
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::to_string (tr ("Computing contexts for ")) + description (op));
tl::SelfTimer timer (tl::verbosity () > base_verbosity () + 10, tl::to_string (tr ("Computing contexts for ")) + description (op));
if (m_nthreads > 0) {
mp_cc_job.reset (new tl::Job<local_processor_context_computation_worker<TS, TI, TR> > (m_nthreads));
if (threads () > 0) {
mp_cc_job.reset (new tl::Job<local_processor_context_computation_worker<TS, TI, TR> > (threads ()));
} else {
mp_cc_job.reset (0);
}
@ -1629,11 +1680,11 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
const db::ICplxTrans &subject_cell_inst,
const db::Cell *intruder_cell,
const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders,
db::Coord dist) const
db::Coord dist_top) const
{
CRONOLOGY_COLLECTION_BRACKET(event_compute_contexts)
if (tl::verbosity () >= m_base_verbosity + 20) {
if (tl::verbosity () >= base_verbosity () + 20) {
if (! subject_parent) {
tl::log << tr ("Computing context for top cell ") << mp_subject_layout->cell_name (subject_cell->cell_index ());
} else {
@ -1641,6 +1692,8 @@ void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS,
}
}
db::Coord dist = dist_for_cell (subject_cell->cell_index (), dist_top);
db::local_processor_cell_context<TS, TI, TR> *cell_context = 0;
// prepare a new cell context: this has to happen in a thread-safe way as we share the contexts
@ -1821,7 +1874,7 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
dump_cell_contexts (contexts, mp_subject_layout, mp_intruder_layout ? mp_intruder_layout : mp_subject_layout);
#endif
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::to_string (tr ("Computing results for ")) + description (op));
tl::SelfTimer timer (tl::verbosity () > base_verbosity () + 10, tl::to_string (tr ("Computing results for ")) + description (op));
// avoids updates while we work on the layout
mp_subject_layout->update ();
@ -1829,7 +1882,7 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
// prepare a progress for the computation tasks
size_t comp_effort = 0;
if (m_report_progress) {
if (report_progress ()) {
for (typename local_processor_contexts<TS, TI, TR>::iterator c = contexts.begin (); c != contexts.end (); ++c) {
comp_effort += c->second.size ();
}
@ -1839,9 +1892,9 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
m_progress = 0;
mp_progress = 0;
if (m_nthreads > 0) {
if (threads () > 0) {
std::unique_ptr<tl::Job<local_processor_result_computation_worker<TS, TI, TR> > > rc_job (new tl::Job<local_processor_result_computation_worker<TS, TI, TR> > (m_nthreads));
std::unique_ptr<tl::Job<local_processor_result_computation_worker<TS, TI, TR> > > rc_job (new tl::Job<local_processor_result_computation_worker<TS, TI, TR> > (threads ()));
// 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
@ -1857,7 +1910,7 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
while (true) {
++iter;
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::sprintf (tl::to_string (tr ("Computing results iteration #%d")), iter));
tl::SelfTimer timer (tl::verbosity () > base_verbosity () + 10, tl::sprintf (tl::to_string (tr ("Computing results iteration #%d")), iter));
bool any = false;
std::unordered_set<db::cell_index_type> later;
@ -1917,7 +1970,7 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
try {
mp_progress = m_report_progress ? &progress : 0;
mp_progress = report_progress () ? &progress : 0;
for (db::Layout::bottom_up_const_iterator bu = mp_subject_layout->begin_bottom_up (); bu != mp_subject_layout->end_bottom_up (); ++bu) {
@ -2045,6 +2098,8 @@ template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_contexts<TS, TI, TR> &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation<TS, TI, TR> *op, const typename local_processor_cell_contexts<TS, TI, TR>::context_key_type &intruders, std::vector<std::unordered_set<TR> > &result) const
{
db::Coord dist = dist_for_cell (subject_cell->cell_index (), op->dist ());
const db::Shapes *subject_shapes = &subject_cell->shapes (contexts.subject_layer ());
db::shape_to_object<TS> s2o;
@ -2091,12 +2146,12 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
if (subject_cell == intruder_cell && contexts.subject_layer () == ail && !foreign) {
scan_shape2shape_same_layer<TS, TI> () (subject_shapes, subject_id0, ipl == intruders.second.end () ? empty_intruders : ipl->second, il_index, interactions, op->dist ());
scan_shape2shape_same_layer<TS, TI> () (subject_shapes, subject_id0, ipl == intruders.second.end () ? empty_intruders : ipl->second, il_index, interactions, dist);
} else {
db::Layout *target_layout = (mp_subject_layout == mp_intruder_layout ? 0 : mp_subject_layout);
scan_shape2shape_different_layers<TS, TI> () (target_layout, subject_shapes, intruder_shapes, subject_id0, &(ipl == intruders.second.end () ? empty_intruders : ipl->second), il_index, interactions, op->dist ());
scan_shape2shape_different_layers<TS, TI> () (target_layout, subject_shapes, intruder_shapes, subject_id0, &(ipl == intruders.second.end () ? empty_intruders : ipl->second), il_index, interactions, dist);
}
@ -2106,7 +2161,7 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
db::box_scanner2<TS, int, db::CellInstArray, int> scanner;
db::addressable_object_from_shape<TS> heap;
interaction_registration_shape2inst<TS, TI> rec (mp_subject_layout, mp_intruder_layout, ail, il_index, op->dist (), &interactions);
interaction_registration_shape2inst<TS, TI> rec (mp_subject_layout, mp_intruder_layout, ail, il_index, dist, &interactions);
unsigned int id = subject_id0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
@ -2137,7 +2192,7 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
}
}
scanner.process (rec, op->dist (), db::box_convert<TS> (), inst_bci);
scanner.process (rec, dist, db::box_convert<TS> (), inst_bci);
}
@ -2154,7 +2209,7 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
}
op->compute_local (mp_subject_layout, interactions, result, m_max_vertex_count, m_area_ratio);
op->compute_local (mp_subject_layout, subject_cell, interactions, result, this);
}
}
@ -2264,7 +2319,7 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
std::string process_description, scan_description;
if (m_report_progress) {
if (report_progress ()) {
process_description = description (op);
if (process_description.empty ()) {
@ -2327,7 +2382,7 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
if (*il == subjects && ! ff) {
interaction_registration_shape1_scanner_combo<TS, TI> scanner (&interactions, il_index, m_report_progress, scan_description);
interaction_registration_shape1_scanner_combo<TS, TI> scanner (&interactions, il_index, report_progress (), scan_description);
for (typename shape_interactions<TS, TI>::subject_iterator s = interactions.begin_subjects (); s != interactions.end_subjects (); ++s) {
scanner.insert (&s->second, s->first);
@ -2337,7 +2392,7 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
} else {
db::box_scanner2<TS, unsigned int, TI, unsigned int> scanner (m_report_progress, scan_description);
db::box_scanner2<TS, unsigned int, TI, unsigned int> scanner (report_progress (), scan_description);
interaction_registration_shape2shape<TS, TI> rec (0 /*layout*/, &interactions, il_index);
for (typename shape_interactions<TS, TI>::subject_iterator s = interactions.begin_subjects (); s != interactions.end_subjects (); ++s) {
@ -2393,7 +2448,7 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
if (*il == subjects && ! ff) {
interaction_registration_shape1_scanner_combo<TS, TI> scanner (&interactions, il_index, m_report_progress, scan_description);
interaction_registration_shape1_scanner_combo<TS, TI> scanner (&interactions, il_index, report_progress (), scan_description);
addressable_shape_delivery<TS> is (subjects.confined (common_box, false));
unsigned int id = id_first;
@ -2406,7 +2461,7 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
} else {
db::box_scanner2<TS, unsigned int, TI, unsigned int> scanner (m_report_progress, scan_description);
db::box_scanner2<TS, unsigned int, TI, unsigned int> scanner (report_progress (), scan_description);
interaction_registration_shape2shape<TS, TI> rec (0 /*layout*/, &interactions, il_index);
if (*il == subjects) {
@ -2463,7 +2518,7 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
std::vector<std::unordered_set<TR> > result;
result.resize (result_shapes.size ());
op->compute_local (mp_subject_layout, interactions, result, m_max_vertex_count, m_area_ratio, m_report_progress, process_description);
op->compute_local (mp_subject_layout, 0, interactions, result, this);
for (std::vector<db::Shapes *>::const_iterator r = result_shapes.begin (); r != result_shapes.end (); ++r) {
if (*r) {

View File

@ -30,6 +30,7 @@
#include "dbLayout.h"
#include "dbLocalOperation.h"
#include "dbGenericShapeIterator.h"
#include "dbCellVariants.h"
#include "tlThreadedWorkers.h"
#include "tlProgress.h"
@ -413,22 +414,10 @@ public:
}
};
template <class TS, class TI, class TR>
class DB_PUBLIC local_processor
class DB_PUBLIC LocalProcessorBase
{
public:
local_processor (db::Layout *layout = 0, db::Cell *top = 0, const std::set<db::cell_index_type> *breakout_cells = 0);
local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set<db::cell_index_type> *subject_breakout_cells = 0, const std::set<db::cell_index_type> *intruder_breakout_cells = 0);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layers);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, const std::vector<unsigned int> &output_layers);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, unsigned int output_layer);
void compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers) const;
void compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers) const;
void run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const;
void run_flat (const db::Shapes *subjects, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
void run_flat (const generic_shape_iterator<TS> &subjects, const std::vector<generic_shape_iterator<TI> > &intruders, const std::vector<bool> &foreign, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
LocalProcessorBase ();
void set_description (const std::string &d)
{
@ -440,6 +429,11 @@ public:
m_report_progress = rp;
}
bool report_progress () const
{
return m_report_progress;
}
void set_base_verbosity (int vb)
{
m_base_verbosity = vb;
@ -490,6 +484,62 @@ public:
return m_boolean_core;
}
void set_vars_owned (db::VariantsCollectorBase *vars)
{
mp_vars_owned.reset (vars);
mp_vars = vars;
}
const db::VariantsCollectorBase *vars () const
{
return mp_vars;
}
db::Coord dist_for_cell (db::cell_index_type cell_index, db::Coord dist) const;
db::Coord dist_for_cell (const db::Cell *cell, db::Coord dist) const;
template <class TS, class TI, class TR>
std::string description (const local_operation<TS, TI, TR> *op) const
{
if (op && m_description.empty ()) {
return op->description ();
} else {
return m_description;
}
}
private:
std::string m_description;
bool m_report_progress;
unsigned int m_nthreads;
size_t m_max_vertex_count;
double m_area_ratio;
bool m_boolean_core;
int m_base_verbosity;
const db::VariantsCollectorBase *mp_vars;
std::unique_ptr<db::VariantsCollectorBase> mp_vars_owned;
mutable const db::Cell *mp_current_cell;
};
template <class TS, class TI, class TR>
class DB_PUBLIC local_processor
: public LocalProcessorBase
{
public:
local_processor (db::Layout *layout = 0, db::Cell *top = 0, const std::set<db::cell_index_type> *breakout_cells = 0);
local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set<db::cell_index_type> *subject_breakout_cells = 0, const std::set<db::cell_index_type> *intruder_breakout_cells = 0);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layers, bool make_variants = true);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, const std::vector<unsigned int> &output_layers, bool make_variants = true);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers, bool make_variants = true);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, unsigned int output_layer, bool make_variants = true);
void compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers) const;
void compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers) const;
void run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const;
void run_flat (const db::Shapes *subjects, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
void run_flat (const generic_shape_iterator<TS> &subjects, const std::vector<generic_shape_iterator<TI> > &intruders, const std::vector<bool> &foreign, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
private:
template<typename, typename, typename> friend class local_processor_cell_contexts;
template<typename, typename, typename> friend class local_processor_context_computation_task;
@ -500,18 +550,10 @@ private:
const db::Cell *mp_intruder_top;
const std::set<db::cell_index_type> *mp_subject_breakout_cells;
const std::set<db::cell_index_type> *mp_intruder_breakout_cells;
std::string m_description;
bool m_report_progress;
unsigned int m_nthreads;
size_t m_max_vertex_count;
double m_area_ratio;
bool m_boolean_core;
int m_base_verbosity;
mutable std::unique_ptr<tl::Job<local_processor_context_computation_worker<TS, TI, TR> > > mp_cc_job;
mutable size_t m_progress;
mutable tl::Progress *mp_progress;
std::string description (const local_operation<TS, TI, TR> *op) const;
void next () const;
size_t get_progress () const;
void compute_contexts (db::local_processor_contexts<TS, TI, TR> &contexts, db::local_processor_cell_context<TS, TI, TR> *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<TS, TI, TR>::context_key_type &intruders, db::Coord dist) const;

View File

@ -33,6 +33,7 @@
#include "dbColdProxy.h"
#include "dbLibraryManager.h"
#include "dbLibrary.h"
#include "dbCellVariants.h"
#include "dbRegion.h"
#include "dbEdgePairs.h"
#include "dbEdges.h"
@ -40,6 +41,7 @@
#include "dbCellMapping.h"
#include "dbLayerMapping.h"
#include "dbLayoutUtils.h"
#include "dbCellVariants.h"
#include "tlTimer.h"
#include "tlLog.h"
#include "tlInternational.h"

View File

@ -71,6 +71,7 @@ class Texts;
class Technology;
class CellMapping;
class LayerMapping;
class VariantsCollectorBase;
template <class Coord> class generic_repository;
typedef generic_repository<db::Coord> GenericRepository;
@ -2068,6 +2069,12 @@ public:
*/
tl::Event technology_changed_event;
/**
* @brief This event is raised when cell variants are built
* It will specify a list of cells with their new variants.
*/
tl::event<const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *> variants_created_event;
protected:
/**
* @brief Establish the graph's internals according to the dirty flags

View File

@ -521,8 +521,8 @@ scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db
{
tl::SelfTimer timer1 (tl::verbosity () >= 41, tl::to_string (tr ("scale_and_snap: variant formation")));
vars.collect (layout, cell);
vars.separate_variants (layout, cell);
vars.collect (&layout, cell.cell_index ());
vars.separate_variants ();
}
std::set<db::cell_index_type> called_cells;
@ -543,9 +543,7 @@ scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db
continue;
}
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
db::ICplxTrans tr = v.begin ()->first;
db::ICplxTrans tr = vars.single_variant_transformation (c->cell_index ());
// NOTE: tr_disp is already multiplied with mag, so it can be an integer
db::Vector tr_disp = tr.disp ();

View File

@ -30,17 +30,17 @@ namespace db
// local_operations implementation
template <class TS, class TI, class TR>
void local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio, bool report_progress, const std::string &progress_desc) const
void local_operation<TS, TI, TR>::compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
{
if (interactions.num_subjects () <= 1 || ! requests_single_subjects ()) {
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
do_compute_local (layout, subject_cell, interactions, results, proc);
} else {
std::unique_ptr<tl::RelativeProgress> progress;
if (report_progress) {
progress.reset (new tl::RelativeProgress (progress_desc, interactions.size ()));
if (proc->report_progress ()) {
progress.reset (new tl::RelativeProgress (proc->description (this), interactions.size ()));
}
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
@ -62,7 +62,7 @@ void local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shape
single_interactions.add_interaction (i->first, *ii);
}
do_compute_local (layout, single_interactions, results, max_vertex_count, area_ratio);
do_compute_local (layout, subject_cell, single_interactions, results, proc);
if (progress.get ()) {
++*progress;

View File

@ -37,6 +37,8 @@ namespace db
{
template <class TS, class TI> class shape_interactions;
class LocalProcessorBase;
class TransformationReducer;
/**
* @brief Indicates the desired behaviour for subject shapes for which there is no intruder
@ -93,7 +95,7 @@ public:
*
* If the operation requests single subject mode, the interactions will be split into single subject/intruder clusters
*/
void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio, bool report_progress = false, const std::string &progress_desc = std::string ()) const;
void compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const;
/**
* @brief Indicates the desired behaviour when a shape does not have an intruder
@ -116,6 +118,11 @@ public:
*/
virtual db::Coord dist () const { return 0; }
/**
* @brief Gets the cell variant reducer that indicates whether to build cell variants and which
*/
virtual const db::TransformationReducer *vars () const { return 0; }
protected:
/**
* @brief Computes the results from a given set of interacting shapes
@ -123,7 +130,7 @@ protected:
* @param interactions The interaction set
* @param result The container to which the results are written
*/
virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, size_t max_vertex_count, double area_ratio) const = 0;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, const db::LocalProcessorBase *proc) const = 0;
};
}

View File

@ -199,12 +199,16 @@ check_local_operation_base<TS, TI>::check_local_operation_base (const EdgeRelati
template <class TS, class TI>
void
check_local_operation_base<TS, TI>::compute_results (db::Layout *layout, const std::vector<const TS *> &subjects, const std::set<const TI *> &intruders, std::unordered_set<db::EdgePair> &result, std::unordered_set<db::EdgePair> &intra_polygon_result) const
check_local_operation_base<TS, TI>::compute_results (db::Layout *layout, db::Cell *subject_cell, const std::vector<const TS *> &subjects, const std::set<const TI *> &intruders, std::unordered_set<db::EdgePair> &result, std::unordered_set<db::EdgePair> &intra_polygon_result, const db::LocalProcessorBase *proc) const
{
// NOTE: the rectangle and opposite filters are unsymmetric
bool symmetric_edge_pairs = ! m_has_other && m_options.opposite_filter == db::NoOppositeFilter && m_options.rect_filter == RectFilter::NoRectFilter;
edge2edge_check_negative_or_positive<std::unordered_set<db::EdgePair> > edge_check (m_check, result, intra_polygon_result, m_options.negative, m_different_polygons, m_has_other, m_options.shielded, symmetric_edge_pairs);
// modify the check to take into account scaled cells
EdgeRelationFilter check = m_check;
check.set_distance (proc->dist_for_cell (subject_cell, check.distance ()));
edge2edge_check_negative_or_positive<std::unordered_set<db::EdgePair> > edge_check (check, result, intra_polygon_result, m_options.negative, m_different_polygons, m_has_other, m_options.shielded, symmetric_edge_pairs);
poly2poly_check<TS> poly_check (edge_check);
std::unordered_set<TI> polygons;
@ -677,7 +681,7 @@ check_local_operation<TS, TI>::check_local_operation (const EdgeRelationFilter &
template <class TS, class TI>
void
check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase *proc) const
{
std::vector<const TS *> subjects;
subjects.reserve (interactions.size ());
@ -696,7 +700,7 @@ check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape
std::unordered_set<db::EdgePair> result, intra_polygon_result;
// perform the basic check
check_local_operation_base<TS, TI>::compute_results (layout, subjects, intruders, result, intra_polygon_result);
check_local_operation_base<TS, TI>::compute_results (layout, subject_cell, subjects, intruders, result, intra_polygon_result, proc);
// detect and remove parts of the result which have or do not have results "opposite"
// ("opposite" is defined by the projection of edges "through" the subject shape)
@ -752,7 +756,7 @@ check_local_operation_with_properties<TS, TI>::check_local_operation_with_proper
template <class TS, class TI>
void
check_local_operation_with_properties<TS, TI>::do_compute_local (db::Layout *layout, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::EdgePairWithProperties> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
check_local_operation_with_properties<TS, TI>::do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::EdgePairWithProperties> > &results, const db::LocalProcessorBase *proc) const
{
tl_assert (results.size () == 1);
@ -766,7 +770,7 @@ check_local_operation_with_properties<TS, TI>::do_compute_local (db::Layout *lay
const std::set<const TI *> &intruders = s2p->second.second;
// perform the basic check
check_local_operation_base<TS, TI>::compute_results (layout, subjects, intruders, result, intra_polygon_result);
check_local_operation_base<TS, TI>::compute_results (layout, subject_cell, subjects, intruders, result, intra_polygon_result, proc);
// detect and remove parts of the result which have or do not have results "opposite"
// ("opposite" is defined by the projection of edges "through" the subject shape)
@ -852,7 +856,7 @@ db::Coord interacting_local_operation<TS, TI, TR>::dist () const
}
template <class TS, class TI, class TR>
void interacting_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void interacting_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const
{
if (m_output_mode == None) {
return;
@ -1031,7 +1035,7 @@ db::Coord contained_local_operation<TS, TI, TR>::dist () const
}
template <class TS, class TI, class TR>
void contained_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void contained_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const
{
if (m_output_mode == None) {
return;
@ -1106,7 +1110,7 @@ db::Coord pull_local_operation<TS, TI, TR>::dist () const
}
template <class TS, class TI, class TR>
void pull_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void pull_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front ();
@ -1186,7 +1190,7 @@ db::Coord interacting_with_edge_local_operation<TS, TI, TR>::dist () const
}
template <class TS, class TI, class TR>
void interacting_with_edge_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void interacting_with_edge_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const
{
if (m_output_mode == None) {
return;
@ -1313,7 +1317,7 @@ db::Coord pull_with_edge_local_operation<TS, TI, TR>::dist () const
}
template <class TS, class TI, class TR>
void pull_with_edge_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void pull_with_edge_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front ();
@ -1374,7 +1378,7 @@ db::Coord pull_with_text_local_operation<TS, TI, TR>::dist () const
}
template <class TS, class TI, class TR>
void pull_with_text_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void pull_with_text_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front ();
@ -1443,7 +1447,7 @@ db::Coord interacting_with_text_local_operation<TS, TI, TR>::dist () const
template <class TS, class TI, class TR>
void interacting_with_text_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
void interacting_with_text_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const
{
if (m_output_mode == None) {
return;
@ -1555,7 +1559,7 @@ bool_and_or_not_local_operation<TS, TI, TR>::description () const
template <class TS, class TI, class TR>
void
bool_and_or_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
bool_and_or_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
{
tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front ();
@ -1603,7 +1607,7 @@ bool_and_or_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layou
db::BooleanOp op (m_is_and ? db::BooleanOp::And : db::BooleanOp::ANotB);
db::polygon_ref_generator<TR> pr (layout, result);
db::PolygonSplitter splitter (pr, area_ratio, max_vertex_count);
db::PolygonSplitter splitter (pr, proc->area_ratio (), proc->max_vertex_count ());
db::PolygonGenerator pg (splitter, true, true);
ep.set_base_verbosity (50);
ep.process (pg, op);
@ -1640,7 +1644,7 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::description () cons
template <class TS, class TI, class TR>
void
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &results, size_t max_vertex_count, double area_ratio) const
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &results, const db::LocalProcessorBase *proc) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::object_with_properties<TR> > &result = results.front ();
@ -1717,7 +1721,7 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (d
db::BooleanOp op (m_is_and ? db::BooleanOp::And : db::BooleanOp::ANotB);
db::polygon_ref_generator_with_properties<db::object_with_properties<TR> > pr (layout, result, prop_id);
db::PolygonSplitter splitter (pr, area_ratio, max_vertex_count);
db::PolygonSplitter splitter (pr, proc->area_ratio (), proc->max_vertex_count ());
db::PolygonGenerator pg (splitter, true, true);
ep.set_base_verbosity (50);
ep.process (pg, op);
@ -1742,7 +1746,7 @@ two_bool_and_not_local_operation<TS, TI, TR>::two_bool_and_not_local_operation (
template <class TS, class TI, class TR>
void
two_bool_and_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
two_bool_and_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
{
tl_assert (results.size () == 2);
@ -1788,12 +1792,12 @@ two_bool_and_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layo
db::BooleanOp op0 (db::BooleanOp::And);
db::polygon_ref_generator<TR> pr0 (layout, result0);
db::PolygonSplitter splitter0 (pr0, area_ratio, max_vertex_count);
db::PolygonSplitter splitter0 (pr0, proc->area_ratio (), proc->max_vertex_count ());
db::PolygonGenerator pg0 (splitter0, true, true);
db::BooleanOp op1 (db::BooleanOp::ANotB);
db::polygon_ref_generator<TR> pr1 (layout, result1);
db::PolygonSplitter splitter1 (pr1, area_ratio, max_vertex_count);
db::PolygonSplitter splitter1 (pr1, proc->area_ratio (), proc->max_vertex_count ());
db::PolygonGenerator pg1 (splitter1, true, true);
ep.set_base_verbosity (50);
@ -1829,7 +1833,7 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::two_bool_and_not_l
template <class TS, class TI, class TR>
void
two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &results, size_t max_vertex_count, double area_ratio) const
two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &results, const db::LocalProcessorBase *proc) const
{
tl_assert (results.size () == 2);
std::unordered_set<db::object_with_properties<TR> > &result0 = results [0];
@ -1904,12 +1908,12 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
db::BooleanOp op0 (db::BooleanOp::And);
db::polygon_ref_generator<TR> pr0 (layout, result0_wo_props);
db::PolygonSplitter splitter0 (pr0, area_ratio, max_vertex_count);
db::PolygonSplitter splitter0 (pr0, proc->area_ratio (), proc->max_vertex_count ());
db::PolygonGenerator pg0 (splitter0, true, true);
db::BooleanOp op1 (db::BooleanOp::ANotB);
db::polygon_ref_generator<TR> pr1 (layout, result1_wo_props);
db::PolygonSplitter splitter1 (pr1, area_ratio, max_vertex_count);
db::PolygonSplitter splitter1 (pr1, proc->area_ratio (), proc->max_vertex_count ());
db::PolygonGenerator pg1 (splitter1, true, true);
ep.set_base_verbosity (50);
@ -1949,7 +1953,7 @@ SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wra
}
void
SelfOverlapMergeLocalOperation::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
SelfOverlapMergeLocalOperation::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase * /*proc*/) const
{
tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front ();
@ -2021,7 +2025,7 @@ PolygonToEdgeLocalOperation::description () const
}
void
PolygonToEdgeLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties> &interactions, std::vector<std::unordered_set<db::EdgeWithProperties> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
PolygonToEdgeLocalOperation::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties> &interactions, std::vector<std::unordered_set<db::EdgeWithProperties> > &results, const db::LocalProcessorBase * /*proc*/) const
{
db::EdgeProcessor ep;
ep.set_base_verbosity (50);

View File

@ -236,7 +236,7 @@ protected:
bool m_other_is_merged;
db::RegionCheckOptions m_options;
void compute_results (db::Layout *layout, const std::vector<const TS *> &subjects, const std::set<const TI *> &intruders, std::unordered_set<db::EdgePair> &result, std::unordered_set<db::EdgePair> &intra_polygon_result) const;
void compute_results (db::Layout *layout, db::Cell *subject_cell, const std::vector<const TS *> &subjects, const std::set<const TI *> &intruders, std::unordered_set<db::EdgePair> &result, std::unordered_set<db::EdgePair> &intra_polygon_result, const LocalProcessorBase *proc) const;
void apply_opposite_filter (const std::vector<const TS *> &subjects, std::unordered_set<db::EdgePair> &result, std::unordered_set<db::EdgePair> &intra_polygon_result) const;
void apply_rectangle_filter (const std::vector<const TS *> &subjects, std::unordered_set<db::EdgePair> &result) const;
};
@ -253,7 +253,12 @@ public:
virtual bool requests_single_subjects () const { return true; }
virtual std::string description () const;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual const db::TransformationReducer *vars () const { return &m_vars; }
private:
db::MagnificationReducer m_vars;
};
template <class TS, class TI>
@ -268,10 +273,13 @@ public:
virtual bool requests_single_subjects () const { return true; }
virtual std::string description () const;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::EdgePairWithProperties> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::EdgePairWithProperties> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual const db::TransformationReducer *vars () const { return &m_vars; }
private:
mutable db::PropertyMapper m_pms, m_pmi;
db::MagnificationReducer m_vars;
};
typedef check_local_operation<db::PolygonRef, db::PolygonRef> CheckLocalOperation;
@ -288,7 +296,7 @@ public:
interacting_local_operation (int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count, bool other_is_merged);
virtual db::Coord dist () const;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -310,7 +318,7 @@ public:
pull_local_operation (int mode, bool touching);
virtual db::Coord dist () const;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -329,7 +337,7 @@ public:
interacting_with_edge_local_operation (InteractingOutputMode output_mode, size_t min_count, size_t max_count, bool other_is_merged);
virtual db::Coord dist () const;
virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -349,7 +357,7 @@ public:
pull_with_edge_local_operation ();
virtual db::Coord dist () const;
virtual void do_compute_local (db::Layout *, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
};
@ -364,7 +372,7 @@ public:
interacting_with_text_local_operation (InteractingOutputMode output_mode, size_t min_count, size_t max_count);
virtual db::Coord dist () const;
virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -383,7 +391,7 @@ public:
pull_with_text_local_operation ();
virtual db::Coord dist () const;
virtual void do_compute_local (db::Layout *, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
};
@ -398,7 +406,7 @@ public:
contained_local_operation (InteractingOutputMode output_mode);
virtual db::Coord dist () const;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const LocalProcessorBase * /*proc*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -421,7 +429,7 @@ class DB_PUBLIC bool_and_or_not_local_operation
public:
bool_and_or_not_local_operation (bool is_and);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, const db::LocalProcessorBase *proc) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -441,7 +449,7 @@ class DB_PUBLIC bool_and_or_not_local_operation_with_properties
public:
bool_and_or_not_local_operation_with_properties (bool is_and, db::PropertiesRepository *target_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint);
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &result, const db::LocalProcessorBase *proc) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -468,7 +476,7 @@ class DB_PUBLIC two_bool_and_not_local_operation
public:
two_bool_and_not_local_operation ();
virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, const db::LocalProcessorBase *proc) const;
virtual std::string description () const;
};
@ -487,7 +495,7 @@ class DB_PUBLIC two_bool_and_not_local_operation_with_properties
public:
two_bool_and_not_local_operation_with_properties (db::PropertiesRepository *target1_pr, db::PropertiesRepository *target2_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &result, const db::LocalProcessorBase *proc) const;
virtual std::string description () const;
private:
@ -508,7 +516,7 @@ class DB_PUBLIC SelfOverlapMergeLocalOperation
public:
SelfOverlapMergeLocalOperation (unsigned int wrap_count);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, const db::LocalProcessorBase *proc) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const;
@ -529,7 +537,7 @@ public:
virtual bool requests_single_subjects () const { return true; }
virtual std::string description () const;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties> &interactions, std::vector<std::unordered_set<db::EdgeWithProperties> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties> &interactions, std::vector<std::unordered_set<db::EdgeWithProperties> > &results, const db::LocalProcessorBase *proc) const;
private:
mutable db::PropertyMapper m_pm;

View File

@ -118,7 +118,13 @@ void RelativeExtentsAsEdges::process (const db::Polygon &poly, std::vector<db::E
const TransformationReducer *RelativeExtentsAsEdges::vars () const
{
return & m_anisotropic_reducer;
if (fabs (m_fx1) < db::epsilon && fabs (m_fy1) < db::epsilon && fabs (1.0 - m_fx2) < db::epsilon && fabs (1.0 - m_fy2) < db::epsilon) {
return 0;
} else if (fabs (m_fx1 - m_fy1) < db::epsilon && fabs (1.0 - (m_fx1 + m_fx2)) < db::epsilon && fabs (m_fx2 - m_fy2) < db::epsilon && fabs (1.0 - (m_fy1 + m_fy2)) < db::epsilon) {
return & m_isotropic_reducer;
} else {
return & m_anisotropic_reducer;
}
}
bool RelativeExtentsAsEdges::result_must_not_be_merged () const

View File

@ -282,6 +282,7 @@ public:
private:
double m_fx1, m_fy1, m_fx2, m_fy2;
db::MagnificationAndOrientationReducer m_anisotropic_reducer;
db::MagnificationReducer m_isotropic_reducer;
};
/**

View File

@ -402,7 +402,7 @@ private:
bool m_inverse;
parameter_type m_parameter;
db::MagnificationReducer m_isotropic_vars;
db::MagnificationAndOrientationReducer m_anisotropic_vars;
db::XYAnisotropyAndMagnificationReducer m_anisotropic_vars;
bool check (const db::Box &box) const;
};
@ -472,7 +472,7 @@ private:
bool m_inverse;
parameter_type m_parameter;
db::MagnificationReducer m_isotropic_vars;
db::MagnificationAndOrientationReducer m_anisotropic_vars;
db::XYAnisotropyAndMagnificationReducer m_anisotropic_vars;
};
/**
@ -593,11 +593,14 @@ public:
SinglePolygonCheck (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options);
virtual void process (const db::Polygon &polygon, std::vector<db::EdgePair> &res) const;
virtual const TransformationReducer *vars () const { return &m_vars; }
virtual bool wants_variants () const { return true; }
private:
db::edge_relation_type m_relation;
db::Coord m_d;
db::RegionCheckOptions m_options;
db::MagnificationReducer m_vars;
};
} // namespace db

View File

@ -169,21 +169,21 @@ DB_PUBLIC_TEMPLATE
OutputContainer *
shape_collection_processed_impl (const db::DeepLayer &input, const shape_collection_processor<Shape, Result> &filter)
{
db::Layout &layout = const_cast<db::Layout &> (input.layout ());
std::unique_ptr<VariantsCollectorBase> vars;
if (filter.vars ()) {
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
vars->collect (input.layout (), input.initial_cell ());
vars->collect (&layout, input.initial_cell ().cell_index ());
if (filter.wants_variants ()) {
const_cast<db::DeepLayer &> (input).separate_variants (*vars);
vars->separate_variants ();
}
}
db::Layout &layout = const_cast<db::Layout &> (input.layout ());
std::vector<Result> heap;
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
@ -198,20 +198,20 @@ shape_collection_processed_impl (const db::DeepLayer &input, const shape_collect
if (vars.get ()) {
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vars->variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes *st;
if (vv.size () == 1) {
st = & c->shapes (res->deep_layer ().layer ());
} else {
st = & to_commit [c->cell_index ()] [v->first];
st = & to_commit [c->cell_index ()] [*v];
}
shape_collection_processor_delivery<Result> delivery (&layout, st);
shape_collection_processor_delivery<db::object_with_properties<Result> > delivery_wp (&layout, st);
const db::ICplxTrans &tr = v->first;
const db::ICplxTrans &tr = *v;
db::ICplxTrans trinv = tr.inverted ();
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
@ -256,7 +256,7 @@ shape_collection_processed_impl (const db::DeepLayer &input, const shape_collect
}
if (! to_commit.empty () && vars.get ()) {
res->deep_layer ().commit_shapes (*vars, to_commit);
vars->commit_shapes (res->deep_layer ().layer (), to_commit);
}
if (filter.result_is_merged ()) {

View File

@ -27,6 +27,18 @@
#include "tlUnitTest.h"
#include "tlStream.h"
std::string var2str (const std::set<db::ICplxTrans> &vars)
{
std::string res;
for (auto i = vars.begin (); i != vars.end (); ++i) {
if (! res.empty ()) {
res += ";";
}
res += i->to_string ();
}
return res;
}
std::string var2str (const std::map<db::ICplxTrans, size_t> &vars)
{
std::string res;
@ -93,14 +105,14 @@ TEST(1_Trivial)
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > vm;
vb.separate_variants (ly, a, &vm);
vb.separate_variants (&vm);
EXPECT_EQ (vm.empty (), true);
EXPECT_EQ (vm2str (ly, vm), "");
}
@ -118,16 +130,16 @@ TEST(2_TwoVariants)
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "m0 *1 0,0;r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:m0 *1 1,100");
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > vm;
vb.separate_variants (ly, a, &vm);
vb.separate_variants (&vm);
EXPECT_EQ (vm2str (ly, vm), "B:B[m0 *1 0,0],B$VAR1[r0 *1 0,0]");
EXPECT_EQ (inst2str (ly, a), "B$VAR1:r0 *1 1,10;B:m0 *1 1,100");
}
@ -147,17 +159,17 @@ TEST(3_TwoLevels)
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r90 *1 1,100");
EXPECT_EQ (inst2str (ly, b), "C:r0 *1 2,10;C:m0 *1 2,100");
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > vm;
vb.separate_variants (ly, a, &vm);
vb.separate_variants (&vm);
EXPECT_EQ (vm2str (ly, vm), "B:B[r0 *1 0,0],B$VAR1[r90 *1 0,0];C:C[m0 *1 0,0],C$VAR1[r0 *1 0,0],C$VAR2[m45 *1 0,0],C$VAR3[r90 *1 0,0]");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B$VAR1:r90 *1 1,100");
@ -181,18 +193,18 @@ TEST(4_ThreeLevels)
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "r270 *1 0,0[1];m90 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "r270 *1 0,0;m90 *1 0,0;r0 *1 0,0;m45 *1 0,0");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r90 *1 1,100");
EXPECT_EQ (inst2str (ly, b), "C:r0 *1 2,10;C:m0 *1 2,100");
EXPECT_EQ (inst2str (ly, c), "D:m45 *1 0,0");
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > vm;
vb.separate_variants (ly, a, &vm);
vb.separate_variants (&vm);
EXPECT_EQ (vm2str (ly, vm), "B:B[r0 *1 0,0],B$VAR1[r90 *1 0,0];C:C[m0 *1 0,0],C$VAR1[r0 *1 0,0],C$VAR2[m45 *1 0,0],C$VAR3[r90 *1 0,0];D:D[r270 *1 0,0],D$VAR1[m90 *1 0,0],D$VAR2[r0 *1 0,0],D$VAR3[m45 *1 0,0]");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B$VAR1:r90 *1 1,100");
@ -219,16 +231,15 @@ TEST(5_ComplexTrans)
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
TEST(6_Arrays)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
@ -242,10 +253,10 @@ TEST(6_Arrays)
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[100];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[100];r0 *1 0,0[10000];m45 *1 0,0[1];r90 *1 0,0[100]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
@ -264,10 +275,10 @@ TEST(7_ScalingVariants)
db::MagnificationReducer red;
db::cell_variants_collector<db::MagnificationReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r0 *1.5 0,0[100]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 0,0[1];r0 *1.5 0,0[100];r0 *2 0,0[100];r0 *3 0,0[10000]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r0 *1.5 0,0");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 0,0;r0 *1.5 0,0;r0 *2 0,0;r0 *3 0,0");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
@ -284,9 +295,9 @@ TEST(8_GridVariants)
db::GridReducer red (10);
db::cell_variants_collector<db::GridReducer> vb (red);
vb.collect (ly, a);
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 1,0[1];r0 *1 3,0[1];r0 *1 1,1[1];r0 *1 3,1[1]");
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 1,0;r0 *1 3,0;r0 *1 1,1;r0 *1 3,1");
// placements are:
// b in a: r0 *1 x=1,1+102 y=10,10+101
@ -297,7 +308,7 @@ TEST(8_GridVariants)
// expanded placements mod 10:
// c in a: r0 *2 x=1,1+102 y=10,10+101 x r0 *1 x=2,y=3
// = (3,3),(5,3),(3,4),(5,4)
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 -5,3[1];r0 *1 3,3[1];r0 *1 -5,4[1];r0 *1 3,4[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 -5,3;r0 *1 3,3;r0 *1 -5,4;r0 *1 3,4");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r0 *1 1,111;B:r0 *1 103,10;B:r0 *1 103,111");
@ -305,7 +316,7 @@ TEST(8_GridVariants)
EXPECT_EQ (inst2str (ly, c), "");
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > vm;
vb.separate_variants (ly, a, &vm);
vb.separate_variants (&vm);
EXPECT_EQ (vm2str (ly, vm), "B:B[r0 *1 1,0],B$VAR1[r0 *1 3,0],B$VAR2[r0 *1 1,1],B$VAR3[r0 *1 3,1];C:C[r0 *1 -5,3],C$VAR1[r0 *1 3,3],C$VAR2[r0 *1 -5,4],C$VAR3[r0 *1 3,4]");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B$VAR2:r0 *1 1,111;B$VAR1:r0 *1 103,10;B$VAR3:r0 *1 103,111");
@ -331,7 +342,278 @@ TEST(9_ComplexGridVariants)
db::GridReducer red (10);
db::cell_variants_collector<db::GridReducer> vb (red);
vb.collect (ly, a);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *2 1,0;r90 *1 1,0;r0 *2 3,0;r0 *2 1,1;r0 *2 3,1");
// placements are:
// b in a: r0 *2 x=1,1+102 y=10,10+101
// r90 *1 x=1,y=100
// c in b: r0 *2 x=2,2+105 y=10,10+103
// m0 *1 x=2,y=100
// expanded placements:
// c in a: r0 *2 x=1,1+102 y=10,10+101 x r0 *2 x=2,2+105 y=10,10+103
// = (5,30),(215,30),(5,236),(215,236)
// (107,30),(317,30),(107,236),(317,236)
// (5,131),(215,131),(5,337),(215,337)
// (107,131),(317,131),(107,337),(317,337)
// r0 *2 x=1,1+102 y=10,10+101 x m0 *1 x=2,y=100
// (5,210),(5,311),(107,210),(107,311)
// r90 *1 x=1,y=100 x r0 *2 x=2,2+105 y=10,10+103
// (-9,102),(-9,207),(-112,102),(-112,207)
// r90 *1 x=1,y=100 x m0 *1 x=2,y=100
// (-99,102)
// expanded ((placements + 5) mod 10) - placements
// c in a: r0 *2 x=1,1+102 y=10,10+101 x r0 *2 x=2,2+105 y=10,10+103
// = (5,0),(5,0),(-5,-4),(-5,-4)
// (7,0),(7,0),(-3,-4),(-3,-4)
// (-5,1),(-5,1),(-5,-3),(-5,-3)
// (-3,1),(-3,1),(-3,-3),(-3,-3)
// r0 *2 x=1,1+102 y=10,10+101 x m0 *1 x=2,y=100
// (-5,0),(-5,1),(-3,0),(-3,1)
// r90 *1 x=1,y=100 x r0 *2 x=2,2+105 y=10,10+103
// (1,2),(1,-3),(-2,2),(-2,-3)
// r90 *1 x=1,y=100 x m0 *1 x=2,y=100
// (1,2)
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *4 -5,-4;r0 *4 -3,-4;r0 *4 -5,-3;r0 *4 -3,-3;r90 *2 -2,-3;"
"r90 *2 1,-3;m0 *2 -5,0;r0 *4 -5,0;m0 *2 -3,0;r0 *4 -3,0;"
"m0 *2 -5,1;r0 *4 -5,1;m0 *2 -3,1;r0 *4 -3,1;r90 *2 -2,2;m45 *1 1,2;r90 *2 1,2");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
TEST(100_OrientationVariantsWithLayout)
{
db::Layout ly;
{
std::string fn (tl::testdata ());
fn += "/algo/deep_region_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (&ly, top_cell.cell_index ());
vb.separate_variants ();
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testdata () + "/algo/cell_variants_au1.gds");
}
TEST(10_TrivialStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (0, false, db::Vector (1, 10))));
db::OrientationReducer red;
db::cell_variants_statistics<db::OrientationReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
TEST(11_TwoVariantsStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (0, false, db::Vector (1, 10))));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (0, true, db::Vector (1, 100))));
db::OrientationReducer red;
db::cell_variants_statistics<db::OrientationReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:m0 *1 1,100");
}
TEST(12_TwoLevelsStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (0, false, db::Vector (1, 10))));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (1, false, db::Vector (1, 100))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::Trans (0, false, db::Vector (2, 10))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::Trans (0, true, db::Vector (2, 100))));
db::OrientationReducer red;
db::cell_variants_statistics<db::OrientationReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r90 *1 1,100");
EXPECT_EQ (inst2str (ly, b), "C:r0 *1 2,10;C:m0 *1 2,100");
}
TEST(13_ThreeLevelsStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (0, false, db::Vector (1, 10))));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (1, false, db::Vector (1, 100))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::Trans (0, false, db::Vector (2, 10))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::Trans (0, true, db::Vector (2, 100))));
c.insert (db::CellInstArray (db::CellInst (d.cell_index ()), db::Trans (1, true, db::Vector (0, 0))));
db::OrientationReducer red;
db::cell_variants_statistics<db::OrientationReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "r270 *1 0,0[1];m90 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1]");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r90 *1 1,100");
EXPECT_EQ (inst2str (ly, b), "C:r0 *1 2,10;C:m0 *1 2,100");
EXPECT_EQ (inst2str (ly, c), "D:m45 *1 0,0");
}
TEST(14_ComplexTransStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::ICplxTrans (db::Trans (0, false, db::Vector (1, 10)))));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::ICplxTrans (db::Trans (1, false, db::Vector (1, 100)))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::ICplxTrans (db::Trans (0, false, db::Vector (2, 10)))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::ICplxTrans (db::Trans (0, true, db::Vector (2, 100)))));
db::OrientationReducer red;
db::cell_variants_statistics<db::OrientationReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
TEST(15_ArraysStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (0, false, db::Vector (1, 10)), db::Vector (0, 100), db::Vector (100, 0), 10, 10));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::Trans (1, false, db::Vector (1, 100))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::Trans (0, false, db::Vector (2, 10)), db::Vector (0, 101), db::Vector (101, 0), 10, 10));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::Trans (0, true, db::Vector (2, 100))));
db::OrientationReducer red;
db::cell_variants_statistics<db::OrientationReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[100];r90 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[100];r0 *1 0,0[10000];m45 *1 0,0[1];r90 *1 0,0[100]");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
TEST(16_ScalingVariantsStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::ICplxTrans (1.5, 0, false, db::Vector (1, 10)), db::Vector (0, 100), db::Vector (100, 0), 10, 10));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::ICplxTrans (1.0, 90.0, false, db::Vector (1, 100))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::ICplxTrans (2.0, 0, false, db::Vector (2, 10)), db::Vector (0, 101), db::Vector (101, 0), 10, 10));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::ICplxTrans (1.0, 0, true, db::Vector (2, 100))));
db::MagnificationReducer red;
db::cell_variants_statistics<db::MagnificationReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r0 *1.5 0,0[100]");
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 0,0[1];r0 *1.5 0,0[100];r0 *2 0,0[100];r0 *3 0,0[10000]");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
TEST(17_GridVariantsStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::ICplxTrans (1.0, 0, false, db::Vector (1, 10)), db::Vector (0, 101), db::Vector (102, 0), 2, 2));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::ICplxTrans (1.0, 0, false, db::Vector (2, 3))));
db::GridReducer red (10);
db::cell_variants_statistics<db::GridReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 1,0[1];r0 *1 3,0[1];r0 *1 1,1[1];r0 *1 3,1[1]");
// placements are:
// b in a: r0 *1 x=1,1+102 y=10,10+101
// c in b: r0 *1 x=2,y=3
// expanded placements:
// c in a: r0 *2 x=1,1+102 y=10,10+101 x r0 *1 x=2,y=3
// = (3,13),(105,13),(3,114),(105,114)
// expanded placements mod 10:
// c in a: r0 *2 x=1,1+102 y=10,10+101 x r0 *1 x=2,y=3
// = (3,3),(5,3),(3,4),(5,4)
EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 -5,3[1];r0 *1 3,3[1];r0 *1 -5,4[1];r0 *1 3,4[1]");
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r0 *1 1,111;B:r0 *1 103,10;B:r0 *1 103,111");
EXPECT_EQ (inst2str (ly, b), "C:r0 *1 2,3");
EXPECT_EQ (inst2str (ly, c), "");
}
TEST(18_ComplexGridVariantsStatistics)
{
db::Layout ly;
db::Cell &a = ly.cell (ly.add_cell ("A"));
db::Cell &b = ly.cell (ly.add_cell ("B"));
db::Cell &c = ly.cell (ly.add_cell ("C"));
db::Cell &d = ly.cell (ly.add_cell ("D"));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::ICplxTrans (2.0, 0, false, db::Vector (1, 10)), db::Vector (0, 101), db::Vector (102, 0), 2, 2));
a.insert (db::CellInstArray (db::CellInst (b.cell_index ()), db::ICplxTrans (1.0, 90.0, false, db::Vector (1, 100))));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::ICplxTrans (2.0, 0, false, db::Vector (2, 10)), db::Vector (0, 103), db::Vector (105, 0), 2, 2));
b.insert (db::CellInstArray (db::CellInst (c.cell_index ()), db::ICplxTrans (1.0, 0, true, db::Vector (2, 100))));
db::GridReducer red (10);
db::cell_variants_statistics<db::GridReducer> vb (red);
vb.collect (&ly, a.cell_index ());
EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]");
EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *2 1,0[1];r90 *1 1,0[1];r0 *2 3,0[1];r0 *2 1,1[1];r0 *2 3,1[1]");
@ -370,29 +652,6 @@ TEST(9_ComplexGridVariants)
EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "");
}
TEST(100_OrientationVariantsWithLayout)
{
db::Layout ly;
{
std::string fn (tl::testdata ());
fn += "/algo/deep_region_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::OrientationReducer red;
db::cell_variants_collector<db::OrientationReducer> vb (red);
vb.collect (ly, top_cell);
vb.separate_variants (ly, top_cell);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testdata () + "/algo/cell_variants_au1.gds");
}
TEST(101_Propagation)
{
db::Layout ly;
@ -413,25 +672,25 @@ TEST(101_Propagation)
unsigned int l2 = ly.insert_layer (db::LayerProperties (2, 0));
db::cell_variants_collector<db::MagnificationAndOrientationReducer> vb;
vb.collect (ly, top_cell);
vb.collect (&ly, top_cell.cell_index ());
for (db::Layout::const_iterator c = ly.begin (); c != ly.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &vv = vb.variants (c->cell_index ());
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
const std::set<db::ICplxTrans> &vv = vb.variants (c->cell_index ());
for (auto v = vv.begin (); v != vv.end (); ++v) {
db::Shapes &out = to_commit [c->cell_index ()][v->first];
db::Shapes &out = to_commit [c->cell_index ()][*v];
for (db::Shapes::shape_iterator s = c->shapes (l1).begin (db::ShapeIterator::All); ! s.at_end (); ++s) {
db::Box b = s->bbox ().transformed (v->first);
db::Box b = s->bbox ().transformed (*v);
b.enlarge (db::Vector (-100, 0));
out.insert (b.transformed (v->first.inverted ()));
out.insert (b.transformed (v->inverted ()));
}
}
}
vb.commit_shapes (ly, top_cell, l2, to_commit);
vb.commit_shapes (l2, to_commit);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testdata () + "/algo/cell_variants_au2.gds");

View File

@ -61,7 +61,7 @@ public:
// .. nothing yet ..
}
virtual void do_compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
virtual void do_compute_local (db::Layout *layout, db::Cell *cell, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions;
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
@ -73,7 +73,7 @@ public:
}
}
db::BoolAndOrNotLocalOperation::do_compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio);
db::BoolAndOrNotLocalOperation::do_compute_local (layout, cell, sized_interactions, results, proc);
}
db::Coord dist () const
@ -98,7 +98,7 @@ public:
// .. nothing yet ..
}
virtual void do_compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
virtual void do_compute_local (db::Layout *layout, db::Cell *cell, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase *proc) const
{
db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions;
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
@ -119,7 +119,7 @@ public:
}
SelfOverlapMergeLocalOperation::do_compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio);
SelfOverlapMergeLocalOperation::do_compute_local (layout, cell, sized_interactions, results, proc);
}
db::Coord dist () const

View File

@ -1566,3 +1566,54 @@ TEST(70d_props)
{
run_test (_this, "70", true);
}
TEST(80_deep_with_mag_width)
{
run_test (_this, "80", true);
}
TEST(81_deep_with_mag_space)
{
run_test (_this, "81", true);
}
TEST(82_deep_with_mag_cop_width)
{
run_test (_this, "82", true);
}
TEST(83_deep_with_mag_cop_space)
{
run_test (_this, "83", true);
}
TEST(84_deep_with_mag_edge_width)
{
run_test (_this, "84", true);
}
TEST(85_deep_with_mag_edge_space)
{
run_test (_this, "85", true);
}
TEST(86_deep_with_mag_size)
{
run_test (_this, "86", true);
}
TEST(87_deep_with_mag_size_aniso)
{
run_test (_this, "87", true);
}
TEST(88_deep_with_mag_cop_size)
{
run_test (_this, "88", true);
}
TEST(89_deep_with_mag_cop_size_aniso)
{
run_test (_this, "89", true);
}

Binary file not shown.

Binary file not shown.

View File

@ -28,5 +28,5 @@ l1.drc(middle).output(110, 0)
l1.drc(middle(as_dots)).output(111, 0)
l1.drc(middle(as_boxes)).output(112, 0)
l1.drc(extent_refs(0.0, 0.0, 0.25, 0.5, as_edges)).output(113, 0)
l1.drc(extent_refs(0.0, 0.0, 0.25, 0.5, 0.5, 1.0, as_boxes)).output(114, 0)
l1.drc(extent_refs(0.0, 0.0, 0.25, 0.5, as_boxes)).output(114, 0)

Binary file not shown.

Binary file not shown.

Binary file not shown.

14
testdata/drc/drcSimpleTests_80.drc vendored Normal file
View File

@ -0,0 +1,14 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.width(0.4).output(100, 0)
l1.width(0.9).output(101, 0)
l1.width(1.1).output(102, 0)

BIN
testdata/drc/drcSimpleTests_80.gds vendored Normal file

Binary file not shown.

14
testdata/drc/drcSimpleTests_81.drc vendored Normal file
View File

@ -0,0 +1,14 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.space(0.4, projection).output(100, 0)
l1.space(0.9, projection).output(101, 0)
l1.space(1.1, projection).output(102, 0)

BIN
testdata/drc/drcSimpleTests_81.gds vendored Normal file

Binary file not shown.

14
testdata/drc/drcSimpleTests_82.drc vendored Normal file
View File

@ -0,0 +1,14 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.drc(width < 0.4).output(100, 0)
l1.drc(width < 0.9).output(101, 0)
l1.drc(width < 1.1).output(102, 0)

BIN
testdata/drc/drcSimpleTests_82.gds vendored Normal file

Binary file not shown.

14
testdata/drc/drcSimpleTests_83.drc vendored Normal file
View File

@ -0,0 +1,14 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.drc(space(projection) < 0.4).output(100, 0)
l1.drc(space(projection) < 0.9).output(101, 0)
l1.drc(space(projection) < 1.1).output(102, 0)

BIN
testdata/drc/drcSimpleTests_83.gds vendored Normal file

Binary file not shown.

14
testdata/drc/drcSimpleTests_84.drc vendored Normal file
View File

@ -0,0 +1,14 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.edges.width(0.4, projection).output(100, 0)
l1.edges.width(0.9, projection).output(101, 0)
l1.edges.width(1.1, projection).output(102, 0)

BIN
testdata/drc/drcSimpleTests_84.gds vendored Normal file

Binary file not shown.

14
testdata/drc/drcSimpleTests_85.drc vendored Normal file
View File

@ -0,0 +1,14 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.edges.space(0.4, projection).output(100, 0)
l1.edges.space(0.9, projection).output(101, 0)
l1.edges.space(1.1, projection).output(102, 0)

BIN
testdata/drc/drcSimpleTests_85.gds vendored Normal file

Binary file not shown.

13
testdata/drc/drcSimpleTests_86.drc vendored Normal file
View File

@ -0,0 +1,13 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.sized(0.2).output(100, 0)
l1.sized(-0.2).output(101, 0)

BIN
testdata/drc/drcSimpleTests_86.gds vendored Normal file

Binary file not shown.

15
testdata/drc/drcSimpleTests_87.drc vendored Normal file
View File

@ -0,0 +1,15 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.sized(0.2, 0.0).output(100, 0)
l1.sized(0.0, 0.2).output(101, 0)
l1.sized(-0.2, 0.0).output(102, 0)
l1.sized(0.0, -0.2).output(103, 0)

BIN
testdata/drc/drcSimpleTests_87.gds vendored Normal file

Binary file not shown.

13
testdata/drc/drcSimpleTests_88.drc vendored Normal file
View File

@ -0,0 +1,13 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.drc(sized(0.2)).output(100, 0)
l1.drc(sized(-0.2)).output(101, 0)

BIN
testdata/drc/drcSimpleTests_88.gds vendored Normal file

Binary file not shown.

15
testdata/drc/drcSimpleTests_89.drc vendored Normal file
View File

@ -0,0 +1,15 @@
source $drc_test_source
target $drc_test_target
deep
l1 = input(1, 0)
l1.output(1, 0)
l1.drc(sized(0.2, 0.0)).output(100, 0)
l1.drc(sized(0.0, 0.2)).output(101, 0)
l1.drc(sized(-0.2, 0.0)).output(102, 0)
l1.drc(sized(0.0, -0.2)).output(103, 0)

BIN
testdata/drc/drcSimpleTests_89.gds vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au80d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au81d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au82d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au83d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au84d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au85d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au86d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au87d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au88d.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au89d.gds vendored Normal file

Binary file not shown.