Some optimization: keep merged state in deep region.

This commit is contained in:
Matthias Koefferlein 2019-02-13 17:17:03 +01:00
parent 68947bedd2
commit ddcfda8761
8 changed files with 168 additions and 58 deletions

View File

@ -122,7 +122,8 @@ DeepEdges::~DeepEdges ()
DeepEdges::DeepEdges (const DeepEdges &other) DeepEdges::DeepEdges (const DeepEdges &other)
: AsIfFlatEdges (other), : AsIfFlatEdges (other),
m_deep_layer (other.m_deep_layer.copy ()), m_deep_layer (other.m_deep_layer.copy ()),
m_merged_edges_valid (other.m_merged_edges_valid) m_merged_edges_valid (other.m_merged_edges_valid),
m_is_merged (other.m_is_merged)
{ {
if (m_merged_edges_valid) { if (m_merged_edges_valid) {
m_merged_edges = other.m_merged_edges; m_merged_edges = other.m_merged_edges;
@ -133,6 +134,7 @@ void DeepEdges::init ()
{ {
m_merged_edges_valid = false; m_merged_edges_valid = false;
m_merged_edges = db::DeepLayer (); m_merged_edges = db::DeepLayer ();
m_is_merged = false;
} }
EdgesDelegate * EdgesDelegate *
@ -215,8 +217,7 @@ DeepEdges::empty () const
bool bool
DeepEdges::is_merged () const DeepEdges::is_merged () const
{ {
// TODO: there is no such thing as a "surely merged" state except after merged() maybe return m_is_merged;
return false;
} }
const db::Edge * const db::Edge *
@ -354,6 +355,13 @@ DeepEdges::ensure_merged_edges_valid () const
{ {
if (! m_merged_edges_valid) { if (! m_merged_edges_valid) {
if (m_is_merged) {
// NOTE: this will reuse the deep layer reference
m_merged_edges = m_deep_layer;
} else {
m_merged_edges = m_deep_layer.derived (); m_merged_edges = m_deep_layer.derived ();
tl::SelfTimer timer (tl::verbosity () > base_verbosity (), "Ensure merged polygons"); tl::SelfTimer timer (tl::verbosity () > base_verbosity (), "Ensure merged polygons");
@ -385,11 +393,20 @@ DeepEdges::ensure_merged_edges_valid () const
} }
} }
}
m_merged_edges_valid = true; m_merged_edges_valid = true;
} }
} }
void
DeepEdges::set_is_merged (bool f)
{
m_is_merged = f;
m_merged_edges_valid = false;
}
void void
DeepEdges::insert_into (db::Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const DeepEdges::insert_into (db::Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{ {
@ -485,8 +502,7 @@ EdgesDelegate *DeepEdges::merged () const
c->shapes (res->deep_layer ().layer ()) = c->shapes (m_merged_edges.layer ()); c->shapes (res->deep_layer ().layer ()) = c->shapes (m_merged_edges.layer ());
} }
res->deep_layer ().layer (); res->set_is_merged (true);
return res.release (); return res.release ();
} }
@ -549,6 +565,7 @@ DeepEdges::add_in_place (const Edges &other)
} }
set_is_merged (false);
return this; return this;
} }

View File

@ -155,13 +155,17 @@ public:
protected: protected:
virtual void merged_semantics_changed (); virtual void merged_semantics_changed ();
void set_is_merged (bool f);
private: private:
friend class DeepRegion;
DeepEdges &operator= (const DeepEdges &other); DeepEdges &operator= (const DeepEdges &other);
DeepLayer m_deep_layer; DeepLayer m_deep_layer;
mutable DeepLayer m_merged_edges; mutable DeepLayer m_merged_edges;
mutable bool m_merged_edges_valid; mutable bool m_merged_edges_valid;
bool m_is_merged;
void init (); void init ();
void ensure_merged_edges_valid () const; void ensure_merged_edges_valid () const;

View File

