-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better drawings for control flow #8904
Comments
@jakelishman as discussed on slack |
@gabrieleagl I've thought about this a bit as well. I feel like your Idea 1 will work and provides the best option. For the mpl drawer, it might not require changing the wire spacing, and the text drawer already adjusts wire spacing to fit other text between gates. I believe it would be possible to adapt the current The text and latex drawers may require a bit more work, since there is not as much flexibility with the spacing and fonts. |
Here's a not-ready-for-primetime demo for the mpl drawer with an 'if'. This took a bit less than 50 lines of code, so no major restructuring of the drawer is required. This should work with any arbitrary circuit inside the 'if', and should also work with any of the other ControlFlowOps. To-dos:
|
Oh, this looks great as a start, thanks so much Edwin! For your sanity: I think drawing the box around the clbits is the more sensible way to go - control-flow may well act on the bits that it's conditioned on, and it'd start getting really confusing trying to do something sensible if the block's condition was on a clbit that's above (in the drawing) another clbit it acts on. Instead, to show the condition better, perhaps we don't draw the condition at all (in the normal mechanism), and instead write some representation of it up above the blocks? I think that'll be easier to make things like paired "if" and "else" blocks look better - we could do something like write the condition, then have a big brace coming out from it to hold the two blocks, so it's clear they're from the same condition. One more thing to consider: I think we'll still want a sensible way of showing qubits/clbits that are unaffected by the blocks, much like opaque instructions currently do in the drawers. We can probably do that by drawing some sigil where the input wires cross the block delimiter, or perhaps better, we could try to not draw the wires at all within the block? |
I'm keen to stick close to what Edwin thinks is reasonably implementable here, because we 100% do not have the resources to make Qiskit's visualisations "perfect". We've generally maintained the position that we would support a more full-featured visualisation package being responsible for the best drawings, and that Qiskit's internal support is just best-effort. As a direct response: I think drawing the box around all the affected wires (both qubit and clbit), and not doing something different between qubits and clbits is the best way forwards. There are many edge cases, such as blocks that aren't on visually contiguous qubits/clbits, that are already considered for opaque instructions (i.e. we draw a box from the top-most qubit to bottom-most clbit and label unused wires), and I think it will be simplest to stick close to that type of approach. It will also mean that if a control-flow block contains one of these opaque instructions, we won't suddenly end up with the case where an opaque instruction is sticking out of the surrounding control-flow box. I agree that writing out the condition / loop indices above the box(es) will probably be the neatest (and easier to implement). |
@gabrieleagl I thought of something similar to your top drawing, but I think it's probably simpler and more easily readable if we just put the condition for the IfElseOp in text at the top. And for the loops that would work as well. More demos to follow. |
This looks great, thanks Edwin. For how to handle wrapping: my initial reaction is that we could just count these boxes as "atomic", and force them to start a new line if necessary. If they're still too long for the line length, then we could just extend the line - I think it'll be pretty hard to read if we split the boxes. I'm completely open to whatever you've got in mind too. I don't have preferences on box shape or colour, provided that the colour is distinguishable, controllable in user stylesheets, and for our default style probably just uses an existing colour. Your picture looks like it matches all those points. In your "box scaling": your box seems to scale horizontally but not vertically. Is that just because you built the qr = QuantumRegister(4, "qr")
cr = ClassicalRegister(3, "cr")
qc = QuantumCircuit(qr, cr)
qc.h(0)
qc.h(1)
qc.measure(0, 1)
qc.measure(1, 2)
qc.x(2)
qc.x(2, label="XLabel").c_if(cr, 2)
with qc.if_test((cr[1], 1)):
qc.x(1)
qc.y(1)
qc.x(0)
qc.x(2).c_if(cr, 4)
qc.x(0)
qc.draw(style={"showindex": True}) Your plan sounds sensible to me. |
Great job @enavarro51 - I love it! For the problem of breaking lines, another option could be to make two boxes on the two lines, and finding a way to mark that it's a continuation (such as a double or dashed line on the right side of the box on the first line, and a similar double or dashed on the left of the second line). One possibly hard test case, that you didn't mention: a gate that is both quantum-controlled and classically-conditioned. |
So this crazy circuit,
produces this crazy drawing The plan is now to do 2 PRs. The first will be a number of structural data changes that alter 200 lines of the mpl drawer code, but should function exactly as the current main. This was discussed with @jakelishman and is being done to simplify the review process, since these changes are almost all simple like changing The second will be a WIP PR for the actual if/else functionality. The big missing piece right now, other than more testing, is how to wrap the if/else boxes. |
I think this was closed via #10207 Let me know otherwise. |
What should we add?
Currently,
if_else
,while_loop
andfor_loop
are represented in drawings as black boxes.Additionally, the tested condition is not explicit in the drawing.
I propose adding a more explicit representation.
In the figure below I propose two alternatives, so that we can choose one or discuss an even better option.
The text was updated successfully, but these errors were encountered: