[WIP] control methods produce annotated operations by default #13870
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
AnnotatedOperation
s allow to define a "controlled" version of a gate when a circuit is being constructed, without having to eagerly synthesize the gate in the process. The actual synthesis is left to the transpiler (and specifically to theHighLevelSynthesis
transpiler pass). This offers at least two benefits:The
control
method forGate
s andQuantumCircuit
s already accepts the argumentannotated
which can be eitherFalse
,True
orNone
, with roughly the following semantics:False
, the annotated version of the gate is not constructed, with the only exception that anannotated=False
-controlled version of anAnnotatedOperation
is anAnnotatedOperation
as well.True
, the annotated operation is constructed, except for gates that implement their own control method, thus anannotated=True
-controlled version of anXGate
will produce either aCX-Gate
, aCCX-Gate
, or anMCX-Gate
.None
, we attempt to construct anannotated=False
-version, but if this fails, such as when the gate is parameterized, we create theannotated=True
-version.In the above,
None
is the default.In addition, for backward compatibility (at the time), when a
QuantumCircuit
is converted to aGate
using theto_gate
method, the argumentannotated
is set toFalse
. Unfortunately, this means that when constructing hierarchical circuits that involve controlled subcircuits, the subcircuits are typically not annotated, preventing potential transpiler optimizations. For example this is the case for the older version of circuits in the circuit library, though this is somewhat improved for the new gate classes whencontrol(annotated=True)
is explicitly specified. On the other hand, most of the user circuit are not constructed usingannotated=True.
The suggestion here is to change the default behavior to construct annotated versions of a gate (unless the gate implements a custom
control
method). This is a breaking API change, and in particular if someone now writesmy_controlled_custom_gate = my_custom_gate.control(3)
, themy_controlled_custom_gate
will no longer be an instance ofControlledGate
. I don't if this can break a lot of user code potentially depend on thisisinstance
check. In addition, themy_controlled_custom_gate
will not have adefinition
available, one would need to usetranspile
/HighLevelSynthesis
to obtain one.I would like to discuss if we can add this breaking change to 2.0 or possibly to a later release, and what the migration path for the users should be. Comments are highly welcome.
This PR shows that the number of factual changes within Qiskit is very small: the main difference comes up in visualization, where the name of a
ControlledGate
-version of a gate is drawn with all letters lowercased, while the name of anAnnotatedOperation
-version of a gate is drawn with first letter uppercased (compare "ghz" and "Ghz"); and also the annotated-control SWAP gate is drawn differently.