Skip to content
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

Add display of internal circuits for IfElseOps and WhileLoopOps to mpl circuit drawer #10170

Closed
wants to merge 46 commits into from

Conversation

enavarro51
Copy link
Contributor

@enavarro51 enavarro51 commented May 26, 2023

Summary

This PR adds display of the circuits inside IfElseOps to the mpl circuit drawer

Details and comments

UPDATED: Now boxes properly fold onto the next line and no longer a WIP.

UPDATE 2: Added WhileLoopOps

This PR is intended to be merged after #10096. It should accomplish the following

  1. First, do no harm. All circuits without IfElseOps should display EXACTLY as they do in main.
  2. Whether created directly as IfElseOp or through qc.if_test all if-else should display with a box with the if and else circuits inside.

Testers Wanted!

Since the circuits inside the if-else can be very large and complex, it's difficult to test all the scenarios. If you have a qiskit-terra development environment on your local system, just create a new branch out of main, and copy visualization/circuit/utils.py and visualization/circuit/matplotlib.py into the branch. Things to test,

  • Try lots of complex existing circuits to make sure 1. above is satisfied.
  • Create lots of if_test examples with and without else and using different kinds and complexities of circuits.
  • Set fold=-1 to the draw command initially to test 2. This will do no folding.
  • Set fold to a small number and see that the circuits properly wrap.

To do

  • Tests?

Futures

  • Add switch, for, and while control flow ops.
  • Perhaps use some of this capability for showing sub-circuits or expanding gates built from circuits.
qr = QuantumRegister(4, "q")
cr = ClassicalRegister(3, "cr")
qc = QuantumCircuit(qr, cr)
qc.h(0)

with qc.if_test((cr[1], 1)) as _else:
    qc.x(0, label="X1111i").c_if(cr, 4)
    with qc.if_test((cr[2], 1)):
        qc.z(0)
        with qc.if_test((cr[1], 1)):
            qc.cx(0, 1)
            with qc.if_test((cr[2], 1)):
                qc.y(1)
                qc.z(2)
                with qc.if_test((cr[1], 1)):
                    qc.cx(0, 1)
with _else:
    qc.y(1)
    with qc.if_test((cr[2], 1)):
        qc.x(0)
        qc.x(1)
    qr1 = QuantumRegister(2, "qr1")
    cr1 = ClassicalRegister(2, "cr1")
    cr2 = ClassicalRegister(2, "cr2")
    circuit = QuantumCircuit(qr1, cr1, cr2)
    inst = QuantumCircuit(2, 2, name="Inst").to_instruction()
    qc.append(inst, [qr[0], qr[1]], [cr[0], cr[1]])

qc.x(0)
qc.draw(fold=30, style={"showindex": True})

image
Using fold=7, the above circuit looks like this,
image
Directly instantiating the IfElseOp instead of using if_test also works.

qr = QuantumRegister(4, "q")
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)

qr2 = QuantumRegister(3, "qr2")
qc2 = QuantumCircuit(qr2, cr)
qc2.x(1)
qc2.y(1)
qc2.z(0)
qc2.x(0, label="X1i").c_if(cr, 4)

qc.if_else((cr[1], 1), qc2, None, [0, 1, 2], [0, 1, 2])
qc.x(0, label="X1i")
qc.draw(style={"showindex": True}, cregbundle=True)

image

@enavarro51 enavarro51 requested review from a team and nonhermitian as code owners May 26, 2023 17:59
@qiskit-bot
Copy link
Collaborator

One or more of the the following people are requested to review this:

@coveralls
Copy link

coveralls commented May 26, 2023

Pull Request Test Coverage Report for Build 5258853096

  • 155 of 318 (48.74%) changed or added relevant lines in 2 files are covered.
  • 20 unchanged lines in 6 files lost coverage.
  • Overall coverage decreased (-0.04%) to 85.865%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/visualization/circuit/matplotlib.py 153 316 48.42%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/lex.rs 1 91.65%
qiskit/extensions/quantum_initializer/squ.py 2 80.0%
qiskit/transpiler/passes/synthesis/unitary_synthesis.py 2 90.18%
crates/accelerate/src/sabre_swap/layer.rs 4 97.32%
qiskit/visualization/circuit/matplotlib.py 5 52.01%
crates/qasm2/src/parse.rs 6 97.11%
Totals Coverage Status
Change from base Build 5256241220: -0.04%
Covered Lines: 71470
Relevant Lines: 83235

💛 - Coveralls

@enavarro51 enavarro51 changed the title [WIP] Add display of internal circuits for IfElseOps to mpl circuit drawer Add display of internal circuits for IfElseOps to mpl circuit drawer May 29, 2023
@enavarro51 enavarro51 changed the title Add display of internal circuits for IfElseOps to mpl circuit drawer Add display of internal circuits for IfElseOps and WhileLoopOps to mpl circuit drawer Jun 2, 2023
@jakelishman
Copy link
Member

Edwin and I spoke privately, and currently our intention is skip review of this PR and merge #10207 directly, which includes this PR and additionally reworks a fair amount of its internals.

I'll leave this PR unclosed for now, but our current intention is to close it via #10207.

@enavarro51 enavarro51 closed this Jul 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants