Experimental: sparse cell variants table

This commit is contained in:
Matthias Koefferlein 2023-11-18 21:21:00 +01:00
parent d0172d57f3
commit b0648e1c45
11 changed files with 224 additions and 199 deletions

View File

@ -230,32 +230,45 @@ VariantsCollectorBase::collect (const db::Layout &layout, const db::Cell &top_ce
{
tl_assert (mp_red != 0);
// 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 (top_cell.cell_index ());
std::set<db::cell_index_type> called;
top_cell.collect_called_cells (called);
top_cell.collect_called_cells (m_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 ()) {
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;
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::map<db::ICplxTrans, size_t> &variants = variants_per_parent_cell [pi->inst ().object ().cell_index ()];
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);
}
}
@ -287,8 +300,8 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell
db::Cell &cell = 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];
@ -302,11 +315,11 @@ 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);
var_name += "$VAR" + tl::to_string (index);
@ -316,21 +329,27 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell
copy_shapes (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 (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 {
@ -352,7 +371,12 @@ 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 ());
}
}
@ -387,14 +411,14 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
db::Cell &cell = 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;
@ -406,11 +430,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) {
@ -431,7 +455,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);
@ -442,7 +466,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;
@ -450,7 +474,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 ()) {
@ -474,22 +501,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;
}
@ -498,7 +552,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);
@ -508,35 +562,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));
}
}
}
@ -564,9 +618,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);
@ -626,9 +680,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);

View File

@ -216,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
@ -229,13 +237,14 @@ 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;
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;

View File

@ -432,7 +432,7 @@ public:
virtual bool is_translation_invariant () const;
// NOTE: equality does not really matter here as we use it only on leaf reducers
virtual bool equals (const TransformationReducer *other) const { return false; }
virtual bool equals (const TransformationReducer * /*other*/) const { return false; }
private:
std::vector<const db::TransformationReducer *> m_vars;
@ -1161,9 +1161,7 @@ private:
// in the presence of variants, handle the object in top level space
const std::map<db::ICplxTrans, size_t> &vv = proc->vars ()->variants (cell->cell_index ());
tl_assert (vv.size () == 1);
const db::ICplxTrans &tr = vv.begin ()->first;
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ());
processed (layout, *p, tr, res);
} else {
@ -1314,9 +1312,7 @@ private:
// in the presence of variants, handle the object in top level space
const std::map<db::ICplxTrans, size_t> &vv = proc->vars ()->variants (cell->cell_index ());
tl_assert (vv.size () == 1);
const db::ICplxTrans &tr = vv.begin ()->first;
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ());
processed (layout, tr * *p, res);
if (! res.empty ()) {
@ -1383,9 +1379,7 @@ private:
// in the presence of variants, handle the object in top level space
const std::map<db::ICplxTrans, size_t> &vv = proc->vars ()->variants (cell->cell_index ());
tl_assert (vv.size () == 1);
const db::ICplxTrans &tr = vv.begin ()->first;
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ());
processed (layout, tr * *p, res);
if (! res.empty ()) {
@ -1453,9 +1447,7 @@ private:
// in the presence of variants, handle the object in top level space
const std::map<db::ICplxTrans, size_t> &vv = proc->vars ()->variants (cell->cell_index ());
tl_assert (vv.size () == 1);
const db::ICplxTrans &tr = vv.begin ()->first;
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ());
processed (layout, tr * *p, res);
if (! res.empty ()) {
@ -1520,9 +1512,7 @@ private:
// in the presence of variants, handle the object in top level space
const std::map<db::ICplxTrans, size_t> &vv = proc->vars ()->variants (cell->cell_index ());
tl_assert (vv.size () == 1);
const db::ICplxTrans &tr = vv.begin ()->first;
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ());
mp_proc->process (tr * *p, res);
if (! res.empty ()) {
@ -1592,9 +1582,7 @@ private:
// in the presence of variants, handle the object in top level space
const std::map<db::ICplxTrans, size_t> &vv = proc->vars ()->variants (cell->cell_index ());
tl_assert (vv.size () == 1);
const db::ICplxTrans &tr = vv.begin ()->first;
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ());
processed (layout, *p, tr, res);
} else {
@ -1667,9 +1655,7 @@ private:
// in the presence of variants, handle the object in top level space
const std::map<db::ICplxTrans, size_t> &vv = proc->vars ()->variants (cell->cell_index ());
tl_assert (vv.size () == 1);
const db::ICplxTrans &tr = vv.begin ()->first;
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ());
processed (layout, *p, tr, res);
} else {

View File

@ -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))) {

View File

@ -256,10 +256,8 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
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 ());
@ -750,10 +748,10 @@ DeepEdges::length_type DeepEdges::length (const db::Box &box) const
for (db::ShapeIterator s = layout.cell (*c).shapes (edges.layer ()).begin (db::ShapeIterator::Edges); ! s.at_end (); ++s) {
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) {
double mag = v->first.mag ();
l += v->second * lc * mag;
const std::set<db::ICplxTrans> &vv = vars.variants (*c);
for (auto v = vv.begin (); v != vv.end (); ++v) {
double mag = v->mag ();
// @@@ l += v->second * lc * mag;
}
}
@ -836,20 +834,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);
}
}
@ -1279,14 +1275,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 +1291,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 +1314,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 ()));
}
}

