From cfa0e8431c78e715f9927fcfc505604feafedb51 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 17 Nov 2018 01:33:58 +0100 Subject: [PATCH] WIP: implemented AND/NOT in deep region, added tests. --- src/db/db/dbDeepRegion.cc | 69 +++++++++++++++++++++++++ src/db/db/dbDeepRegion.h | 10 ++++ src/db/db/dbDeepShapeStore.cc | 28 ++++++++++ src/db/db/dbDeepShapeStore.h | 45 ++++++++++++++++ src/db/db/gsiDeclDbRegion.cc | 9 ++++ src/db/unit_tests/dbDeepRegionTests.cc | 62 +++++++++++++++++++++- testdata/algo/deep_region_au1.gds | Bin 9250 -> 2570 bytes testdata/algo/deep_region_au2.gds | Bin 0 -> 9250 bytes testdata/algo/deep_region_au3.gds | Bin 0 -> 4074 bytes 9 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 testdata/algo/deep_region_au2.gds create mode 100644 testdata/algo/deep_region_au3.gds 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 bfa6b5bde37c2c7396658552e9a72212db726a82..c21eadd76136e63aee6e508001c0f1ec507796df 100644 GIT binary patch delta 507 zcmZ4F(Iuk9z{bGD6u}_F$i)7Lftx{)fssLiK?<2YQAt%8i}2=cJZBgu2e2qi?9i6R zBG16V#^&i4W;D4)(s8o3oa^KT!fl(R`xv=cD;O9U4>2&XR!p8DW5x#J@@$&?OVo^u z?*>Sefr0PFWGk^XlVb$F8e%h;i;XSF)6d&y+0|1Fqa^wI2 literal 9250 zcmdT|&x@5+7(VyT%)NJhD3cBb;X-8EiRq}5A&HhzgEGl9NQlrs(87gCgvLNEs+EgY z)UWzq z&*Sx8ulomn3$d<^*XiS&XE_i1&Qm`}$=%s1eazkM?K8ZN-(BvX;o<(czq6wK9OwRq zjd|+fKSRlr{afMr*KXVS*KR}a5}s#;k`p8Q1AXlMyB`Nq5BGmUD0xA@5Hs{&Ss^f47a!?^buHR&@$$qV`gpDEA1BJ$ku3FP^Kb@=RV z<};75^g4Dh5KiSb2HDKQ1W>Hz~@QKz%kdOi z9o#xj7I=MQ)g7yEsyb(O7OHbDPwWr8juBL4{|Ah#b1uhIc>cs|oQG&BFnTVR{($OS z^xFP%ufftQ*pb|K1^)$3?~jL82VU!s+dAS>p#jmhg1nlOvi-p+yfeRV z!YN!=^=0TYS7tZQlxKJ281_fJG>%D5jG{Y;6O4hs#n;30IQ4PTP4<2fC%|rh_q0Fj z50X0%?8i9+PVjNc^D|z7syfwi8goM0`whzpjBkJc9$`OXA?q`I%nk7QL{`&Li#qmZ zk<@Xl7jK zWMRi<_C3-L-xT?F-@OIPfxRD*-RRtel6P-KCrb38bCUWv(HqpyQF3>(UVr?C=}&xP z`a;RaZ`A8g9x?r?L#8j3eDa9t54b1vGX6&UA1C(D&gGRW>YyH;LpfXS^@we}xBY!B zN6A~uk=32>)*pQeOVNQ58+S}!C^;sCm7}0PzSs08Z<@YP^6|Zqek0w#-6_|XyxocP z$3p#wU*r5&aeiPM-)bIxl%wRWtENBvt@BINgmXK#WnZTH4q>!U@tailJnzre$IO|+ z%mewniTgG44!YJ0jTOh)@Pu_a{?G-;5L3kQ3+MyB$Wd}ksMcSF4F~z& zhDl$+F7$dr$w%<*h2QzI^F}$b_5iD6e`1HhrA#_W8FX*)5d3&i*u~8Dq?C;_x{QzkPtS+%e?&E$1WqYjWE3CT|)JpVP7a;GBl7 zyK#RX8jhX;f*XaB1H=2@a81bK=b2>^-aDDBj~TUr4>aHj@iZf z$9L2^Qv8BUC5D0#j9(`Po^?@?ng<}>|fC^<1Ye~{OvCkC7P!SscaSLe0qi@~=3YWhOS zmDgGP1B|;5|8F2IGZo%3gK4r8!(POWB9Ik=LLkLxVi7oD-}Q z=K8Z#QJzX~y|%&%g9@;c_te&7OHPb3AgW;0V+A6rClyLw*PE_AV1@YqRv@06Jv320 zwNUbe0ip`x?;jP2`syeQS$QZYM)#lS!*6(BramhVdvl@Wbrs0ljrV0DD-ZRBtUxv% z?Z4p)G@yduyU)_X;+t>xD@RgKkgF&Hryc)1qgpQ!%|aV#Z@e?t>gSRF-{O~ rh;cAv>zE;*pFeNUM9G0+#}nz#e{b`M)L-0{BlWX!ua9^c9d-WzeKT?l diff --git a/testdata/algo/deep_region_au2.gds b/testdata/algo/deep_region_au2.gds new file mode 100644 index 0000000000000000000000000000000000000000..bfa6b5bde37c2c7396658552e9a72212db726a82 GIT binary patch literal 9250 zcmdT|&x@5+7(VyT%)NJhD3cBb;X-8EiRq}5A&HhzgEGl9NQlrs(87gCgvLNEs+EgY z)UWzq z&*Sx8ulomn3$d<^*XiS&XE_i1&Qm`}$=%s1eazkM?K8ZN-(BvX;o<(czq6wK9OwRq zjd|+fKSRlr{afMr*KXVS*KR}a5}s#;k`p8Q1AXlMyB`Nq5BGmUD0xA@5Hs{&Ss^f47a!?^buHR&@$$qV`gpDEA1BJ$ku3FP^Kb@=RV z<};75^g4Dh5KiSb2HDKQ1W>Hz~@QKz%kdOi z9o#xj7I=MQ)g7yEsyb(O7OHbDPwWr8juBL4{|Ah#b1uhIc>cs|oQG&BFnTVR{($OS z^xFP%ufftQ*pb|K1^)$3?~jL82VU!s+dAS>p#jmhg1nlOvi-p+yfeRV z!YN!=^=0TYS7tZQlxKJ281_fJG>%D5jG{Y;6O4hs#n;30IQ4PTP4<2fC%|rh_q0Fj z50X0%?8i9+PVjNc^D|z7syfwi8goM0`whzpjBkJc9$`OXA?q`I%nk7QL{`&Li#qmZ zk<@Xl7jK zWMRi<_C3-L-xT?F-@OIPfxRD*-RRtel6P-KCrb38bCUWv(HqpyQF3>(UVr?C=}&xP z`a;RaZ`A8g9x?r?L#8j3eDa9t54b1vGX6&UA1C(D&gGRW>YyH;LpfXS^@we}xBY!B zN6A~uk=32>)*pQeOVNQ58+S}!C^;sCm7}0PzSs08Z<@YP^6|Zqek0w#-6_|XyxocP z$3p#wU*r5&aeiPM-)bIxl%wRWtENBvt@BINgmXK#WnZTH4q>!U@tailJnzre$IO|+ z%mewniTgG44!YJ0jTOh)@Pu_a{?G-;5L3kQ3+MyB$Wd}ksMcSF4F~z& zhDl$+F7$dr$w%<*h2QzI^F}$b_5iD6e`1HhrA#_W8FX*)5d3&i*u~8Dq?C;_x{QzkPtS+%e?&E$1WqYjWE3CT|)JpVP7a;GBl7 zyK#RX8jhX;f*XaB1H=2@a81bK=b2>^-aDDBj~TUr4>aHj@iZf z$9L2^Qv8BUC5D0#j9(`Po^?@?ng<}>|fC^<1Ye~{OvCkC7P!SscaSLe0qi@~=3YWhOS zmDgGP1B|;5|8F2IGZo%3gK4r8!(POWB9Ik=LLkLxVi7oD-}Q z=K8Z#QJzX~y|%&%g9@;c_te&7OHPb3AgW;0V+A6rClyLw*PE_AV1@YqRv@06Jv320 zwNUbe0ip`x?;jP2`syeQS$QZYM)#lS!*6(BramhVdvl@Wbrs0ljrV0DD-ZRBtUxv% z?Z4p)G@yduyU)_X;+t>xD@RgKkgF&Hryc)1qgpQ!%|aV#Z@e?t>gSRF-{O~ rh;cAv>zE;*pFeNUM9G0+#}nz#e{b`M)L-0{BlWX!ua9^c9d-WzeKT?l literal 0 HcmV?d00001 diff --git a/testdata/algo/deep_region_au3.gds b/testdata/algo/deep_region_au3.gds new file mode 100644 index 0000000000000000000000000000000000000000..e2e935ba883d674b6b0f5129915c00aeb11dca8e GIT binary patch literal 4074 zcmai%PiS0a6vglS>6^*SBu+D#Ng1jLB?Y09Vv8Y*h_L}pEu+K`LTN!Lbm1y1S1l9@ z1q%hCuBwZyDipdZ6cHD$vd~Re-MA?tUAW5HR-fPR-8sCON#2)DPI~S=-}&Bs_uki7 zV&(F-oh+4We_GRyTgl$E^P|68y_{TH|Hy2va_ocEZ9RE}nJJsunRX@oyqTu|Er4dFKg`N^h2k@;9zRr{rvH9T97LC< z>20C-1Nv6(KdGPeSKLPZ=SKDEZTE5C{5kx&xKHk1vuLI2NwPlJde5p2v&O8d)@oP6 z2|MBBPywoNc(k#9NHpn}ZkdG>LQTFcIAJ13=Nxg@@K!h02Oodt_o>hN%`>OWC%@}h ztnvBSEyiMVyT!4$_KRchd{`ViH~!RPek(7Eb)TFqj&0m3j$L_{$A;bB9PO4@FTGn{ zz4R`x_J!i}ZaJtA|^E;k5zvH?SKMTdj_5J6b*MIK1Q=u90 zKh+Q)*Dsv*yoJ-Qd-t+Xd|bbnO}p7*Htl9hk6gd>$o0ec=(LX1-)wo$^OpBqxB8Dz zeB6Jn=Xq;A*Il|O6d%_Qu6y3#y6d(c2*tE@`{97nKrcYD)ZmR3p`aKM3 zKdgr#il6F^ZM(7h(RU%9^&dL=Pbfa7r|-xE(b0cG@i9GpM;?fd{u7Fi>FGQ2Ky>t< zP<%{J-;oERqyL2BV|x0IJP;lIClnvk(|6>7=;%M8_?Vu)BM(GJ{|Uv%^zh%fln`G0hej)TyhJk+(&R!9k&9pr(to`CTA$;?i=YiE9!oSbt zSUK-;M?bf9RcHp^`YuQGt*fpFIe+$kj`&W$4tE$L_a^S>=XUN1UDth*Bj>mTkI?(x(08O6`iXtsyeR&_ zKAF&aKWGo2ryoH20e+$%#`IHL?lZOJzB6A5#mD{8;RE7}UMN21-@fBM?K|$<4fDYB zcOQt4`=i4L#239#e9XV|(0w`&-B;gbeW!=nJj=6CZe}q2FYc`+5xn&-+IULR<^Bm%Z{`42~2QruS zUvm^6uu#wQvv=4-mAC!*9mQuD(YrT#=8*acxf6WALOu1vpZeiT{T#)|{n6nA;;X#{ zijVov-uL&!9^<`r?g_=m-(UBM=ds7ovzHvjAEDPC44Cb=uj{M4Q2cN8D5KRW6RQh)S9@v-_-Km4=rK=7x2`0G0`j2AvXI($HU P^<4nP%Rl@@SFPIro;b=; literal 0 HcmV?d00001