Skip to content

Commit

Permalink
added instruction pi_phi to target for urdd DD and converted from bac…
Browse files Browse the repository at this point in the history
…kend to target
  • Loading branch information
nbronn committed Aug 9, 2024
1 parent b0f6dce commit c0c1934
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 24 deletions.
11 changes: 5 additions & 6 deletions qiskit_research/utils/convenience.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from qiskit.circuit import Gate
from qiskit.circuit.library import XGate
from qiskit.providers.backend import Backend
from qiskit.transpiler import PassManager
from qiskit.transpiler import PassManager, Target
from qiskit.transpiler.passes.scheduling import ALAPScheduleAnalysis
from qiskit.transpiler.passes.scheduling.scheduling.base_scheduler import BaseScheduler

Expand All @@ -37,7 +37,7 @@

def add_dynamical_decoupling(
circuits: Union[QuantumCircuit, List[QuantumCircuit], List[List[QuantumCircuit]]],
backend: Backend,
target: Target,
dd_str: str,
scheduler: BaseScheduler = ALAPScheduleAnalysis,
add_pulse_cals: bool = False,
Expand Down Expand Up @@ -67,23 +67,22 @@ def add_dynamical_decoupling(
single or sequence type of QuantumCircuit, shceduled with DD sequences
inserted into idle times.
"""

pass_manager = PassManager(
list(
dynamical_decoupling_passes(
backend, dd_str, scheduler, urdd_pulse_num=urdd_pulse_num
target, dd_str, scheduler, urdd_pulse_num=urdd_pulse_num
)
)
)
if isinstance(circuits, QuantumCircuit) or isinstance(circuits[0], QuantumCircuit):
circuits_dd = pass_manager.run(circuits)
if add_pulse_cals:
add_pulse_calibrations(circuits_dd, backend, pulse_method=pulse_method)
add_pulse_calibrations(circuits_dd, target, pulse_method=pulse_method)
else:
circuits_dd = [pass_manager.run(circs) for circs in circuits]
if add_pulse_cals:
for circs_dd in circuits_dd:
add_pulse_calibrations(circs_dd, backend, pulse_method=pulse_method)
add_pulse_calibrations(circs_dd, target, pulse_method=pulse_method)

return circuits_dd

Expand Down
25 changes: 14 additions & 11 deletions qiskit_research/utils/dynamical_decoupling.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import numpy as np
from qiskit import QuantumCircuit, pulse
from qiskit.circuit import Gate, Qubit
from qiskit.circuit import Gate, Parameter, Qubit
from qiskit.circuit.delay import Delay
from qiskit.circuit.library import U3Gate, UGate, XGate, YGate
from qiskit.circuit.reset import Reset
Expand All @@ -26,7 +26,7 @@
from qiskit.providers.backend import Backend
from qiskit.pulse import Drag, Waveform
from qiskit.synthesis import OneQubitEulerDecomposer
from qiskit.transpiler import InstructionDurations
from qiskit.transpiler import InstructionDurations, Target
from qiskit.transpiler.basepasses import BasePass
from qiskit.transpiler.exceptions import TranspilerError
from qiskit.transpiler.instruction_durations import InstructionDurationsType
Expand Down Expand Up @@ -69,7 +69,7 @@ class PulseMethod(Enum):


def dynamical_decoupling_passes(
backend: Backend,
target: Target,
dd_str: str,
scheduler: BaseScheduler = ALAPScheduleAnalysis,
urdd_pulse_num: int = 4,
Expand All @@ -87,18 +87,21 @@ def dynamical_decoupling_passes(
Yields:
Iterator[Iterable[BasePass]]: Transpiler passes used for adding DD sequences.
"""
target = backend.target
for new_gate in [Xp, Xm, Yp, Ym]:
target.add_instruction(new_gate, target["x"])
durations = target.durations()
if new_gate.name not in target:
target.add_instruction(new_gate, target["x"])

if dd_str in DD_SEQUENCE:
sequence = DD_SEQUENCE[dd_str]
elif dd_str == "URDD":
phis = get_urdd_angles(urdd_pulse_num)
sequence = tuple(PiPhiGate(phi) for phi in phis)
yield scheduler(durations)
yield PadDynamicalDecoupling(durations, list(sequence))
if "pi_phi" not in target:
phi = Parameter("φ")
target.add_instruction(PiPhiGate(phi), target["x"])

yield scheduler(target.durations())
yield PadDynamicalDecoupling(target.durations(), list(sequence))


def periodic_dynamical_decoupling(
Expand Down Expand Up @@ -173,7 +176,7 @@ def periodic_dynamical_decoupling(
# TODO refactor this as a CalibrationBuilder transpilation pass
def add_pulse_calibrations(
circuits: Union[QuantumCircuit, List[QuantumCircuit]],
backend: Backend,
target: Target,
pulse_method: PulseMethod = PulseMethod.PHASESHIFT,
) -> None:
"""
Expand All @@ -190,8 +193,8 @@ def add_pulse_calibrations(
Raises:
ValueError: Not a defined method for implementing pulse schedules for URDD gates.
"""
inst_sched_map = backend.defaults().instruction_schedule_map
num_qubits = backend.configuration().num_qubits
inst_sched_map = target.instruction_schedule_map()
num_qubits = target.num_qubits

if isinstance(circuits, QuantumCircuit):
circuits = [circuits]
Expand Down
19 changes: 12 additions & 7 deletions test/utils/test_dynamical_decoupling.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

import unittest

from qiskit import transpile
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

from qiskit_research.utils.convenience import (
Expand All @@ -38,9 +38,11 @@ def test_add_dynamical_decoupling(self):
circuit.rx(1.0, [0, 1, 2])

backend = FakeSherbrooke()
transpiled = transpile(circuit, backend)
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=2)
transpiled = pm.run(circuit)
transpiled_dd = add_dynamical_decoupling(
transpiled, backend, "XY4pm", add_pulse_cals=True
transpiled, target, "XY4pm", add_pulse_cals=True
)
self.assertIsInstance(transpiled_dd, QuantumCircuit)
self.assertIn("xp", transpiled_dd.count_ops())
Expand All @@ -60,10 +62,12 @@ def test_add_urdd_dynamical_decoupling(self):
circuit.rx(1.0, [0, 1, 2])

backend = FakeSherbrooke()
transpiled = transpile(circuit, backend)
target = backend.target
pm = generate_preset_pass_manager(2, backend)
transpiled = pm.run(circuit)
transpiled_urdd4 = add_dynamical_decoupling(
transpiled,
backend,
target,
"URDD",
add_pulse_cals=True,
urdd_pulse_num=4,
Expand All @@ -75,7 +79,7 @@ def test_add_urdd_dynamical_decoupling(self):

transpiled_urdd8 = add_dynamical_decoupling(
transpiled,
backend,
target,
"URDD",
add_pulse_cals=True,
urdd_pulse_num=8,
Expand All @@ -89,7 +93,8 @@ def test_add_pulse_calibrations(self):
"""Test adding dynamical decoupling."""
circuit = QuantumCircuit(2)
backend = FakeSherbrooke()
add_pulse_calibrations(circuit, backend)
target = backend.target
add_pulse_calibrations(circuit, target)
for key in circuit.calibrations["xp"]:
drag_xp = circuit.calibrations["xp"][key].instructions[0][1].operands[0]
drag_xm = circuit.calibrations["xm"][key].instructions[0][1].operands[0]
Expand Down

0 comments on commit c0c1934

Please sign in to comment.