mirror of https://github.com/KLayout/klayout.git
Refactoring with the goal to reduce the overhead for variant computation
This commit is contained in:
parent
b0648e1c45
commit
dd81fda27d
|
|
@ -706,5 +706,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, const db::Cell &top_cell)
|
||||
{
|
||||
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));
|
||||
|
||||
std::set<db::cell_index_type> called;
|
||||
top_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,6 +282,85 @@ 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, const db::Cell &top_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
|
||||
|
|
|
|||
|
|
@ -737,7 +737,7 @@ 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);
|
||||
db::cell_variants_statistics<db::MagnificationReducer> vars (red);
|
||||
vars.collect (edges.layout (), edges.initial_cell ());
|
||||
|
||||
DeepEdges::length_type l = 0;
|
||||
|
|
@ -748,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::set<db::ICplxTrans> &vv = vars.variants (*c);
|
||||
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (*c);
|
||||
for (auto v = vv.begin (); v != vv.end (); ++v) {
|
||||
double mag = v->mag ();
|
||||
// @@@ l += v->second * lc * mag;
|
||||
double mag = v->first.mag ();
|
||||
l += v->second * lc * mag;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1109,7 +1109,7 @@ DeepRegion::area (const db::Box &box) const
|
|||
|
||||
const db::DeepLayer &polygons = merged_deep_layer ();
|
||||
|
||||
db::cell_variants_collector<db::MagnificationReducer> vars;
|
||||
db::cell_variants_statistics<db::MagnificationReducer> vars;
|
||||
vars.collect (polygons.layout (), polygons.initial_cell ());
|
||||
|
||||
DeepRegion::area_type a = 0;
|
||||
|
|
@ -1120,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::set<db::ICplxTrans> &vv = vars.variants (*c);
|
||||
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (*c);
|
||||
for (auto v = vv.begin (); v != vv.end (); ++v) {
|
||||
double mag = v->mag ();
|
||||
// @@@ a += v->second * ac * mag * mag;
|
||||
double mag = v->first.mag ();
|
||||
a += v->second * ac * mag * mag;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1146,7 +1146,7 @@ DeepRegion::perimeter (const db::Box &box) const
|
|||
|
||||
const db::DeepLayer &polygons = merged_deep_layer ();
|
||||
|
||||
db::cell_variants_collector<db::MagnificationReducer> vars;
|
||||
db::cell_variants_statistics<db::MagnificationReducer> vars;
|
||||
vars.collect (polygons.layout (), polygons.initial_cell ());
|
||||
|
||||
DeepRegion::perimeter_type p = 0;
|
||||
|
|
@ -1157,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::set<db::ICplxTrans> &vv = vars.variants (*c);
|
||||
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (*c);
|
||||
for (auto v = vv.begin (); v != vv.end (); ++v) {
|
||||
double mag = v->mag ();
|
||||
// @@@ p += v->second * pc * mag;
|
||||
double mag = v->first.mag ();
|
||||
p += v->second * pc * mag;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,21 @@ std::string var2str (const std::set<db::ICplxTrans> &vars)
|
|||
return res;
|
||||
}
|
||||
|
||||
std::string var2str (const std::map<db::ICplxTrans, size_t> &vars)
|
||||
{
|
||||
std::string res;
|
||||
for (std::map<db::ICplxTrans, size_t>::const_iterator i = vars.begin (); i != vars.end (); ++i) {
|
||||
if (! res.empty ()) {
|
||||
res += ";";
|
||||
}
|
||||
res += i->first.to_string ();
|
||||
res += "[";
|
||||
res += tl::to_string (i->second);
|
||||
res += "]";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string vm2str (const db::Layout &ly, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &vm)
|
||||
{
|
||||
std::string res;
|
||||
|
|
@ -390,6 +405,254 @@ TEST(100_OrientationVariantsWithLayout)
|
|||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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]");
|
||||
|
||||
// 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[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 (d.cell_index ())), "");
|
||||
}
|
||||
|
||||
TEST(101_Propagation)
|
||||
{
|
||||
db::Layout ly;
|
||||
|
|
|
|||
Loading…
Reference in New Issue