-
Notifications
You must be signed in to change notification settings - Fork 12
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
feat: handle IfElseOp
in qiskit_to_tk
#437
Conversation
The test case I added is now working after 52458ab. I'll need to add more diverse test cases before I'm confident in merging this as well as negate the "else" condition properly and see what the story is for more complex conditions. |
IfElseOp
in qiskit_to_tk
IfElseOp
in qiskit_to_tk
|
||
# Coniditions must be on a single bit (for now) | ||
assert len(if_else_op.condition) == 2 | ||
if not isinstance(if_else_op.condition[0], Clbit): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said in the description I've restricted to the case of single bit conditions for now. However it should be easy enough to generalise for conditons on values of entire registers in a follow up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check that len(bits) == 1
, or perhaps change the signature of this function to take a single Bit
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the former suggestion as the restriction to a single bit should be removable soon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR description says that this closes #366 , but this does not change tk_to_qiskit
a all does it? Did you intend to address that direction as well?
tests/qiskit_convert_test.py
Outdated
assert tkc.n_gates_of_type(OpType.Conditional) == 2 | ||
if_cond, else_cond = tuple(tkc.commands_of_type(OpType.Conditional)) | ||
|
||
if_circ = if_cond.op.op.get_circuit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mypy check is failing. Probably need to assert that op
is a Conditional
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this was the issue. It doesn't matter anymore as I've redone the test.
circ = circ_builder.circuit() | ||
|
||
# Coniditions must be on a single bit (for now) | ||
assert len(if_else_op.condition) == 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to raise an exception rather than assert
-- assert
is best reserved for catching internal logic errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I considered this. I should add an exception to do things properly.
My assumption was that the object returned from if_else_op.condition
would always be of length 2 however this may not be true.
I think for conditions on multiple bits this could be longer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see cebf4dd
|
||
# Coniditions must be on a single bit (for now) | ||
assert len(if_else_op.condition) == 2 | ||
if not isinstance(if_else_op.condition[0], Clbit): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check that len(bits) == 1
, or perhaps change the signature of this function to take a single Bit
?
args=qubits, | ||
condition_bits=bits, | ||
# TODO: handle conditions over multiple bits/registers? | ||
condition_value=not bool(if_else_op.condition[1]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is if_else_op.condition[1]
an int
? Can we check that it is 0 or 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a check in cebf4dd
|
||
expected_circ.Measure(q1_tk[0], c1_tk[0]) | ||
|
||
assert tket_circ_if_else == expected_circ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A similar test including an else
condition would be good to add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turned the two branch test into an explicit equality check in a40732d
Description
Converting a qiskit IfElseOp as two conditional pytket
CircBox
es. This sort of control flow is probably better expressed in the HUGR data structure than as a pytketCircuit/CircBox
.Theres a C.I. failure for one of the tests I added that I can't reproduce locally -> https://github.com/CQCL/pytket-qiskit/actions/runs/12811218709/job/35720030508#step:7:786
Needs more diverse test cases before merging and we also need to decide if we want to handle more complex conditions.
NOTE: For now I've restricted to conditions on a single bit but we should generalise this. This PR is already quite busy.
Looking at the qiskit docs they also have switch-case as well as for and while loops which we may want to support in the future.
https://docs.quantum.ibm.com/guides/classical-feedforward-and-control-flow
Example
Now the corresponding pytket circuit looks like
The$H$ and $X$ gate respectively.
If
andElse
boxes contain a singleI thought about putting string representing the conditon inside the "If" label however this could be awkward. Hopefully its clear from the diagram whats going on.
This conversion ended up being slighly tricker than I expected because the qiskit circuits which define the
true_body
andfalse_body
do not have registers. Managed to get around this by using the register from the circuit containing theIfElseOp
and cleaning up empty wires withCircuit.remove_blank_wires
to ensure theCircBox
is of the correct size.Related issues
closes #415
Checklist