Skip to content
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
5 changes: 2 additions & 3 deletions qiskit/transpiler/passes/calibration/rzx_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ def __init__(
"""
super().__init__()

if instruction_schedule_map is None:
raise QiskitError("Calibrations can only be added to Pulse-enabled backends")

if qubit_channel_mapping:
warnings.warn(
"'qubit_channel_mapping' is no longer used. This value is ignored.",
Expand All @@ -97,6 +94,8 @@ def __init__(
self._verbose = verbose
if target:
self._inst_map = target.instruction_schedule_map()
if self._inst_map is None:
raise QiskitError("Calibrations can only be added to Pulse-enabled backends")

def supported(self, node_op: CircuitInst, qubits: List) -> bool:
"""Determine if a given node supports the calibration.
Expand Down
128 changes: 127 additions & 1 deletion test/python/transpiler/test_calibrationbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from qiskit import circuit, schedule
from qiskit.circuit.library.standard_gates import SXGate, RZGate
from qiskit.providers.fake_provider import FakeHanoi
from qiskit.providers.fake_provider import FakeHanoi, FakeHanoiV2
from qiskit.pulse import (
ControlChannel,
DriveChannel,
Expand Down Expand Up @@ -109,6 +109,132 @@ def test_rzx_calibration_rotary_pulse_stretch(self, theta: float):

self.assertEqual(test_sched.duration, self.compute_stretch_duration(self.d1p_play, theta))

def test_native_cr_with_target(self):
"""Test that correct pulse sequence is generated for native CR pair."""
# Sufficiently large angle to avoid minimum duration, i.e. amplitude rescaling
theta = np.pi / 4

qc = circuit.QuantumCircuit(2)
qc.rzx(theta, 0, 1)

target = FakeHanoiV2().target

_pass = RZXCalibrationBuilder(target=target)
test_qc = PassManager(_pass).run(qc)

duration = self.compute_stretch_duration(self.u0p_play, theta)
with builder.build(
self.backend,
default_alignment="sequential",
default_transpiler_settings={"optimization_level": 0},
) as ref_sched:
with builder.align_left():
# Positive CRs
u0p_params = self.u0p_play.pulse.parameters
u0p_params["duration"] = duration
u0p_params["width"] = self.compute_stretch_width(self.u0p_play, theta)
builder.play(
GaussianSquare(**u0p_params),
ControlChannel(0),
)
d1p_params = self.d1p_play.pulse.parameters
d1p_params["duration"] = duration
d1p_params["width"] = self.compute_stretch_width(self.d1p_play, theta)
builder.play(
GaussianSquare(**d1p_params),
DriveChannel(1),
)
builder.x(0)
with builder.align_left():
# Negative CRs
u0m_params = self.u0m_play.pulse.parameters
u0m_params["duration"] = duration
u0m_params["width"] = self.compute_stretch_width(self.u0m_play, theta)
builder.play(
GaussianSquare(**u0m_params),
ControlChannel(0),
)
d1m_params = self.d1m_play.pulse.parameters
d1m_params["duration"] = duration
d1m_params["width"] = self.compute_stretch_width(self.d1m_play, theta)
builder.play(
GaussianSquare(**d1m_params),
DriveChannel(1),
)
builder.x(0)

self.assertEqual(schedule(test_qc, self.backend), target_qobj_transform(ref_sched))

def test_non_native_cr_with_target(self):
"""Test that correct pulse sequence is generated for non-native CR pair."""
# Sufficiently large angle to avoid minimum duration, i.e. amplitude rescaling
theta = np.pi / 4

qc = circuit.QuantumCircuit(2)
qc.rzx(theta, 1, 0)

target = FakeHanoiV2().target

_pass = RZXCalibrationBuilder(target=target)
test_qc = PassManager(_pass).run(qc)

duration = self.compute_stretch_duration(self.u0p_play, theta)
with builder.build(
self.backend,
default_alignment="sequential",
default_transpiler_settings={"optimization_level": 0},
) as ref_sched:
# Hadamard gates
builder.call_gate(RZGate(np.pi / 2), qubits=(0,))
builder.call_gate(SXGate(), qubits=(0,))
builder.call_gate(RZGate(np.pi / 2), qubits=(0,))
builder.call_gate(RZGate(np.pi / 2), qubits=(1,))
builder.call_gate(SXGate(), qubits=(1,))
builder.call_gate(RZGate(np.pi / 2), qubits=(1,))
with builder.align_left():
# Positive CRs
u0p_params = self.u0p_play.pulse.parameters
u0p_params["duration"] = duration
u0p_params["width"] = self.compute_stretch_width(self.u0p_play, theta)
builder.play(
GaussianSquare(**u0p_params),
ControlChannel(0),
)
d1p_params = self.d1p_play.pulse.parameters
d1p_params["duration"] = duration
d1p_params["width"] = self.compute_stretch_width(self.d1p_play, theta)
builder.play(
GaussianSquare(**d1p_params),
DriveChannel(1),
)
builder.x(0)
with builder.align_left():
# Negative CRs
u0m_params = self.u0m_play.pulse.parameters
u0m_params["duration"] = duration
u0m_params["width"] = self.compute_stretch_width(self.u0m_play, theta)
builder.play(
GaussianSquare(**u0m_params),
ControlChannel(0),
)
d1m_params = self.d1m_play.pulse.parameters
d1m_params["duration"] = duration
d1m_params["width"] = self.compute_stretch_width(self.d1m_play, theta)
builder.play(
GaussianSquare(**d1m_params),
DriveChannel(1),
)
builder.x(0)
# Hadamard gates
builder.call_gate(RZGate(np.pi / 2), qubits=(0,))
builder.call_gate(SXGate(), qubits=(0,))
builder.call_gate(RZGate(np.pi / 2), qubits=(0,))
builder.call_gate(RZGate(np.pi / 2), qubits=(1,))
builder.call_gate(SXGate(), qubits=(1,))
builder.call_gate(RZGate(np.pi / 2), qubits=(1,))

self.assertEqual(schedule(test_qc, self.backend), target_qobj_transform(ref_sched))

def test_native_cr(self):
"""Test that correct pulse sequence is generated for native CR pair."""
# Sufficiently large angle to avoid minimum duration, i.e. amplitude rescaling
Expand Down