diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index d5c1cbbfa..b14e1818c 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -27,6 +27,7 @@ #include "dbRegion.h" #include "dbShapeProcessor.h" #include "dbFlatRegion.h" +#include "dbHierProcessor.h" namespace db { @@ -111,6 +112,12 @@ DeepRegion::DeepRegion () init (); } +DeepRegion::DeepRegion (const DeepLayer &dl) + : AsIfFlatRegion (), m_deep_layer (dl) +{ + init (); +} + DeepRegion::~DeepRegion () { // .. nothing yet .. @@ -285,5 +292,67 @@ DeepRegion::insert_into (db::Layout *layout, db::cell_index_type into_cell, unsi m_deep_layer.insert_into (layout, into_cell, into_layer); } +RegionDelegate * +DeepRegion::and_with (const Region &other) const +{ + const DeepRegion *other_deep = dynamic_cast (other.delegate ()); + + if (empty () || other.empty ()) { + + // Nothing to do + return new EmptyRegion (); + + } else if (! other_deep) { + + return AsIfFlatRegion::and_with (other); + + } else { + + return new DeepRegion (and_or_not_with (other_deep, true)); + + } +} + +RegionDelegate * +DeepRegion::not_with (const Region &other) const +{ + const DeepRegion *other_deep = dynamic_cast (other.delegate ()); + + if (empty ()) { + + // Nothing to do + return new EmptyRegion (); + + } else if (other.empty () && ! strict_handling ()) { + + // Nothing to do + return clone (); + + } else if (! other_deep) { + + return AsIfFlatRegion::not_with (other); + + } else { + + return new DeepRegion (and_or_not_with (other_deep, false)); + + } +} + +DeepLayer +DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const +{ + DeepLayer dl_out (m_deep_layer.derived ()); + + db::BoolAndOrNotLocalOperation op (and_op); + + db::LocalProcessor proc (const_cast (m_deep_layer.layout ()), const_cast (m_deep_layer.initial_cell ()), other->deep_layer ().layout (), other->deep_layer ().initial_cell ()); + proc.set_threads (m_deep_layer.store ()->threads ()); + + proc.run (&op, m_deep_layer.layer (), other->deep_layer ().layer (), dl_out.layer ()); + + return dl_out; +} + } diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index 147162aa0..a69e6ff7f 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -70,13 +70,22 @@ public: virtual bool equals (const Region &other) const; virtual bool less (const Region &other) const; + virtual RegionDelegate *and_with (const Region &other) const; + virtual RegionDelegate *not_with (const Region &other) const; + virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const; + const DeepLayer &deep_layer () const + { + return m_deep_layer; + } + protected: virtual void merged_semantics_changed (); private: DeepRegion &operator= (const DeepRegion &other); + DeepRegion (const DeepLayer &dl); DeepLayer m_deep_layer; // @@@ have hierarchical merged polygons later @@ -85,6 +94,7 @@ private: void init (); void ensure_merged_polygons_valid () const; + DeepLayer and_or_not_with(const DeepRegion *other, bool and_op) const; }; } diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index b17a15b39..ed76dbaf5 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -55,6 +55,12 @@ DeepLayer::~DeepLayer () // .. nothing yet .. } +DeepLayer +DeepLayer::derived () const +{ + return DeepLayer (const_cast (mp_store.get ()), m_layout, const_cast (layout ())->insert_layer ()); +} + void DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const { @@ -76,6 +82,22 @@ DeepLayer::layout () const return const_cast (mp_store.get ())->layout (m_layout); } +db::Cell * +DeepLayer::initial_cell () +{ + db::Layout *ly = layout (); + tl_assert (ly->begin_top_down () != ly->end_top_down ()); + return &ly->cell (*ly->begin_top_down ()); +} + +const db::Cell * +DeepLayer::initial_cell () const +{ + const db::Layout *ly = layout (); + tl_assert (ly->begin_top_down () != ly->end_top_down ()); + return &ly->cell (*ly->begin_top_down ()); +} + void DeepLayer::check_dss () const { @@ -89,6 +111,7 @@ DeepLayer::check_dss () const static size_t s_instance_count = 0; DeepShapeStore::DeepShapeStore () + : m_threads (1) { ++s_instance_count; } @@ -103,6 +126,11 @@ size_t DeepShapeStore::instance_count () return s_instance_count; } +void DeepShapeStore::set_threads (int n) +{ + m_threads = n; +} + DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count) { unsigned int layout_index = 0; diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index 227213d36..e920ad788 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -80,6 +80,17 @@ public: */ const db::Layout *layout () const; + /** + * @brief Gets the layout object + * The return value is guaranteed to be non-null. + */ + db::Cell *initial_cell (); + + /** + * @brief Gets the initial cell object (const version) + */ + const db::Cell *initial_cell () const; + /** * @brief Gets the layer */ @@ -101,6 +112,24 @@ public: */ void insert_into (Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const; + /** + * @brief Creates a derived new deep layer + * Derived layers use the same layout and context, but are initially + * empty layers for use as output layers on the same hierarchy. + */ + DeepLayer derived () const; + + /** + * @brief Gets the shape store object + * This is a pure const version to prevent manipulation of the store. + * This method is intended to fetch configuration options from the store. + */ + const DeepShapeStore *store () const + { + check_dss (); + return mp_store.get (); + } + private: friend class DeepShapeStore; @@ -172,6 +201,21 @@ public: */ static size_t instance_count (); + /** + * @brief The deep shape store also keeps the number of threads to allocate for the hierarchical processor + * + * This is a kind of hack, but it's convenient. + */ + void set_threads (int n); + + /** + * @brief Gets the number of threads + */ + int threads () const + { + return m_threads; + } + private: friend class DeepLayer; @@ -189,6 +233,7 @@ private: tl::stable_vector m_layouts; tl::stable_vector m_builders; layout_map_type m_layout_map; + int m_threads; struct DeliveryMappingCacheKey { diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 12df8eeee..6aa47528a 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -720,6 +720,12 @@ int td_simple (); int po_any (); Class decl_DeepShapeStore ("db", "DeepShapeStore", + method ("threads=", &db::DeepShapeStore::set_threads, gsi::arg ("threads"), + "@brief Sets the number of threads for use for operations acting on this heap\n" + ) + + method ("threads", &db::DeepShapeStore::threads, + "@brief Gets the number of threads for use for operations acting on this heap\n" + ) + method ("instance_count", db::DeepShapeStore::instance_count, "@hide"), "@brief An opaque layout heap for the deep region processor\n" "\n" @@ -735,6 +741,9 @@ Class decl_DeepShapeStore ("db", "DeepShapeStore", "region = RBA::Region::new(cell.begin(layer), dss)\n" "@/code\n" "\n" + "The DeepShapeStore object also supplies some configuration options " + "for the operations acting on the deep regions. See for example \\threads=.\n" + "\n" "This class has been introduced in version 0.26.\n" ); diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index a5e582579..9a15f52d0 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -108,6 +108,66 @@ TEST(2) } 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_au2.gds"); +} + +TEST(3_BoolAndNot) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/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::DeepShapeStore dss; + + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); + unsigned int l42 = ly.get_layer (db::LayerProperties (42, 0)); + + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss); + db::Region r42 (db::RecursiveShapeIterator (ly, top_cell, l42), dss); + db::Region box (db::Box (2000, -1000, 6000, 4000)); + + db::Region r2minus3 = r2 - r3; + db::Region r2minusbox = r2 - box; + db::Region r2minus42 = r2 - r42; + db::Region rboxminus3 = box - r3; + db::Region r42minus3 = r42 - r3; + db::Region r42minus42 = r42 - r42; + + db::Region r2and3 = r2 & r3; + db::Region r2andbox = r2 & box; + db::Region r2and42 = r2 & r42; + db::Region rboxand3 = box & r3; + db::Region r42and3 = r42 & r3; + db::Region r42and42 = r42 & r42; + + db::Layout target; + unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r2minus3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r2minusbox); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r2minus42); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), rboxminus3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (14, 0)), r42minus3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (15, 0)), r42minus42); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r2and3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), r2andbox); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 0)), r2and42); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (23, 0)), rboxand3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (24, 0)), r42and3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (25, 0)), r42and42); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au3.gds"); } diff --git a/testdata/algo/deep_region_au1.gds b/testdata/algo/deep_region_au1.gds index bfa6b5bde..c21eadd76 100644 Binary files a/testdata/algo/deep_region_au1.gds and b/testdata/algo/deep_region_au1.gds differ diff --git a/testdata/algo/deep_region_au2.gds b/testdata/algo/deep_region_au2.gds new file mode 100644 index 000000000..bfa6b5bde Binary files /dev/null and b/testdata/algo/deep_region_au2.gds differ diff --git a/testdata/algo/deep_region_au3.gds b/testdata/algo/deep_region_au3.gds new file mode 100644 index 000000000..e2e935ba8 Binary files /dev/null and b/testdata/algo/deep_region_au3.gds differ