From a8014646bb5931584a185cb2cb21db2d23fab868 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 7 Feb 2021 09:36:46 +0100 Subject: [PATCH] Added doc for 'under construction' mode. --- src/db/db/gsiDeclDbLayout.cc | 2 + src/lay/lay/doc/about/index.xml | 1 + .../doc/about/layouts_under_construction.xml | 134 ++++++++++++++++++ src/lay/lay/layHelpResources.qrc | 1 + 4 files changed, 138 insertions(+) create mode 100644 src/lay/lay/doc/about/layouts_under_construction.xml diff --git a/src/db/db/gsiDeclDbLayout.cc b/src/db/db/gsiDeclDbLayout.cc index 42d02f5f6..73c149c8e 100644 --- a/src/db/db/gsiDeclDbLayout.cc +++ b/src/db/db/gsiDeclDbLayout.cc @@ -1331,6 +1331,8 @@ Class decl_Layout ("db", "Layout", "end_changes, in particular when it is possible to put a layout object into an invalid state temporarily.\n\n" "While the layout is under construction \\update can be called to update the internal state explicitly if required.\n" "This for example might be necessary to update the cell bounding boxes or to redo the sorting for region queries.\n" + "\n" + "For further discussion of this mode, see @Editable and non-editable layouts@.\n" ) + gsi::method ("end_changes", &db::Layout::end_changes, "@brief Cancels the \"in changes\" state (see \"start_changes\")\n" diff --git a/src/lay/lay/doc/about/index.xml b/src/lay/lay/doc/about/index.xml index 489c80c0b..dfba7923f 100644 --- a/src/lay/lay/doc/about/index.xml +++ b/src/lay/lay/doc/about/index.xml @@ -29,6 +29,7 @@ + diff --git a/src/lay/lay/doc/about/layouts_under_construction.xml b/src/lay/lay/doc/about/layouts_under_construction.xml new file mode 100644 index 000000000..1b78c9e08 --- /dev/null +++ b/src/lay/lay/doc/about/layouts_under_construction.xml @@ -0,0 +1,134 @@ + + + + + + Layouts "under construction" + +

+ Layout objects hold primary information such as cells, shapeso and instances. + The also keep secondary information + they can derive from the basic data: bounding boxes, child cells, parent cells. There are also + quad trees which speed up region lookups (search for objects inside a rectangular regions). + Secondary information needs to be updated on every change of the basic data. + This update may be time consuming and under certain conditions this may happen more + often than desired. +

+ +

+ This code for example is supposed to copy the bounding box of a cell into a + new layer: +

+ +
+# ly is a Layout, bbox_layer an layer index:
+for c in ly.each_cell():
+  c.shapes(bbox_layer).insert(c.bbox())
+
+ +

+ This loop executes in 0.3 s for 1000 cells, but takes 50 seconds for 10000 cells. This is + a typical O(2) complexity and the time required for the loop will quickly grow with the + number of cells. +

+ +

+ The reason behind this behaviour is the update step: after changing a single cell's + shape collections, the bounding boxes need to be re-evaluated. So the loop basically + consists of two steps: insert of a shape and the re-evaluation of the bounding boxes. + Even though the bounding box re-evaluation isn't expensive for a single cell, simply + checking every cell for a change will consume time which is proportional to the + number of cells. As this is done for every cell, the complexity will become proportional + to the square of the number of cells. +

+ +

+ To mitigate this, you can freeze the bounding boxes before the loop starts. + We don't need the bounding boxes to reflect the change by the shape insert. + First because it simply isn't changed and second because we only change a single + cell after we have obtained it's bounding box. +

+ +

+ To enter this "frozen bounding box mode", use . + After that you should make sure to release this mode using . + After "start_changes", the layout is in "under_construction" mode and bounding boxes will + not be updated among other information which is expensive to obtain. The sample code + using this technique is this: +

+ +
+ly.start_changes()
+for c in ly.each_cell():
+  c.shapes(bbox_layer).insert(c.bbox())
+ly.end_changes()
+
+ +

+ To make sure, "end_changes" is always called - even in case of an exception between "start_changes" and "end_changes" - you can use + a "try .. finally" block. In Ruby, that is the "begin .. ensure" equivalent: +

+ +
+# Python
+ly.start_changes()
+try:
+  for c in ly.each_cell():
+    c.shapes(bbox_layer).insert(c.bbox())
+finally:
+  ly.end_changes()
+
+ +
+# Ruby
+ly.start_changes
+begin
+  ly.each_cell do |c|
+    c.shapes(bbox_layer).insert(c.bbox)
+  end
+ensure
+  ly.end_changes
+end
+
+ +

+ With this modification the above loop executes in 18 ms for 1000 cells and 180 ms for 10000 cells. + So it scales nicely with the number of cells and provides a 277x performance improvement for the 10000 cell case. +

+ +

+ "start_changes" and "end_changes" add up, i.e. when you call "start_changes" two times, you'll also need to + call "end_changes" two times before leaving "under_construction" mode. + Upon leaving this mode, the layout will automatically update its data to be prepared for further + actions. +

+ +

+ You can check if a layout is under construction using . + You can use to force an update of the layout's data while in "under_construction" mode. +

+ +

Restrictions in "under_construction" mode

+ +

+ While under construction, a layout is subject to certain restrictions: +

+ +
    +
  • Bounding boxes of cells and shape collections are not updated
  • +
  • Region queries will be performed using the initial lookup trees (e.g )
  • +
  • Parent-child relations of cells may be invalid (e.g. )
  • +
+ +

+ In general, the data will reflect the initial status before the "under construction" + mode is entered. There is a specific risk connected with the erasing of + objects during "under construction" mode: as some references may still point + to objects already erased, access to such objects may result in an application + crash. So be careful when erasing objects while in "under construction" mode. + A safe strategy in general is to first collect objects to be erased and then + delete them in a second loop hence avoiding using information outdated by the "erase". +

+ +
+ diff --git a/src/lay/lay/layHelpResources.qrc b/src/lay/lay/layHelpResources.qrc index e67575d99..7a21f026b 100644 --- a/src/lay/lay/layHelpResources.qrc +++ b/src/lay/lay/layHelpResources.qrc @@ -48,6 +48,7 @@ doc/about/lvs_ref_netter.xml doc/about/packages.xml doc/about/editable_layouts.xml + doc/about/layouts_under_construction.xml doc/manual/adjust_origin.xml