View File

@ -264,10 +264,8 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
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 ());
@ -1122,10 +1120,10 @@ DeepRegion::area (const db::Box &box) const
for (db::ShapeIterator s = layout.cell (*c).shapes (polygons.layer ()).begin (db::ShapeIterator::All); ! s.at_end (); ++s) {
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) {
double mag = v->first.mag ();
a += v->second * ac * mag * mag;
const std::set<db::ICplxTrans> &vv = vars.variants (*c);
for (auto v = vv.begin (); v != vv.end (); ++v) {
double mag = v->mag ();
// @@@ a += v->second * ac * mag * mag;
}
}
@ -1159,10 +1157,10 @@ DeepRegion::perimeter (const db::Box &box) const
for (db::ShapeIterator s = layout.cell (*c).shapes (polygons.layer ()).begin (db::ShapeIterator::All); ! s.at_end (); ++s) {
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) {
double mag = v->first.mag ();
p += v->second * pc * mag;
const std::set<db::ICplxTrans> &vv = vars.variants (*c);
for (auto v = vv.begin (); v != vv.end (); ++v) {
double mag = v->mag ();
// @@@ p += v->second * pc * mag;
}
}
@ -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);
}
@ -1311,9 +1309,7 @@ DeepRegion::snapped (db::Coord gx, db::Coord gy)
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 ());
@ -1385,9 +1381,7 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
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 ());
@ -1506,22 +1500,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);
}
}
@ -1663,9 +1655,8 @@ DeepRegion::sized (coord_type d, unsigned int mode) const
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 ());
@ -1719,10 +1710,9 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
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);
@ -2020,9 +2010,8 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c
std::unique_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (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);
EdgeRelationFilter check (rel, d_with_mag, options.metrics);

View File

@ -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);
}
}

View File

@ -1491,10 +1491,8 @@ LocalProcessorBase::dist_for_cell (db::cell_index_type cell_index, db::Coord dis
{
if (mp_vars) {
const std::map<db::ICplxTrans, size_t> &v = mp_vars->variants (cell_index);
tl_assert (v.size () == size_t (1));
double mag = v.begin ()->first.mag ();
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 {

View File

@ -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

@ -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) {

View File

@ -27,17 +27,14 @@
#include "tlUnitTest.h"
#include "tlStream.h"
std::string var2str (const std::map<db::ICplxTrans, size_t> &vars)
std::string var2str (const std::set<db::ICplxTrans> &vars)
{
std::string res;
for (std::map<db::ICplxTrans, size_t>::const_iterator i = vars.begin (); i != vars.end (); ++i) {
for (auto i = vars.begin (); i != vars.end (); ++i) {
if (! res.empty ()) {
res += ";";
}
res += i->first.to_string ();
res += "[";
res += tl::to_string (i->second);
res += "]";
res += i->to_string ();
}
return res;
}
@ -94,8 +91,8 @@ 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]");
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 ())), "");
@ -119,8 +116,8 @@ 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]");
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 ())), "");
@ -148,9 +145,9 @@ 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]");
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");
@ -182,10 +179,10 @@ 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]");
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");
@ -220,9 +217,9 @@ 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]");
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 ())), "");
}
@ -243,9 +240,9 @@ 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]");
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 ())), "");
}
@ -265,9 +262,9 @@ 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]");
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 ())), "");
}
@ -285,8 +282,8 @@ 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]");
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 +294,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");
@ -332,8 +329,8 @@ TEST(9_ComplexGridVariants)
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 *2 1,0[1];r90 *1 1,0[1];r0 *2 3,0[1];r0 *2 1,1[1];r0 *2 3,1[1]");
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
@ -364,9 +361,9 @@ TEST(9_ComplexGridVariants)
// (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[2];r0 *4 -3,-4[2];r0 *4 -5,-3[2];r0 *4 -3,-3[2];r90 *2 -2,-3[1];"
"r90 *2 1,-3[1];m0 *2 -5,0[1];r0 *4 -5,0[2];m0 *2 -3,0[1];r0 *4 -3,0[2];"
"m0 *2 -5,1[1];r0 *4 -5,1[2];m0 *2 -3,1[1];r0 *4 -3,1[2];r90 *2 -2,2[1];m45 *1 1,2[1];r90 *2 1,2[1]");
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 ())), "");
}
@ -417,14 +414,14 @@ TEST(101_Propagation)
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 ()));
}
}