-
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
Classical conditioning on individual classical bits now supported #6018
Conversation
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 @TharrmashasthaPV for taking this on! This looks great so far. A few small comments inline.
Can you open separate issues for validation of the condition values and for raising gracefully when attempting to export to QASM2?
qiskit/dagcircuit/dagcircuit.py
Outdated
except StopIteration as ex: | ||
raise DAGCircuitError('Did not find creg containing ' | ||
'mapped clbit in conditional.') from ex |
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 nice generalization that's enabled by this PR (and maybe something to consider for a future issue/contribution) is to allow conditionals that span a list of arbitrary circuit Clbit
s (even if they live in different Register
s). That would allow us to remove this DAGCircuitError
(in the case where the condition doesn't map cleanly to a different register) and instead map the condition to a list of Clbit
s.
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.
So we ( me and @1ucian0 ) have been thinking about the generalization: conditioning on a list of Clbits
. I would certainly be happy to work on it.
qiskit/dagcircuit/dagcircuit.py
Outdated
@@ -351,12 +352,19 @@ def _bits_in_condition(self, cond): | |||
"""Return a list of bits in the given condition. | |||
|
|||
Args: | |||
cond (tuple or None): optional condition (ClassicalRegister, int) | |||
cond (tuple or None): optional condition (ClassicalRegister, int) or (Clbit, int) |
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.
cond (tuple or None): optional condition (ClassicalRegister, int) or (Clbit, int) | |
cond (tuple or None): optional condition (ClassicalRegister, int), (Clbit, int), or (Clbit, bool) |
qiskit/dagcircuit/dagcircuit.py
Outdated
@@ -320,13 +320,14 @@ def _check_condition(self, name, condition): | |||
|
|||
Args: | |||
name (string): used for error reporting | |||
condition (tuple or None): a condition tuple (ClassicalRegister,int) | |||
condition (tuple or None): a condition tuple (ClassicalRegister,int), | |||
(Clbit,Bool) or (Clbit,int) |
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.
(Clbit,Bool) or (Clbit,int) | |
(Clbit, bool) or (Clbit, int) |
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 for taking this on @TharrmashasthaPV , this looks great! Is there a release note covering this in any of the PRs? If not, it'd be good to add one here.
Thanks a lot for the review @kdk . I have not added a release note yet. I will be sure to add one. |
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 @TharrmashasthaPV !
In Qiskit#6018 initial support for adding classical conditions on a single bit instead of a register was added. However this wasn't accounted for in qpy because it didn't exist when qpy was first written. This commit adds support to qpy without a file format change so it can be backported and used with already released versions of qpy without needing a new format version. This is accomplished by exploiting the strict register naming in qiskit. A register can't have a name outside of regex "[a-z][a-zA-Z0-9_]*" which we leverage in the case of single clbit conditions the "register" name in the output QPY data is set to str(clbit_index) which isn't a valid name. Then on the loading side we check for a valid name, if it's outside the allowed regex we treat the condition as a single bit and the name is a str(index). The tradeoff here is that for a QPY file generated with 0.18.1 (assuming this is backported and included in 0.18.1) this qpy file can not be loaded with qiskit 0.18.0. But this is fine as we only guarantee compatibility in one direction (loading qpy files generated with older with qiskit with a newer version of qiskit). Fixes partially Qiskit#6475
* Handle single bit conditions in QPY In #6018 initial support for adding classical conditions on a single bit instead of a register was added. However this wasn't accounted for in qpy because it didn't exist when qpy was first written. This commit adds support to qpy without a file format change so it can be backported and used with already released versions of qpy without needing a new format version. This is accomplished by exploiting the strict register naming in qiskit. A register can't have a name outside of regex "[a-z][a-zA-Z0-9_]*" which we leverage in the case of single clbit conditions the "register" name in the output QPY data is set to str(clbit_index) which isn't a valid name. Then on the loading side we check for a valid name, if it's outside the allowed regex we treat the condition as a single bit and the name is a str(index). The tradeoff here is that for a QPY file generated with 0.18.1 (assuming this is backported and included in 0.18.1) this qpy file can not be loaded with qiskit 0.18.0. But this is fine as we only guarantee compatibility in one direction (loading qpy files generated with older with qiskit with a newer version of qiskit). Fixes partially #6475 * Add release note * Prefix bit index with null character This commit modifies the special string we use in the register name field to be prefixed with a null character. This leaves open using the string for other special cases and also returning a sane error if an invalid QPY file was generated by something besides Qiskit. * Update qiskit/circuit/qpy_serialization.py Co-authored-by: Jake Lishman <jake@binhbar.com> * Add note to release note about feature not being supported * Add backwards compat test case too Co-authored-by: Jake Lishman <jake@binhbar.com> Co-authored-by: Jake Lishman <jake.lishman@ibm.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* Handle single bit conditions in QPY In #6018 initial support for adding classical conditions on a single bit instead of a register was added. However this wasn't accounted for in qpy because it didn't exist when qpy was first written. This commit adds support to qpy without a file format change so it can be backported and used with already released versions of qpy without needing a new format version. This is accomplished by exploiting the strict register naming in qiskit. A register can't have a name outside of regex "[a-z][a-zA-Z0-9_]*" which we leverage in the case of single clbit conditions the "register" name in the output QPY data is set to str(clbit_index) which isn't a valid name. Then on the loading side we check for a valid name, if it's outside the allowed regex we treat the condition as a single bit and the name is a str(index). The tradeoff here is that for a QPY file generated with 0.18.1 (assuming this is backported and included in 0.18.1) this qpy file can not be loaded with qiskit 0.18.0. But this is fine as we only guarantee compatibility in one direction (loading qpy files generated with older with qiskit with a newer version of qiskit). Fixes partially #6475 * Add release note * Prefix bit index with null character This commit modifies the special string we use in the register name field to be prefixed with a null character. This leaves open using the string for other special cases and also returning a sane error if an invalid QPY file was generated by something besides Qiskit. * Update qiskit/circuit/qpy_serialization.py Co-authored-by: Jake Lishman <jake@binhbar.com> * Add note to release note about feature not being supported * Add backwards compat test case too Co-authored-by: Jake Lishman <jake@binhbar.com> Co-authored-by: Jake Lishman <jake.lishman@ibm.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit afb0c47)
* Handle single bit conditions in QPY In #6018 initial support for adding classical conditions on a single bit instead of a register was added. However this wasn't accounted for in qpy because it didn't exist when qpy was first written. This commit adds support to qpy without a file format change so it can be backported and used with already released versions of qpy without needing a new format version. This is accomplished by exploiting the strict register naming in qiskit. A register can't have a name outside of regex "[a-z][a-zA-Z0-9_]*" which we leverage in the case of single clbit conditions the "register" name in the output QPY data is set to str(clbit_index) which isn't a valid name. Then on the loading side we check for a valid name, if it's outside the allowed regex we treat the condition as a single bit and the name is a str(index). The tradeoff here is that for a QPY file generated with 0.18.1 (assuming this is backported and included in 0.18.1) this qpy file can not be loaded with qiskit 0.18.0. But this is fine as we only guarantee compatibility in one direction (loading qpy files generated with older with qiskit with a newer version of qiskit). Fixes partially #6475 * Add release note * Prefix bit index with null character This commit modifies the special string we use in the register name field to be prefixed with a null character. This leaves open using the string for other special cases and also returning a sane error if an invalid QPY file was generated by something besides Qiskit. * Update qiskit/circuit/qpy_serialization.py Co-authored-by: Jake Lishman <jake@binhbar.com> * Add note to release note about feature not being supported * Add backwards compat test case too Co-authored-by: Jake Lishman <jake@binhbar.com> Co-authored-by: Jake Lishman <jake.lishman@ibm.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit afb0c47) Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Hi @TharrmashasthaPV |
Summary
Fixes #1160 .
Details and comments
Before this PR the classical conditioning of gates only allowed conditioning on classical registers. As a follow up of discussions in #1160 , this PR allows conditioning gates on single classical bits too. Various tests have been included.
Known Issues:
m
bit integer as the condition value for condition on a creg ofn
classical bits (wherem>n
) does not raise error .qc.qasm()
breaks when circuitqc
contains gates with classical conditioning on a single cbit.qc.depth()
also breaks. Refer to Classical conditioning on individual classical bits now supported #6018 (comment)disassemble(qc_assembled)
breaks whereqc_assembled
is an assembledQobj
.qc.num_connected_components
breaks.circuit_to_instruction(qc)
breaks._check_wires_list()
andsubstitute_node_with_dag()
methods in qiskit/dagcircuit/dagcircuit.py break._is_same_c_conf()
method inForwardMatch
andBackwardMatch
classes in qiskit/transpiler/passes/optimization/template_matching breaks.run()
method inConsolidateBlocks
class in qiskit/transpiler/passes/optimization breaks.