It looks like you're new here. If you want to get involved, click one of these buttons!
Hi
I am slightly lost in user properties. I understand, that Shape
, Cell
and CellInstance
can all have their properties. I would like to pass some information about a PCell via the properties, but if I use self.cell.set_property(name, value)
in produce_impl
of a PCellDeclarationHelper
, the property does not appear for either PCell variant (one in the Cell view on the left) nor for cell instance (one in the design). How could I set properties for the instances of PCell in the PCell definition code?
Comments
Hi,
you cannot. A PCell shall deliver layout and not modify the external attributes of a cell (such as name, placement, etc.). The user properties are among the external attributes. Instances cannot be accessed from within the PCell because KLayout will optimize the PCell generation such that different instances with the same parameter set will share the same PCellVariant.
You can use hidden PCell parameters to keep information you don't what to show up in the user interface, if that is the intention should have.
Regards,
Matthias
My specific goal was to export Sonnet project files and use properties to define port locations. Then, a script could export all cells irrespective if they are PCell variants or manually created.
I think I can use the properties of the shapes in the Cell for now.
Initially I thought, that instances would inherit user properties from a PCell variant. But it seems that even PCell variant does not get the properties of the produced PCell.
Hello,
Yes, shape properties are possible. You could also use texts to label the ports, if that is an option.
Instance properties cannot be used because the PCell is the target of the instance, not the instance itself. Multiple instances can share the same PCell variant (variant in terms of PCell parameters). Hence there is no connection back from the PCell variant to the instance.
If you really, really want to have an instance with properties you can create a cell inside the PCell and produce in instance of this cell inside ... but I'd only do this is absolutely necessary.
Regards,
Matthias
Thank you for the reply (and the great software)!
Is instances inheriting properties of the cell variants a bad idea? Obliviously many instances would share the inherited properties. And cell variants could get properties during the production.
I already use text to annotate the ports for users. For Sonnet files I need to tell the index of the polygon edge to be used as a port and finding the edge under a text position seems a bit inefficient. For this purpose I now use the property of the shape.
Shape properties are fine. Instances have their own properties and it's not common to have instances inherit cell properties. Both are different concepts and used for very different purposes, so I'd not mix that.
Matthias
I keep pumping into the same issue and from reading the Q&A regarding the Circle PCell parameters I think other people have reached the same point. I define a lot of features in
PCellDeclarationHelper
. It generates geometry, but some of the intermediate results are useful for other object and I want to access them.First, why do I keep using PCells: I want to make use of API handling copies of cells with same parameters - this is a very nice feature. Also, then a user can turn the top cell into static and change parameters of the children.
Second, why do I define the geometry and other calculations inside
PCellDeclarationHelper
? I want to initiate my object via a single interface. If the geometry was defined in another object, I would initiate the geometry object to extract intermediate results and then initialize the library PCell with the same arguments. I want to avoid doing it twice and keep using PCells. Thus, the geometry is defined behind PCell.Useful intermediate results from PCells: First, there are geometric locations, which other constructs need to relate to. These I can "leak out" from
PCellDeclarationHelper
inside coordinates of theText
objects on an extra layer. This is reasonable (although it would be very nice to see some mark at the exact location ofText
). However, there are other useful quantities as well. For example, an index for a special polygon edge or a length of my waveguide with rounded edges. How to "leak" them out fromPCellDeclarationHelper
? I tried two approaches.Readonly
pcell_parameter
- it seems, that they get updated only after a call tocoerce_parameters_impl
and this only happens after event on the GUI. If I create an instance in the code, thecoerce_parameters
is never evoked and non of the parameter values is updated even if I set the value inproduce_impl
. Is that true? Is it possible to work around this? I also triedlayout.update()
.Property of
Cell
objects. InsidePCellDeclarationHelper
we have access to someself.cell
, to which we add shapes. But if I setself.cell.set_property
, these properties are not passed to theCell
object given bylayout.create_cell
, and also it is not passed to theInstance
returned bytopcell.insert
. This relates to the discussion we had above.How to pass out internal variables of
PCellDeclarationHelper
?To check my claims I modified the
Circle
example by adding the following lines to the end ofproduce_impl
:And in a macro I had following lines:
And here is the output I got:
If I open the PCell parameters window in the GUI and only click apply, I get extra output
and if I run single a print command of the macro again, I get
as expected.
I would have been happy, if the output before touching GUI would have included
or something similar.
I know, that I could have set 'ru' in
params
, but my goal was to calculate something insidePCellDeclarationHelper
.I hope you see my point and can suggest a workaround. Perhaps, if I understood it all correctly and you consider adding features, I suggest that
PCell
parameter update was invoked by some additional events via API and theself.cell
parameters formPCellDeclarationHelper
would be passed toCell
objects in thelayout
.KLayout version 0.25.6, Windows 64 bit build obtained from Lukas via the package manger.
Hi,
thanks for the lengthy description ... this discussions isn't new, but here are my points:
1.) doing something from inside the PCell to the objects that use the PCell simply isn't possible. You shouldn't underestimate the complexity of the whole system. The PCell might live in a library which is shared by multiple layouts etc. So then what is the cell or instance that is the PCell in your layout? The cell you see is a pointer (a proxy) to another cell inside a library which itself is a proxy to a PCell variant. The cell you get when you create PCell geometry is the PCell variant proxy. It's cached for performance and two links away from the actual layout. So setting properties on the target layout's cell or even instance simply isn't possible.
2.) The only storage KLayout gives you are the parameters. Only these are persisted in GDS (how this is done is a discussion on it's own). So using hidden parameters is the only way to store additional attributes.
It's true that "coerce_parameters"/"coerce_parameters_impl" is only called on manual changes. That's because the user cannot change readonly or hidden parameters. So "coerce_parameters_impl" is there to compute these values.
When changing parameters programmatically, you don't have this limitation. So you're expected to supply the PCell implementation with the right and consistent parameters. You could even supply a parameter set that goes beyond what is possible in the UI+coerce_parameters. If you really want to have coerce_parameters, you can explicitly call "coerce_parameters" (note: without "_impl"):
There is a strong restriction when a PCell's state can be changed: the functions by which the PCell is supposed to deliver information (update geometry, derive description etc.) are operated in strict readonly mode and cannot modify anything on the PCell. To understand that in detail, you can study the PCellDeclarationHelper implementation which is a thin layer atop of PCellDeclaration. This object lacks some of the convenience of the PCellDeclarationHelper but reveals the strict, low-level API.
Regards,
Matthias
Thank you for a detailed reply! I had a look at
pcell_declaration_helper.lym
and learned about what you described. However, I think I still did not make my goal clear. Sorry for insisting.I never intend to change instance from PCell declaration, I only want to read PCell Cell properties.
lib
object in my code is the libraryCell
, a PCell variant stored in the library layout, right? Why doeslib.property("test")
orlib.library().layout().properties(lib.library().layout().cell(lib.library_cell_index()).prop_id)
not show properties I have set inproduce
? Somehowproduce
has added shapes to theCell
, but not the cell parameters.This is clear, but I would use some parameters as inputs and some readonly parameters as outputs. From the documentation alone it was not clear that only
coerce_parameters
can update parameters. The workaround you suggest works. Now I have to calculate geometry both incoerce_parameters
andproduce
though.Good that it works now :-)
The answer to your question
is simply that "produce" is only intended to produce shapes and instances. By "intended" I mean I have designed it for this purpose and this is the contract between KLayout's core and the PCell implementation. So trying to do something else is working against my design and this contract.
The cell object this method receives is just a container, not necessarily a real cell. Take caching: in this case, "produce" isn't even called. KLayout will take the data from the cell which acts as the data container for the cache. Think of "cell" as "multi-layered container for shapes plus instances", not as something that lives in your target layout. Properties simply aren't part of this concept. Note also that there is no warranty that "produce" is called if KLayout decides that no update is required. The basis KLayout makes this decision is the parameter set alone. The assumption is that if there is no parameter change, not update is required.
Matthias
I keep trying to redesign my architecture, but I keep pumping into this constraint.
Invoking
coerce_parameters
does not solve my problem. First, it would require rerunning the geometry calculations. Secondly, as it does not have access to theCell
object, unlikeproduce
, I cannot produce instances during the calculation. When generating and arranging subcells I produce computationally expensive information and I want to pass it out (like the length of a complex waveguide recursively made of other waveguides). As far as I know I cannot pass anything out from produce except the child instances and shapes. Do I really have to serialize my extra information into text in the shapes?Just to illustrate how hard I try to work around this, here is something I tried to get working for 2 days. I tried setting a class instance variable in
produce
and copied it to a PCell parameter incoerce
. It works if the PCell parameters are unique, as then the PCell is produced just before I callcoerce
(which triggers produce again). However, this works only if produce is called always before coerce as other PCell variants produced meanwhile could leave other values of the instance variable.I think it comes down to philosophy on what can be "produced". I understand, that shapes have to be cached very efficiently, but attaching some metadata to raw geometry really has its use cases in my humble opinion. From reading the documentation I got the wrong impression that "parameters" are exactly for that - metadata for shapes and cells.
Does not solve the problem, if I cannot set the hidden parameters in
produce
. Parameters only seem to be intended as "inputs" for generating the Cell and not "outputs" as metadata.The problem seems to be, that the Porperties are stored in with a layout and do not move together with the geometry. And Parameters are only intended as input.
At this point this seems like the only option: to use a shape or subcell to carry metadata of the parent cell produced in PCell produce. I imagine creating a special "metadata" PCell type, such that I could easily find it if I want to access the metadata
This discussion is getting pretty philosophical. I'd like to have a sample on which we can discuss this further.
As a matter of fact, you cannot access the layout objects and it will stay like this. A program architecture is based on certain interfaces and contracts, and I'm not going to support such a substantial modification of these interfaces. Of course, you can dig into the C++ code if you want to do it yourself. But I think you will just discover why my position is that way.
Basically the roles of the functions are these and this is the contract and the warranties:
So if you want to cache computationally expensive results, you can only use "coerce_parameters". You can use more hidden parameters as shadow parameters to keep track of actual parameter changes to minimize the execution frequency of the computation (if shadow != real value update shadow with real value and trigger computation). The results of any computation can be stored in forms compatible with the parameter types in hidden parameters and read by the "produce" function. Parameter values can be strings, doubles etc.
The number of (hidden) parameters is essentially unlimited, string lengths are limited by the way they are serialized into GDS attributes to about 10k bytes for binary data and about 32k for ASCII.
I you find that this approach is not what you are looking for, I'd strongly suggest to consider a "generator" approach which is non-interactive, like providing a menu function that generates or modifies a cell with a certain layout structure. You'll have all freedom you ask for then. That's what you would do with complex arrangements such a memory blocks. No one would seriously consider implementing a SRAM generator inside a PCell for example.
Matthias
I don't want to push more but just for record for other people reading this.
PCell hidden parameters would not be suitable solutions, since the expensive calculation produces subcells, shapes and metadata. While I could limit the metadata format to fit into concept of hidden cells I doubt I should store shapes and subcells in hidden parameters until I later call produce. (Also, after creating instances in code I would need to manually call coerce_parameters as discussed before.)
Downside of the generator class is that in order to avoid regenerating the geometry I would need to cache the generated elements. This is exactly what PCells do and I would duplicate this functionality. I will consider this when restructuring the project.
My workaround at this point is to have a geometric representation of my metadata which is kept in a extra layer and then it is cashed together with the shapes. It is quite natural to store the endpoints of the waveguide as points. For easy extraction of the waveguide length I generated an extra Line object following the waveguide and it is easy to get the line length in contrast polygons of the curved waveguide.
Thanks for the discuss here, the code from Matthias works for me. smile:
A little problem here, because of the parameter changed, it create a new Pcell variant and the original Pcell variant become unused and appears as a new top cell.
@wishalpha Thanks for sharing the code.
Usually KLayout does a cleanup of such unused cells itself. If it doesn't, you can call
to clean up. The argument is an empty list - if there are precious orphan PCell variants you want to keep you can list their (proxy) cell indexes there.
Matthias
Hi @Matthias
Regarding cleanup(), I find that these orphan PCell variants show up in my layout when I load the GDS file. Namely I save a file with a single top cell, and after opening, there are new orphan top cells.
The specific case is a PCell that creates fixed subcells, where the names are fixed but there are many different instances of the PCell with different parameters. The fixed names get a $1, $2, appended in the subcell, which is fine, except when they are re-evaluated at loading, then I end up with tons of orphans.
I need to run the cleanup function manually after opening the layout. I wrote a script to trigger this to happen automatically after a GDS file is loaded, however, then the layout is marked as edited [+].
I tried adding cleanup() inside the PCells, but that didn't help.
Is there a proper way of having PCells contain subcells and hierarchy?
thank you
Lukas
Hi Lukas,
I did not consider need for cleanup after re-evaluation (specifically after reading), but in your scenario this makes sense.
I created a ticket: https://github.com/KLayout/klayout/issues/1059.
Matthias