It looks like you're new here. If you want to get involved, click one of these buttons!
Hello @Matthias, I hope you are doing well, thank you for your work on this great project.
I am trying to use the drc deep function(it seems it helps in reducing memory usage and time). I am not sure if this is good enough:
layer_top = pya.Region(layout_ut.top_cell().begin_shapes_rec(layout_ut.layer(atop.layer, atop.datatype)), pya.DeepShapeStore())
and using pya.DeepShapeStore()
I am getting this error on the not
operation between layer_top and layer_bot
layer_top - layer_bot
RuntimeError: Heap lost: the DeepShapeStore container no longer exists in Region.-
#!/bin/python3.8
import klayout.db as pya
import klayout.rdb as rdb
import argparse
import time
import gc
from pprint import pprint
from pathlib import Path
class Material:
def __init__(self, name, bottom, list_of_tops):
self.name = name
self.bottom = bottom
self.list_of_tops = list_of_tops
def mark_purpose_not_overlapping_drawing(layout_path, markers_output_file):
layout_ut = pya.Layout()
layout_ut.read(str(layout_path))
report = rdb.ReportDatabase(str(markers_output_file))
rdb_top_cell = report.create_cell(layout_ut.top_cell().name)
materials = [
Material("nwell", bottom=pya.LayerInfo(64,20), list_of_tops=[pya.LayerInfo(64,16),pya.LayerInfo(64,5)]),
Material("diff", bottom=pya.LayerInfo(65,20), list_of_tops=[pya.LayerInfo(65,16),pya.LayerInfo(65,6)]),
Material("tap", bottom=pya.LayerInfo(65,44), list_of_tops=[pya.LayerInfo(65,48),pya.LayerInfo(65,5)]),
Material("poly", bottom=pya.LayerInfo(66,20), list_of_tops=[pya.LayerInfo(66,16),pya.LayerInfo(66,5)]),
Material("licon1", bottom=pya.LayerInfo(66,44), list_of_tops=[pya.LayerInfo(66,58)]),
Material("li1", bottom=pya.LayerInfo(67,20), list_of_tops=[pya.LayerInfo(67,16),pya.LayerInfo(67,5)]),
Material("mcon", bottom=pya.LayerInfo(67,44), list_of_tops=[pya.LayerInfo(67,48)]),
Material("met1", bottom=pya.LayerInfo(68,20), list_of_tops=[pya.LayerInfo(68,16),pya.LayerInfo(68,5)]),
Material("via", bottom=pya.LayerInfo(68,44), list_of_tops=[pya.LayerInfo(68,58)]),
Material("met2", bottom=pya.LayerInfo(69,20), list_of_tops=[pya.LayerInfo(69,16),pya.LayerInfo(69,5)]),
Material("via2", bottom=pya.LayerInfo(69,44), list_of_tops=[pya.LayerInfo(69,58)]),
Material("met3", bottom=pya.LayerInfo(70,20), list_of_tops=[pya.LayerInfo(70,16),pya.LayerInfo(70,5)]),
Material("via3", bottom=pya.LayerInfo(70,44), list_of_tops=[pya.LayerInfo(70,48)]),
Material("met4", bottom=pya.LayerInfo(71,20), list_of_tops=[pya.LayerInfo(71,16),pya.LayerInfo(71,5)]),
Material("via4", bottom=pya.LayerInfo(71,44), list_of_tops=[pya.LayerInfo(71,48)]),
Material("met5", bottom=pya.LayerInfo(72,20), list_of_tops=[pya.LayerInfo(72,16),pya.LayerInfo(72,5)]),
Material("pad", bottom=pya.LayerInfo(76,20), list_of_tops=[pya.LayerInfo(76,5),pya.LayerInfo(76,16)]),
Material("pnp", bottom=pya.LayerInfo(82,44), list_of_tops=[pya.LayerInfo(82,59)]),
Material("npn", bottom=pya.LayerInfo(82,20), list_of_tops=[pya.LayerInfo(82,5)]),
Material("rdl", bottom=pya.LayerInfo(74,20), list_of_tops=[pya.LayerInfo(74,16),pya.LayerInfo(74,5)]),
Material("inductor", bottom=pya.LayerInfo(82,24), list_of_tops=[pya.LayerInfo(82,25)])]
for amaterial in materials:
for atop in amaterial.list_of_tops:
layer_top = pya.Region(layout_ut.top_cell().begin_shapes_rec(layout_ut.layer(atop.layer, atop.datatype)), pya.DeepShapeStore())
layer_bot = pya.Region(layout_ut.top_cell().begin_shapes_rec(layout_ut.layer(amaterial.bottom.layer, amaterial.bottom.datatype)), pya.DeepShapeStore())
print(f"Doing {amaterial.bottom.layer}/{amaterial.bottom.datatype} with {atop.layer}/{atop.datatype}")
violating_region = layer_top - layer_bot
category_inst = report.create_category(f"{atop.layer}/{atop.datatype}")
report.create_items(rdb_top_cell.rdb_id(), category_inst.rdb_id(), pya.CplxTrans(layout_ut.dbu), violating_region)
# del violating_region
# del layer_top
# gc.collect()
# del layer_bot
# gc.collect()
report.save(str(markers_output_file))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-l", "--layout_path", required=True, type=Path, help="Layout path")
parser.add_argument("-m", "--markers_output_file", required=True, type=Path, help="violating shapes makeres file path")
args = parser.parse_args()
layout_path = Path(args.layout_path).absolute()
markers_output_file = Path(args.markers_output_file).absolute()
mark_purpose_not_overlapping_drawing(layout_path, markers_output_file)
Your help is greatly appreciated, hopefully I am not causing you too much trouble, thanks again for taking the time.
Comments
@nofal Thanks for your feedback.
When you use DeepShapeStore, you need to create a single one and make sure the Regions share the same object. It's a container for the internal data that deep mode needs for it's computations. You also need to make sure Python does not free the object before the Regions. As the DeepShapeStore also acts as a cache it's efficient not the generate a new one, but to keep it somewhere you can reuse it.
As a useful pattern, you can create a Processor class which provides the computations and holds the reference to the DeepShapeStore plus the results:
Matthias
Thank you for the awesome response @Matthias it definitely showed great improvement in memory usage and execution time.
@nofal Good to hear
My own experiences are somewhat indifferent - sometimes deep mode is very fast and lean, sometimes very slow. For being of good use in general, deep mode definitely needs some polishing.