@ -133,7 +133,8 @@ DeepRegion::~DeepRegion ()
DeepRegion::DeepRegion (const DeepRegion &other) DeepRegion::DeepRegion (const DeepRegion &other)
: AsIfFlatRegion (other), : AsIfFlatRegion (other),
m_deep_layer (other.m_deep_layer.copy ()), m_deep_layer (other.m_deep_layer.copy ()),
m_merged_polygons_valid (other.m_merged_polygons_valid) m_merged_polygons_valid (other.m_merged_polygons_valid),
m_is_merged (other.m_is_merged)
{ {
if (m_merged_polygons_valid) { if (m_merged_polygons_valid) {
m_merged_polygons = other.m_merged_polygons; m_merged_polygons = other.m_merged_polygons;
@ -144,6 +145,7 @@ void DeepRegion::init ()
{ {
m_merged_polygons_valid = false; m_merged_polygons_valid = false;
m_merged_polygons = db::DeepLayer (); m_merged_polygons = db::DeepLayer ();
m_is_merged = false;
} }
RegionDelegate * RegionDelegate *
@ -226,8 +228,7 @@ DeepRegion::empty () const
bool bool
DeepRegion::is_merged () const DeepRegion::is_merged () const
{ {
// TODO: there is no such thing as a "surely merged" state except after merged() maybe return m_is_merged;
return false;
} }
const db::Polygon * const db::Polygon *
@ -368,6 +369,13 @@ DeepRegion::ensure_merged_polygons_valid () const
{ {
if (! m_merged_polygons_valid) { if (! m_merged_polygons_valid) {
if (m_is_merged) {
// NOTE: this will reuse the deep layer reference
m_merged_polygons = m_deep_layer;
} else {
m_merged_polygons = m_deep_layer.derived (); m_merged_polygons = m_deep_layer.derived ();
tl::SelfTimer timer (tl::verbosity () > base_verbosity (), "Ensure merged polygons"); tl::SelfTimer timer (tl::verbosity () > base_verbosity (), "Ensure merged polygons");
@ -399,11 +407,20 @@ DeepRegion::ensure_merged_polygons_valid () const
} }
} }
}
m_merged_polygons_valid = true; m_merged_polygons_valid = true;
} }
} }
void
DeepRegion::set_is_merged (bool f)
{
m_is_merged = f;
m_merged_polygons_valid = false;
}
void void
DeepRegion::insert_into (db::Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const DeepRegion::insert_into (db::Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{ {
@ -530,6 +547,7 @@ DeepRegion::add_in_place (const Region &other)
} }
set_is_merged (false);
return this; return this;
} }
@ -785,9 +803,17 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
} }
res->set_is_merged (true);
return db::Edges (res.release ()); return db::Edges (res.release ());
} }
RegionDelegate *
DeepRegion::filter_in_place (const PolygonFilterBase &filter)
{
// TODO: implement to be really in-place
return filtered (filter);
}
RegionDelegate * RegionDelegate *
DeepRegion::filtered (const PolygonFilterBase &filter) const DeepRegion::filtered (const PolygonFilterBase &filter) const
{ {
@ -828,6 +854,7 @@ DeepRegion::filtered (const PolygonFilterBase &filter) const
} }
res->set_is_merged (true);
return res.release (); return res.release ();
} }
@ -839,6 +866,7 @@ DeepRegion::merged_in_place ()
// NOTE: this makes both layers share the same resource // NOTE: this makes both layers share the same resource
m_deep_layer = m_merged_polygons; m_deep_layer = m_merged_polygons;
set_is_merged (true);
return this; return this;
} }
@ -863,6 +891,7 @@ DeepRegion::merged () const
res->deep_layer ().layer (); res->deep_layer ().layer ();
res->set_is_merged (true);
return res.release (); return res.release ();
} }
@ -915,6 +944,12 @@ DeepRegion::sized (coord_type d, unsigned int mode) const
} }
// in case of negative sizing the output polygons will still be merged (on positive sizing they might
// overlap after size and are not necessarily merged)
if (d < 0) {
res->set_is_merged (true);
}
return res.release (); return res.release ();
} }
@ -989,6 +1024,12 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
} }
// in case of negative sizing the output polygons will still be merged (on positive sizing they might
// overlap after size and are not necessarily merged)
if (dx < 0 && dy < 0) {
res->set_is_merged (true);
}
return res.release (); return res.release ();
} }
@ -1022,6 +1063,7 @@ DeepRegion::holes () const
} }
res->set_is_merged (true);
return res.release (); return res.release ();
} }
@ -1053,6 +1095,7 @@ DeepRegion::hulls () const
} }
res->set_is_merged (true);
return res.release (); return res.release ();
} }
@ -1250,7 +1293,7 @@ DeepRegion::selected_interacting_generic (const Region &other, int mode, bool to
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
proc.set_base_verbosity (base_verbosity ()); proc.set_base_verbosity (base_verbosity ());
proc.set_threads (m_deep_layer.store ()->threads ()); proc.set_threads (m_deep_layer.store ()->threads ());
#if 0 #if defined(SPLIT )
// with these settings, the resulting polygons are broken again ... // with these settings, the resulting polygons are broken again ...
proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ()); proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ());
proc.set_max_vertex_count (m_deep_layer.store ()->max_vertex_count ()); proc.set_max_vertex_count (m_deep_layer.store ()->max_vertex_count ());
@ -1258,8 +1301,9 @@ DeepRegion::selected_interacting_generic (const Region &other, int mode, bool to
proc.run (&op, m_merged_polygons.layer (), other_deep->merged_deep_layer ().layer (), dl_out.layer ()); proc.run (&op, m_merged_polygons.layer (), other_deep->merged_deep_layer ().layer (), dl_out.layer ());
// TODO: mark the results as merged (unless we split - see above) db::DeepRegion *res = new db::DeepRegion (dl_out);
return new db::DeepRegion (dl_out); res->set_is_merged (true);
return res;
} }
RegionDelegate * RegionDelegate *

