From 7b4e8a346299545daa02668ae5589c04950d6fd2 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 4 Mar 2025 19:50:33 +0100 Subject: [PATCH] Refined solution for DSS remapping bug --- src/db/db/dbDeepShapeStore.cc | 58 ++++++++++++++++----- src/db/unit_tests/dbDeepShapeStoreTests.cc | 40 ++++++++++++++ testdata/algo/dss_bug2.gds | Bin 0 -> 852 bytes testdata/algo/dss_bug2_au.gds | Bin 0 -> 1072 bytes 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 testdata/algo/dss_bug2.gds create mode 100644 testdata/algo/dss_bug2_au.gds diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index 23a28ef30..c6bbb6aee 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -1233,7 +1233,6 @@ DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout if (! new_pairs.empty ()) { // the variant's originals we are going to delete - std::set cells_to_delete; std::vector > new_variants; // We now need to fix the cell map from the hierarchy builder, so we can import back from the modified layout. @@ -1248,7 +1247,6 @@ DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout // create the variant clone in the original layout too and delete this cell VariantsCollectorBase::copy_shapes (*into_layout, np->second, icm->second.original_cell); new_variants.push_back (std::make_pair (np->second, icm->second.original_cell)); - cells_to_delete.insert (icm->second.original_cell); // forget the original cell (now separated into variants) and map the variants back into the // DSS layout @@ -1279,26 +1277,60 @@ DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout std::vector mapped = cm->second.target_cells (); std::sort (mapped.begin (), mapped.end ()); - // Copy the variant instances - but only those for cells which are not going to be - // deleted and those not handled by the cell mapping object. + // Copy the variant instances - but only those for cells which are not handled by the cell mapping object. for (auto vv = new_variants.begin (); vv != new_variants.end (); ++vv) { + const db::Cell &from = into_layout->cell (vv->second); db::Cell &to = into_layout->cell (vv->first); for (db::Cell::const_iterator i = from.begin (); ! i.at_end (); ++i) { - if (cells_to_delete.find (i->cell_index ()) == cells_to_delete.end ()) { - auto m = std::lower_bound (mapped.begin (), mapped.end (), i->cell_index ()); - if (m == mapped.end () || *m != i->cell_index ()) { - to.insert (*i); - } + auto m = std::lower_bound (mapped.begin (), mapped.end (), i->cell_index ()); + if (m == mapped.end () || *m != i->cell_index ()) { + to.insert (*i); } } + + } + + // clean up instances of variant original cells + + std::map > delete_instances_of; + + into_layout->force_update (); + + for (auto vv = new_variants.begin (); vv != new_variants.end (); ++vv) { + const db::Cell &to = into_layout->cell (vv->first); + for (auto p = to.begin_parent_cells (); p != to.end_parent_cells (); ++p) { + delete_instances_of [*p].insert (vv->second); + } } - } + std::vector insts_to_delete; + for (auto di = delete_instances_of.begin (); di != delete_instances_of.end (); ++di) { + db::Cell &in = into_layout->cell (di->first); + insts_to_delete.clear (); + for (auto i = in.begin (); ! i.at_end (); ++i) { + if (di->second.find (i->cell_index ()) != di->second.end ()) { + insts_to_delete.push_back (*i); + } + } + in.erase_insts (insts_to_delete); + } + + // remove variant original cells unless they are still used + + into_layout->force_update (); + + std::set cells_to_delete; + for (auto vv = new_variants.begin (); vv != new_variants.end (); ++vv) { + if (into_layout->cell (vv->second).parent_cells () == 0) { + cells_to_delete.insert (vv->second); + } + } + + if (! cells_to_delete.empty ()) { + into_layout->delete_cells (cells_to_delete); + } - if (! cells_to_delete.empty ()) { - // delete the variant original cells - into_layout->delete_cells (cells_to_delete); } } diff --git a/src/db/unit_tests/dbDeepShapeStoreTests.cc b/src/db/unit_tests/dbDeepShapeStoreTests.cc index c0a56db08..4a01e194c 100644 --- a/src/db/unit_tests/dbDeepShapeStoreTests.cc +++ b/src/db/unit_tests/dbDeepShapeStoreTests.cc @@ -301,3 +301,43 @@ TEST(6_RestoreWithCellSelection) db::compare_layouts (_this, ly, tl::testdata () + "/algo/dss_bug_au.gds"); } +TEST(7_RestoreWithCellSelection2) +{ + db::Layout ly; + + { + std::string fn (tl::testdata ()); + fn += "/algo/dss_bug2.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + + db::Cell &top_cell = ly.cell (*ly.begin_top_down ()); + + db::RecursiveShapeIterator in_it (ly, top_cell, l2); + db::RecursiveShapeIterator other_it (ly, top_cell, l2); + + std::set us; + us.insert (ly.cell_by_name ("X").second); + in_it.unselect_cells (us); + + std::set us2; + us2.insert (top_cell.cell_index ()); + other_it.unselect_cells (us2); + other_it.select_cells (us); + + db::DeepShapeStore dss; + + db::Region in_region (in_it, dss); + db::Region other_region (other_it, dss); + in_region += other_region; + + ly.clear_layer (l2); + in_region.insert_into (&ly, top_cell.cell_index (), l2); + + db::compare_layouts (_this, ly, tl::testdata () + "/algo/dss_bug2_au.gds"); +} + diff --git a/testdata/algo/dss_bug2.gds b/testdata/algo/dss_bug2.gds new file mode 100644 index 0000000000000000000000000000000000000000..1c4b8c47be0aa6b1c8fa10bf93cd744935bd29a8 GIT binary patch literal 852 zcma)4u}%U(5Pi41H*63MB9*zy+Qb|&8WTez*cgdgT!DOuA7G~+Kx1QPYm9}ZmGKKK zEGdX~v?4gp-Ejh^!d)_Xm)Y!__udW&N;Tm*D)$ZzgFGzClmD=a8V5C?tljF~#rEOT zO>bxaVdMI$6~J?6+#_oEn}D$ZEh;#mB?Vx;sG0dTDe3g2x(O!z5Mh?(ehxF|5K-NS zSpaM)o@iIXX%4)i7S>&<`(K!qx$++~^YD!M^Er*N=83Oil-0v`lI6PwhdK+WX z?{~6#Zb~xZnMzczfL0xGSn%9hOECPVGEkR*n+H-DWiaCK=W*yN;Jg4S%$Vb8tTuU} zIeKv}vjTB3jnS;Xl4V&>v}I!i)t%g38)MQ(J5#cjC^$Y5wGx+PE4mBe7U@C69w~@V RB!4+!{&v@T>fBe%d4LnY`;oWoY@4Y}nsX78nWnN*!K^_Gx55B`wx>_j#^R`>u zKHb>8zie-oZ&xnP8#M&(-}`*6tKr&GxpD|N9-yZcEa({ppfGET$W^jfX>&a%n$(TL zndANp{`K-AugUvliI&Eb{&^sxhxG-fEC{cU`2@ z5;5A_6Zv@QYf|sDQt>wF!YG{=r2__%@f5eXZhmN*lVs;3(&gOQcy6-R3l@9%fm>=& z%`@zF0$4Rxhc$Bhjf3zqqshBPRoC3R*w>_vW?ByQIIYf^^BR*>odIr^Zo?WS<;12( yIIf3XWa39)MANY4UsBsYU|vR`7diX0Ham4A7Ey=z3uodNk+(bEkf(1Fj)PBU7U2H? literal 0 HcmV?d00001