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 plugin pass to support non-calibrated rzz angles #2043

Merged
merged 23 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c3c6c3d
add plugin pass to support non-calibrated rzz angles
nkanazawa1989 Nov 13, 2024
5ce4cd2
add release note
nkanazawa1989 Nov 13, 2024
55668ed
update phase check logic
nkanazawa1989 Nov 14, 2024
a45251a
add more document
nkanazawa1989 Nov 14, 2024
0bc77b9
add more angle test
nkanazawa1989 Nov 14, 2024
013a6b4
support control flow
nkanazawa1989 Nov 14, 2024
c3c2af2
Update qiskit_ibm_runtime/transpiler/passes/basis/fold_rzz_angle.py
nkanazawa1989 Nov 14, 2024
8ad8947
Update qiskit_ibm_runtime/transpiler/passes/basis/fold_rzz_angle.py
nkanazawa1989 Nov 14, 2024
5285946
Update qiskit_ibm_runtime/transpiler/passes/basis/fold_rzz_angle.py
nkanazawa1989 Nov 14, 2024
75d86d6
Update documentation wording
wshanks Nov 25, 2024
ec478c4
update test to require the same phase
yaelbh Nov 27, 2024
13524bc
fix quad2 no wrap
yaelbh Nov 27, 2024
38a9d95
fix quad3 no wrap
yaelbh Nov 27, 2024
88c89ea
apply a global phase of pi for a 2pi angle offset
yaelbh Nov 27, 2024
c7e6cea
black
yaelbh Nov 27, 2024
7ec8a81
bug fix
yaelbh Dec 2, 2024
dc90bed
Merge branch 'main' into handle_fractional_constraint
kt474 Dec 2, 2024
bae9209
wrote test_fractional_plugin
yaelbh Dec 3, 2024
4b08e7e
made the _quad functions static methods of the class
yaelbh Dec 3, 2024
300fcc6
Merge branch 'main' of github.com:qiskit/qiskit-ibm-runtime into hand…
yaelbh Dec 3, 2024
9c88806
Update release-notes/unreleased/2043.feat.rst
yaelbh Dec 4, 2024
5c38a6e
deleted a test
yaelbh Dec 4, 2024
c0b8c0f
Merge branch 'main' into handle_fractional_constraint
yaelbh Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 41 additions & 17 deletions qiskit_ibm_runtime/transpiler/passes/basis/fold_rzz_angle.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,59 @@ class FoldRzzAngle(TransformationPass):
"""Fold Rzz gate angle into calibrated range of 0-pi/2 with
local gate tweaks.

This pass preserves the number of Rzz gates, but it may add
extra single qubit gate operations.
These gates might be reduced by the following
single qubit optimization passes.
In the IBM Quantum ISA, the instruction Rzz(theta) has
valid "theta" value of [0, pi/2] and any instruction outside
this range becomes non-ISA operation for the quantum backend.
wshanks marked this conversation as resolved.
Show resolved Hide resolved
The transpiler pass discovers such non-ISA Rzz gates
and folds the gate angle into the calibrated range
with addition of single qubit gates while preserving
logical equivalency of the input quantum circuit.
Added local gates might be efficiently merged into
neighboring single qubit gates by the following single qubit
optimization passes.

This pass allows the Qiskit users to naively use the Rzz gates
with angle of arbitrary real numbers.

.. note::
This pass doesn't transform the circuit when the
Rzz gate angle is unbound parameter.
nkanazawa1989 marked this conversation as resolved.
Show resolved Hide resolved
In this case, the user must assign gate angle before
nkanazawa1989 marked this conversation as resolved.
Show resolved Hide resolved
transpile, or be responsible for choosing parameters
nkanazawa1989 marked this conversation as resolved.
Show resolved Hide resolved
from the calibrated range of [0, pi/2].
"""

def run(self, dag: DAGCircuit) -> DAGCircuit:
# Currently control flow ops and Rzz cannot live in the same circuit.
# Once it's supported, we need to recursively check subroutines.
yaelbh marked this conversation as resolved.
Show resolved Hide resolved
for node in dag.op_nodes():
if not isinstance(node.op, RZZGate) or isinstance(
angle := node.op.params[0], ParameterExpression
):
if not isinstance(node.op, RZZGate):
continue
angle = node.op.params[0]
if isinstance(angle, ParameterExpression) or 0 <= angle <= pi / 2:
yaelbh marked this conversation as resolved.
Show resolved Hide resolved
# Angle is unbound parameter or calibrated value.
wshanks marked this conversation as resolved.
Show resolved Hide resolved
continue
wrap_angle = np.angle(np.exp(1j * angle))
if -pi <= wrap_angle <= -pi / 2:
if 0 <= wrap_angle <= pi / 2:
# In the first quadrant after phase wrapping.
# We just need to remove 2pi offset.
dag.substitute_node(
node,
RZZGate(wrap_angle),
yaelbh marked this conversation as resolved.
Show resolved Hide resolved
inplace=True,
)
continue
if pi / 2 < wrap_angle <= pi:
# In the second quadrant.
replace = _quad2(wrap_angle, node.qargs)
elif -pi <= wrap_angle <= -pi / 2:
# In the third quadrant.
replace = _quad3(wrap_angle, node.qargs)
elif -pi / 2 < wrap_angle < 0:
# In the forth quadrant.
replace = _quad4(wrap_angle, node.qargs)
elif pi / 2 < wrap_angle <= pi:
replace = _quad2(wrap_angle, node.qargs)
else:
if angle != wrap_angle:
dag.substitute_node(
node,
RZZGate(wrap_angle),
inplace=True,
)
continue
raise RuntimeError("Unreacheable.")
dag.substitute_node_with_dag(node, replace)
return dag

Expand Down
12 changes: 12 additions & 0 deletions test/unit/transpiler/passes/basis/test_fold_rzz_angle.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from math import pi
from ddt import ddt, named_data
import numpy as np

from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import Operator
Expand Down Expand Up @@ -61,3 +62,14 @@ def test_folding_rzz_angle_unbound(self):
pm = PassManager([FoldRzzAngle()])
isa = pm.run(qc)
self.assertEqual(qc, isa)

def test_identity(self):
yaelbh marked this conversation as resolved.
Show resolved Hide resolved
"""Create identity circuit with angles with [-4pi, 4pi] and transpile."""
# Angle sum is zero
angles = pi * np.linspace(-4, 4, 17)
yaelbh marked this conversation as resolved.
Show resolved Hide resolved
qc = QuantumCircuit(2)
for angle in angles:
qc.rzz(angle, 0, 1)
pm = PassManager([FoldRzzAngle()])
isa = pm.run(qc)
self.assertTrue(Operator.from_label("II").equiv(Operator.from_circuit(isa)))
Loading