Placing a cell using a PCell

Hello,

I am trying to make a PCell that takes a Cell name and places it in the current cell according to some rules. However, in the first tests I have made, KLayout crashes. I am sure it is my fault, but cannot find what I am doing wrong. Any help is highly appreciated!

class PlaceCell(PCellDeclarationHelper):

[... the usual stuff ...]

  def produce_impl(self):
    # This is the main part of the implementation: create the layout

    cells = pya.CellView.active().layout().cells(self.cell_str)
    if len(cells) == 1:
      cell = cells[0]
    else:
      raise Exception("Cannot find cell to include")
    if cell in self.cell.caller_cells():
      raise Exception("Cannot place cell - it is a parent to this cell.")

    trans = pya.ICplxTrans.new(1, 0, False, pya.Point(0,0))
    print(cell.cell_index())
    cia = pya.CellInstArray.new(cell.cell_index(), trans)
    self.cell.insert(cia) # <=======================================  This row seem to make KLayout crash

    if self.can_draw:
      self.cell.shapes(self.layer_layer).insert(pya.DBox(-w_dbu/2, -h_dbu/2, w_dbu/2, h_dbu/2))
    else:
      print("Failed to extract parameters, cannot draw", str(self), '.')

Running the above code gives:

Exception code: 0xc0000005
Program Version: KLayout 0.27.4 (2021-09-25 r8b1278808) AMD64

Backtrace:
0x7fffcf9746b3 - (klayout_db.dll) +411315
0x7fffcf987088 - (klayout_db.dll) +487560
0x7fffcf98d3c6 - (klayout_db.dll) +512966
0x7fffcf9b185d - (klayout_db.dll) +661597
0x7fffcf9872d3 - (klayout_db.dll) +488147
0x7fffcf913134 - (klayout_db.dll) +12596
0x7fffcf9c0cd8 - (klayout_db.dll) +724184
0x7fffcf9c101e - (klayout_db.dll) +725022
0x7fffcf9bde90 - (klayout_db.dll) +712336
0x7fffcf9bf673 - (klayout_db.dll) +718451
0x7fffd085f7dc - (klayout_db.dll) +16054236
0x7ff868e4a700 - (klayout_pya.dll) +108288
0x7ff83f34aeb3 - (libpython3.8.dll) +831155
0x7ff83f3210ab - (libpython3.8.dll) +659627
0x7ff83f330b9f - (libpython3.8.dll) +723871
0x7ff83f32b52d - (libpython3.8.dll) +701741
0x7ff83f33a5be - (libpython3.8.dll) +763326
0x7ff83f32bd5b - (libpython3.8.dll) +703835
0x7ff83f32babd - (libpython3.8.dll) +703165
0x7ff83f325882 - (libpython3.8.dll) +678018
0x7ff83f31ceec - (libpython3.8.dll) +642796
0x7ff83f28cdf4 - (libpython3.8.dll) +52724
0x7ff83f28cd58 - (libpython3.8.dll) +52568
0x7ff868e328a4 - (klayout_pya.dll) +10404
0x7ff864d19f00 - (klayout_lym.dll) +40704
0x7ff807b2e619 - (klayout_lay.dll) +321049
0x7ff807b2e9fe - (klayout_lay.dll) +322046
0x7ff827d3f203 - (Qt5Core.dll) +2945539
0x7ff827313875 - (Qt5Widgets.dll) +997493
0x7ff827315a04 - (Qt5Widgets.dll) +1006084
0x7ff827315c13 - (Qt5Widgets.dll) +1006611
0x7ff8273fe9fe - (Qt5Widgets.dll) +1960446
0x7ff8272673b8 - (Qt5Widgets.dll) +291768
0x7ff827227fd3 - (Qt5Widgets.dll) +32723
0x7ff82722f327 - (Qt5Widgets.dll) +62247
0x7ff807af25cc - (klayout_lay.dll) +75212
0x7ff827c553d0 - (Qt5Core.dll) +1987536
0x7ff82722e307 - (Qt5Widgets.dll) +58119
0x7ff82727f7a2 - (Qt5Widgets.dll) +391074
0x7ff827282915 - (Qt5Widgets.dll) +403733
0x7ff827227fd3 - (Qt5Widgets.dll) +32723
0x7ff807af25cc - (klayout_lay.dll) +75212
0x7ff827c553d0 - (Qt5Core.dll) +1987536
0x7fffe453ffe4 - (Qt5Gui.dll) +262116
0x7fffe45154bc - (Qt5Gui.dll) +87228
0x7ff827cb128f - (Qt5Core.dll) +2364047
0x7ff8289b1945 - (qwindows.dll) +530757
0x7ff827c53473 - (Qt5Core.dll) +1979507
0x7ff827c5c127 - (Qt5Core.dll) +2015527
0x7ff807af5518 - (klayout_lay.dll) +87320
0x7ff79b562111 - (klayout_app.exe) +8465
0x7ff863a615c2 - (klayout_rba.dll) +5570
0x7ff828c38b52 - (x64-msvcrt-ruby300.dll) +2001746
0x7ff828c418a6 - (x64-msvcrt-ruby300.dll) +2037926
0x7ff828c4f2a4 - (x64-msvcrt-ruby300.dll) +2093732
0x7ff828c424c7 - (x64-msvcrt-ruby300.dll) +2041031
0x7ff828ac9c69 - (x64-msvcrt-ruby300.dll) +498793
0x7ff828acc1b5 - (x64-msvcrt-ruby300.dll) +508341
0x7ff863a675fb - (klayout_rba.dll) +30203
0x7ff79b561bb3 - (klayout_app.exe) +7091
0x7ff79b561f43 - (klayout_app.exe) +8003
0x7ff79b5613b1 - (klayout_app.exe) +5041
0x7ff79b5614c6 - (klayout_app.exe) +5318
0x7ff885dc7034 - (KERNEL32.DLL) +94260
0x7ff88705d241 - (ntdll.dll) +315969