View File

@ -138,11 +138,7 @@ public:
virtual Edges edges (const EdgeFilterBase *) const; virtual Edges edges (const EdgeFilterBase *) const;
virtual RegionDelegate *filter_in_place (const PolygonFilterBase &filter) virtual RegionDelegate *filter_in_place (const PolygonFilterBase &filter);
{
return filtered (filter);
}
virtual RegionDelegate *filtered (const PolygonFilterBase &filter) const; virtual RegionDelegate *filtered (const PolygonFilterBase &filter) const;
virtual RegionDelegate *merged_in_place (); virtual RegionDelegate *merged_in_place ();
@ -226,6 +222,7 @@ public:
protected: protected:
virtual void merged_semantics_changed (); virtual void merged_semantics_changed ();
void set_is_merged (bool f);
private: private:
DeepRegion &operator= (const DeepRegion &other); DeepRegion &operator= (const DeepRegion &other);
@ -233,6 +230,7 @@ private:
DeepLayer m_deep_layer; DeepLayer m_deep_layer;
mutable DeepLayer m_merged_polygons; mutable DeepLayer m_merged_polygons;
mutable bool m_merged_polygons_valid; mutable bool m_merged_polygons_valid;
bool m_is_merged;
void init (); void init ();
void ensure_merged_polygons_valid () const; void ensure_merged_polygons_valid () const;

View File

@ -183,6 +183,7 @@ protected:
private: private:
friend class AsIfFlatRegion; friend class AsIfFlatRegion;
friend class Region;
db::Shapes &raw_polygons () { return m_polygons; } db::Shapes &raw_polygons () { return m_polygons; }

View File

@ -162,6 +162,9 @@ Region::flat_region ()
region->RegionDelegate::operator= (*mp_delegate); region->RegionDelegate::operator= (*mp_delegate);
region->insert_seq (begin ()); region->insert_seq (begin ());
} }
if (mp_delegate) {
region->set_is_merged (mp_delegate->is_merged ());
}
set_delegate (region); set_delegate (region);
} }

View File

