-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add control-flow builder interface (#7282)
* Add control-flow builder interface This adds a builder interface for control-flow operations on `QuantumCircuit` (such as `ForLoopOp`, `IfElseOp`, and `WhileLoopOp`). The interface uses the same circuit methods, but they are now overloaded so that if the ``body`` parameter is not given, they return a context manager. Entering one of these context managers pushes a scope into the circuit, and captures all gate calls (and other scopes) and the resources these use, and builds up the relevant operation at the end. For example, you can now do: qc = QuantumCircuit(2, 2) with qc.for_loop(None, range(5)) as i: qc.rx(i * math.pi / 4, 0) This will produce a `ForLoopOp` on `qc`, which knows that qubit 0 is the only resource used within the loop body. These context managers can be nested, and will correctly determine their widths. You can use `break_loop` and `continue_loop` within a context, and it will expand to be the correct width for its containing loop, even if it is nested in further `if_test` blocks. The `if_test` context manager provides a chained manager which, if desired, can be used to create an `else` block, such as by qreg = QuantumRegister(2) creg = ClassicalRegister(2) qc = QuantumCircuit(qreg, creg) qc.h(0) qc.cx(0, 1) qc.measure(0, 0) with qc.if_test((creg, 0)) as else_: qc.x(1) with else_: qc.z(1) The manager will ensure that the `if` and `else` bodies are defined over the same set of resources. This commit also ensures that instances of `ParameterExpression` added to a circuit inside _all_ control flow instructions will correctly propagate up to the top-level circuit. * Fix linter complaints * Fix typos Co-authored-by: Kevin Hartman <kevin@hart.mn> * Add extra error check * Remove useless early return * Document qubits, clbits in ControlFlowBlockBuilder.__init__ * Remove comment that is likely to stagnate * Add extra else test * Improve developer documentation in InstructionPlaceholder * Remove expected failure from test This branch contains the fix that this test depended on. * Remove unused import * Change order of for_loop parameters This changes the parameter order of `QuantumCircuit.for_loop` to be indexset, [loop_parameter, [body, qubits, clbits]] whereas previously it was loop_parameter, indexset, [body, qubits, clbits] Similar changes were made within the constructor of `ForLoopOp` and its parameters. This is to improve ergonomics of the builder interface, where it is not generally necessary to specify a loop variable, since one is allocated for the user. Co-authored-by: Kevin Hartman <kevin@hart.mn>
- Loading branch information
1 parent
efbf436
commit 9ba51b5
Showing
16 changed files
with
3,889 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2021. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""Functions for dealing with classical conditions.""" | ||
|
||
from typing import Tuple, Union | ||
|
||
from qiskit.circuit.classicalregister import ClassicalRegister, Clbit | ||
from qiskit.circuit.exceptions import CircuitError | ||
|
||
|
||
def validate_condition( | ||
condition: Tuple[Union[ClassicalRegister, Clbit], int] | ||
) -> Tuple[Union[ClassicalRegister, Clbit], int]: | ||
"""Validate that a condition is in a valid format and return it, but raise if it is invalid. | ||
Args: | ||
condition: the condition to be tested for validity. | ||
Raises: | ||
CircuitError: if the condition is not in a valid format. | ||
Returns: | ||
The same condition as passed, if it was valid. | ||
""" | ||
try: | ||
bits, value = condition | ||
if isinstance(bits, (ClassicalRegister, Clbit)) and isinstance(value, int): | ||
return (bits, value) | ||
except (TypeError, ValueError): | ||
pass | ||
raise CircuitError( | ||
"A classical condition should be a 2-tuple of `(ClassicalRegister | Clbit, int)`," | ||
f" but received '{condition!r}'." | ||
) | ||
|
||
|
||
def condition_bits(condition: Tuple[Union[ClassicalRegister, Clbit], int]) -> Tuple[Clbit, ...]: | ||
"""Return the classical resources used by ``condition`` as a tuple of :obj:`.Clbit`. | ||
This is useful when the exact set of bits is required, rather than the logical grouping of | ||
:obj:`.ClassicalRegister`, such as when determining circuit blocking. | ||
Args: | ||
condition: the valid condition to extract the bits from. | ||
Returns: | ||
a tuple of all classical bits used in the condition. | ||
""" | ||
return (condition[0],) if isinstance(condition[0], Clbit) else tuple(condition[0]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.