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

transpiler: always decompose wrapped-angle RXX gates #145

Merged
merged 1 commit into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

* Only support Qiskit >= 1.0 (#141)
* Transpiler: always decompose wrapped-angle RXX gates (#145)

## qiskit-aqt-provider v1.3.0

Expand Down
5 changes: 4 additions & 1 deletion qiskit_aqt_provider/transpiler_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ def pass_manager(
if isinstance(pass_manager_config.target, UnboundParametersTarget):
return translation_pm

passes: list[BasePass] = [WrapRxxAngles()]
passes: list[BasePass] = [
WrapRxxAngles(),
Decompose([f"{WrapRxxAngles.SUBSTITUTE_GATE_NAME}*"]),
]

return translation_pm + PassManager(passes)
16 changes: 11 additions & 5 deletions test/test_transpilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_rx_rewrite_example(


@given(theta=st.floats(allow_nan=False, min_value=-1000 * pi, max_value=1000 * pi))
@pytest.mark.parametrize("optimization_level", [1, 2, 3])
@pytest.mark.parametrize("optimization_level", [0, 1, 2, 3])
@pytest.mark.parametrize("test_gate", [RXGate, RYGate])
def test_rx_ry_rewrite_transpile(
theta: float,
Expand Down Expand Up @@ -202,7 +202,7 @@ def test_rxx_wrap_angle_case2_negative() -> None:
)
)
@pytest.mark.parametrize("qubits", [3])
@pytest.mark.parametrize("optimization_level", [1, 2, 3])
@pytest.mark.parametrize("optimization_level", [0, 1, 2, 3])
def test_rxx_wrap_angle_transpile(angle: float, qubits: int, optimization_level: int) -> None:
"""Check that Rxx angles are wrapped by the transpiler."""
assume(abs(angle) > pi / 200)
Expand All @@ -222,21 +222,27 @@ def test_rxx_wrap_angle_transpile(angle: float, qubits: int, optimization_level:

# in high optimization levels, the gate might be dropped
assume(num_rxx is not None)
assert num_rxx == 1
if optimization_level != 3:
# qiskit's optimzation level 3 only emits RXX(π/2), so there
# may be more than one RXX gate in the transpiled circuit.
assert num_rxx == 1

# check that all Rxx have angles in [0, π/2]
num_checked_gates = 0
for operation in trans_qc.data:
instruction = operation[0]
if instruction.name == "rxx":
(theta,) = instruction.params
assert 0 <= float(theta) <= pi / 2
break # there's only one Rxx gate in the circuit
num_checked_gates += 1
if num_checked_gates == num_rxx:
break
else: # pragma: no cover
pytest.fail("Transpiled circuit contains no Rxx gate.")


@pytest.mark.parametrize("qubits", [1, 5, 10])
@pytest.mark.parametrize("optimization_level", [1, 2, 3])
@pytest.mark.parametrize("optimization_level", [0, 1, 2, 3])
def test_qft_circuit_transpilation(
qubits: int, optimization_level: int, offline_simulator_no_noise: AQTResource
) -> None:
Expand Down