@ -60,6 +60,7 @@ TEST(1)
EXPECT_EQ (regions.back ().size (), db::Region (iter).size ()); EXPECT_EQ (regions.back ().size (), db::Region (iter).size ());
EXPECT_EQ (regions.back ().bbox (), db::Region (iter).bbox ()); EXPECT_EQ (regions.back ().bbox (), db::Region (iter).bbox ());
EXPECT_EQ (regions.back ().is_merged (), false);
} }
@ -71,6 +72,26 @@ TEST(1)
CHECKPOINT(); CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au1.gds"); db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au1.gds");
// some operations
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
db::Region r2 (db::RecursiveShapeIterator (ly, ly.cell (top_cell_index), l2), dss);
db::Region r3 (db::RecursiveShapeIterator (ly, ly.cell (top_cell_index), l3), dss);
EXPECT_EQ (r2.is_merged (), false);
r2.merge ();
EXPECT_EQ (r2.is_merged (), true);
r2 += r3;
EXPECT_EQ (r2.is_merged (), false);
EXPECT_EQ (r2.merged ().is_merged (), true);
EXPECT_EQ (r2.is_merged (), false);
r2.merge ();
EXPECT_EQ (r2.is_merged (), true);
r2.flatten ();
EXPECT_EQ (r2.is_merged (), true);
r2.insert (db::Box (0, 0, 1000, 2000));
EXPECT_EQ (r2.is_merged (), false);
} }
TEST(2) TEST(2)
@ -154,6 +175,8 @@ TEST(3_BoolAndNot)
db::Region r42and3 = r42 & r3; db::Region r42and3 = r42 & r3;
db::Region r42and42 = r42 & r42; db::Region r42and42 = r42 & r42;
EXPECT_EQ (r2and3.is_merged (), false);
db::Layout target; db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
@ -278,6 +301,8 @@ TEST(5_BoolXOR)
db::Region r42xor3 = r42 ^ r3; db::Region r42xor3 = r42 ^ r3;
db::Region r42xor42 = r42 ^ r42; db::Region r42xor42 = r42 ^ r42;
EXPECT_EQ (r2xor3.is_merged (), false);
db::Layout target; db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
@ -439,7 +464,13 @@ TEST(9_SizingSimple)
db::Region r6 (db::RecursiveShapeIterator (ly, top_cell, l6), dss); db::Region r6 (db::RecursiveShapeIterator (ly, top_cell, l6), dss);
db::Region r6_sized = r6.sized (-50); db::Region r6_sized = r6.sized (-50);
EXPECT_EQ (r6_sized.is_merged (), true);
db::Region r6_sized_aniso = r6.sized (-20, -100); db::Region r6_sized_aniso = r6.sized (-20, -100);
EXPECT_EQ (r6_sized_aniso.is_merged (), true);
db::Region r6_sized_plus = r6.sized (50);
EXPECT_EQ (r6_sized_plus.is_merged (), false);
db::Region r6_sized_aniso_plus = r6.sized (20, 100);
EXPECT_EQ (r6_sized_aniso_plus.is_merged (), false);
db::Layout target; db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
@ -447,6 +478,8 @@ TEST(9_SizingSimple)
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r6); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r6);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r6_sized); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r6_sized);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r6_sized_aniso); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r6_sized_aniso);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), r6_sized_plus);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (14, 0)), r6_sized_aniso_plus);
CHECKPOINT(); CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au9a.gds"); db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au9a.gds");
@ -565,6 +598,7 @@ TEST(9_SizingWithBoolean)
r1_sized -= r1; r1_sized -= r1;
db::Region r1_sized_aniso = r1.sized (1000, 2000); db::Region r1_sized_aniso = r1.sized (1000, 2000);
r1_sized_aniso -= r1; r1_sized_aniso -= r1;
EXPECT_EQ (r1_sized_aniso.is_merged (), false);
db::Layout target; db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
@ -603,6 +637,8 @@ TEST(10_HullsAndHoles)
db::Region hulls = r1_sized.hulls (); db::Region hulls = r1_sized.hulls ();
db::Region holes = r1_sized.holes (); db::Region holes = r1_sized.holes ();
EXPECT_EQ (hulls.is_merged (), true);
EXPECT_EQ (holes.is_merged (), true);
db::Layout target; db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
@ -673,6 +709,7 @@ TEST(12_GridSnap)
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss); db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::Region r3snapped = r3.snapped (50, 50); db::Region r3snapped = r3.snapped (50, 50);
EXPECT_EQ (r3snapped.is_merged (), false);
db::Layout target; db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
@ -704,6 +741,7 @@ TEST(13_Edges)
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss); db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::Edges r3edges = r3.edges (); db::Edges r3edges = r3.edges ();
EXPECT_EQ (r3edges.is_merged (), true);
db::EdgeLengthFilter f (0, 500, true); db::EdgeLengthFilter f (0, 500, true);
db::Edges r3edges_filtered = r3.edges (f); db::Edges r3edges_filtered = r3.edges (f);
@ -764,6 +802,8 @@ TEST(14_Interacting)
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (26, 0)), r6.selected_overlapping (r1)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (26, 0)), r6.selected_overlapping (r1));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (27, 0)), r6.selected_not_overlapping (r1)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (27, 0)), r6.selected_not_overlapping (r1));
EXPECT_EQ (r2.selected_interacting (r1).is_merged (), true);
CHECKPOINT(); CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au14.gds"); db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au14.gds");
} }
@ -791,6 +831,9 @@ TEST(15_Filtered)
db::Region af1_filtered = r1.filtered (af1); db::Region af1_filtered = r1.filtered (af1);
db::RegionAreaFilter af1inv (0, 1000000000, true); db::RegionAreaFilter af1inv (0, 1000000000, true);
db::Region af1_else = r1.filtered (af1inv); db::Region af1_else = r1.filtered (af1inv);
EXPECT_EQ (af1_filtered.is_merged (), true);
EXPECT_EQ (af1_else.is_merged (), true);
{ {
db::Layout target; db::Layout target;

Binary file not shown.