Comments

  • @ravn Is it possible to supply a complete sample?

    I don't see any obvious mistake in your code. But I would like to debug the issue. I noticed some crashes on Windows and as the Windows build uses Ruby 3, I suspect there is something different with this new Ruby version.

    Thanks,

    Matthias

  • @Matthias. Thanks for your reply. I have attached the TestCell which I try to place and a full PCell that makes KLayout crash on Windows. Thanks for looking into this.

    import pya
    import math
    
    class PlaceCell(pya.PCellDeclarationHelper):
      def __init__(self):
    
        # Important: initialize the super class
        super().__init__()
        self.param("cell_str", self.TypeString, "Width", default = "testCell")
    
      def display_text_impl(self):
        return "PlaceCell"
    
      def coerce_parameters_impl(self):
        pass
    
      def can_create_from_shape_impl(self):
        return self.shape.is_polygon() or self.shape.is_path()
    
      def parameters_from_shape_impl(self):
        pass
    
      def transformation_from_shape_impl(self):
        return pya.Trans(self.shape.bbox().center())
    
      def produce_impl(self):
        cells = pya.CellView.active().layout().cells(self.cell_str)
        if len(cells) == 1:
          cell = cells[0]
        else:
          raise Exception("Cannot find cell to include")
        if cell in self.cell.caller_cells():
          raise Exception("Cannot place cell - it is a parent to this cell.")
    
        trans = pya.ICplxTrans.new(1, 0, False, pya.Vector(0,0))
        print(cell.cell_index())
        cia = pya.CellInstArray.new(cell.cell_index(), trans)
        print(cia)
        self.cell.insert(cia)
    
    class testPack(pya.Library):
      def __init__(self):
        self.description = "testPack"
        self.layout().register_pcell("Place Cell", PlaceCell())
        self.register("testPack")
    
    testPack()
    
    
    
    Exception code: 0xc0000005
    Program Version: KLayout 0.27.4 (2021-09-25 r8b1278808) AMD64
    
    Backtrace:
    0x7fffcf9746b3 - (klayout_db.dll) +411315
    0x7fffcf987088 - (klayout_db.dll) +487560
    0x7fffcf98d3c6 - (klayout_db.dll) +512966
    0x7fffcf9b185d - (klayout_db.dll) +661597
    0x7fffcf9872d3 - (klayout_db.dll) +488147
    0x7fffcf9131cd - (klayout_db.dll) +12749
    0x7fffcf9c1273 - (klayout_db.dll) +725619
    0x7fffcf990b36 - (klayout_db.dll) +527158
    0x7ff8450cc1d7 - (klayout_edt.dll) +508375
    0x7ff8450d16f9 - (klayout_edt.dll) +530169
    0x7ff8450bb0b0 - (klayout_edt.dll) +438448
    0x7fffced3c1b6 - (klayout_laybasic.dll) +1425846
    0x7fffcecaca8e - (klayout_laybasic.dll) +838286
    0x7ff827267c9e - (Qt5Widgets.dll) +294046
    0x7ff827227fd3 - (Qt5Widgets.dll) +32723
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c551e0 - (Qt5Core.dll) +1987040
    0x7ff82725e9a4 - (Qt5Widgets.dll) +256420
    0x7ff82725f999 - (Qt5Widgets.dll) +260505
    0x7ff827247dd6 - (Qt5Widgets.dll) +163286
    0x7ff82723dcf5 - (Qt5Widgets.dll) +122101
    0x7ff827243bc2 - (Qt5Widgets.dll) +146370
    0x7ff827227fb6 - (Qt5Widgets.dll) +32694
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c551e0 - (Qt5Core.dll) +1987040
    0x7ff82725e9a4 - (Qt5Widgets.dll) +256420
    0x7ff82725f999 - (Qt5Widgets.dll) +260505
    0x7ff807c005b8 - (klayout_lay.dll) +1181112
    0x7ff827267c9e - (Qt5Widgets.dll) +294046
    0x7ff827227fd3 - (Qt5Widgets.dll) +32723
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c551e0 - (Qt5Core.dll) +1987040
    0x7ff82725e9a4 - (Qt5Widgets.dll) +256420
    0x7ff82725f999 - (Qt5Widgets.dll) +260505
    0x7ff827247dd6 - (Qt5Widgets.dll) +163286
    0x7ff82723dcf5 - (Qt5Widgets.dll) +122101
    0x7ff827243bc2 - (Qt5Widgets.dll) +146370
    0x7ff827227fb6 - (Qt5Widgets.dll) +32694
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c551e0 - (Qt5Core.dll) +1987040
    0x7ff82725e9a4 - (Qt5Widgets.dll) +256420
    0x7ff82725f999 - (Qt5Widgets.dll) +260505
    0x7ff827243bc2 - (Qt5Widgets.dll) +146370
    0x7ff827227fb6 - (Qt5Widgets.dll) +32694
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c551e0 - (Qt5Core.dll) +1987040
    0x7ff82725e9a4 - (Qt5Widgets.dll) +256420
    0x7ff82725f999 - (Qt5Widgets.dll) +260505
    0x7ff82726a95d - (Qt5Widgets.dll) +305501
    0x7ff82730eaa7 - (Qt5Widgets.dll) +977575
    0x7ff8273ca0a9 - (Qt5Widgets.dll) +1745065
    0x7ff827a78c9d - (Qt5Core.dll) +35997
    0x7ff827a76a88 - (Qt5Core.dll) +27272
    0x7ff827a79941 - (Qt5Core.dll) +39233
    0x7ff827a74af2 - (Qt5Core.dll) +19186
    0x7ff827313340 - (Qt5Widgets.dll) +996160
    0x7ff82734d432 - (Qt5Widgets.dll) +1233970
    0x7ff82737a1fc - (Qt5Widgets.dll) +1417724
    0x7ff82737fb8b - (Qt5Widgets.dll) +1440651
    0x7ff827243bc2 - (Qt5Widgets.dll) +146370
    0x7ff8272454a9 - (Qt5Widgets.dll) +152745
    0x7ff827266e1c - (Qt5Widgets.dll) +290332
    0x7ff807b62a31 - (klayout_lay.dll) +535089
    0x7ff807b62fd8 - (klayout_lay.dll) +536536
    0x7ff827d3f203 - (Qt5Core.dll) +2945539
    0x7fffcededfd3 - (klayout_laybasic.dll) +2154451
    0x7ff8450d0ad0 - (klayout_edt.dll) +527056
    0x7fffced3f398 - (klayout_laybasic.dll) +1438616
    0x7ff8272673b8 - (Qt5Widgets.dll) +291768
    0x7ff827227fd3 - (Qt5Widgets.dll) +32723
    0x7ff827230b2a - (Qt5Widgets.dll) +68394
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c54eb0 - (Qt5Core.dll) +1986224
    0x7ff827281494 - (Qt5Widgets.dll) +398484
    0x7ff827281966 - (Qt5Widgets.dll) +399718
    0x7ff827282aad - (Qt5Widgets.dll) +404141
    0x7ff827227fd3 - (Qt5Widgets.dll) +32723
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c551e0 - (Qt5Core.dll) +1987040
    0x7fffe4541aef - (Qt5Gui.dll) +269039
    0x7fffe4514af6 - (Qt5Gui.dll) +84726
    0x7ff8279b5425 - (qwindows.dll) +414757
    0x7ff8279b61f0 - (qwindows.dll) +418288
    0x7ff886ebbb26 - (ole32.dll) +834342
    0x7ff886ebb98c - (ole32.dll) +833932
    0x7ff886e78e7a - (ole32.dll) +560762
    0x7ff886e78db1 - (ole32.dll) +560561
    0x7ff886e7c900 - (ole32.dll) +575744
    0x7ff8279b8879 - (qwindows.dll) +428153
    0x7fffe457eb77 - (Qt5Gui.dll) +519031
    0x7fffe457efd9 - (Qt5Gui.dll) +520153
    0x7fffcedbc0f0 - (klayout_laybasic.dll) +1949936
    0x7ff827482892 - (Qt5Widgets.dll) +2500754
    0x7ff8272673b8 - (Qt5Widgets.dll) +291768
    0x7ff82730e974 - (Qt5Widgets.dll) +977268
    0x7ff827c53bdc - (Qt5Core.dll) +1981404
    0x7ff827227fc2 - (Qt5Widgets.dll) +32706
    0x7ff82722f327 - (Qt5Widgets.dll) +62247
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c553d0 - (Qt5Core.dll) +1987536
    0x7ff82722e307 - (Qt5Widgets.dll) +58119
    0x7ff82727f7a2 - (Qt5Widgets.dll) +391074
    0x7ff827282915 - (Qt5Widgets.dll) +403733
    0x7ff827227fd3 - (Qt5Widgets.dll) +32723
    0x7ff807af25cc - (klayout_lay.dll) +75212
    0x7ff827c553d0 - (Qt5Core.dll) +1987536
    0x7fffe453ffe4 - (Qt5Gui.dll) +262116
    0x7fffe45154bc - (Qt5Gui.dll) +87228
    0x7ff827cb128f - (Qt5Core.dll) +2364047
    0x7ff8279d1945 - (qwindows.dll) +530757
    0x7ff827c53473 - (Qt5Core.dll) +1979507
    0x7ff827c5c127 - (Qt5Core.dll) +2015527
    0x7ff807af5518 - (klayout_lay.dll) +87320
    0x7ff79b562111 - (klayout_app.exe) +8465
    0x7ff863a615c2 - (klayout_rba.dll) +5570
    0x7ff828c38b52 - (x64-msvcrt-ruby300.dll) +2001746
    0x7ff828c418a6 - (x64-msvcrt-ruby300.dll) +2037926
    0x7ff828c4f2a4 - (x64-msvcrt-ruby300.dll) +2093732
    0x7ff828c424c7 - (x64-msvcrt-ruby300.dll) +2041031
    0x7ff828ac9c69 - (x64-msvcrt-ruby300.dll) +498793
    0x7ff828acc1b5 - (x64-msvcrt-ruby300.dll) +508341
    0x7ff863a675fb - (klayout_rba.dll) +30203
    0x7ff79b561bb3 - (klayout_app.exe) +7091
    0x7ff79b561f43 - (klayout_app.exe) +8003
    0x7ff79b5613b1 - (klayout_app.exe) +5041
    0x7ff79b5614c6 - (klayout_app.exe) +5318
    0x7ff885dc7034 - (KERNEL32.DLL) +94260
    0x7ff88705d241 - (ntdll.dll) +315969
    
  • Excellent! Many thanks for your efforts preparing a test case!

    I'll look into that immediately.

    Matthias

  • Thanks again for the testcase.

    First of all, the crash is probably due to an unchecked cell index value. I admit that could be somewhat safer, but that's an effect of the lean data structures in layout objects. Anyway I'll put better error checking on my TODO list.

    Unfortunately, the basic message is: you cannot directly place a cell from the original layout inside a PCell which resides in a library. The instance created here:

    pya.CellInstArray.new(cell.cell_index(), trans)
    

    will not point to the original layout but to a cell inside the library. So the cell index has to be one from the PCell library. If it is taken from the original layout and does not match to a valid cell index, the crash will happen.

    I'll try to explain the mechanics of PCell instantiation (from a library), so hopefully the problem becomes clearer.

    When you create a library and PCells inside that library, a new Layout object is created. PCells are attached to this layout and when you ask for a specific PCell instance it is first created inside that library-specific layout. This cell - residing inside the library - has no connection to the layout you want to instantiate the PCell in. It acts as kind of shadow cell and caches the geometry of that PCell incarnation.

    In the second step - when you place the PCell - the original layout will refer to this shadow cell through what is called a "proxy cell".

    However, as both steps are separated, the PCell instantiation code has no access to the original layout. You looked up the layout from the main window / view chain, but this will not work. Inside the library, the PCell only can access cells from the same library or other libraries. The original layout however is not a library but a plain layout. So there is no direct way (I know of) how to address an original cell :(

    I thought about other applications which might benefit from a PCell's ability to reflect the original layout it's called in. However, that is a can of worms. As the PCell is potentially used by other client layouts, this association is ambiguous and modifications of the original layout have to be traced back to potential PCell impact. Everything is possible, but this isn't a feature that is easily implemented.

    So right now, a PCell can only reference other library cells (either in the library that declares the PCell or in another library). I don't know the application of yours, but if the goal is to place certain cells only, maybe you can put them into a separate library?

    As a weird hack it's basically possible to copy the cells into the PCell's library before you create an instance, but this will eventually disconnect the cells from the original layout and I assume that is not what you want to do.

    Another solution might be to switch from PCell to some generator script. So some script you can call in the menu to generate an arrangement of cells. You might provide a small dialog box that asks for a cell name and then generates the instances. Such a script will directly operate on the layout and is not subject to the instantiation constraint.

    Best regards,

    Matthias

Sign In or Register to comment.