Skip to content

Commit

Permalink
Drop pulse support from MultiStateDiscrimination and some pulse tests
Browse files Browse the repository at this point in the history
  • Loading branch information
wshanks committed Feb 17, 2025
1 parent 9e059cc commit a15e668
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@
"""Multi state discrimination experiment."""

import warnings
from typing import Dict, List, Optional, Sequence
from typing import Any, Dict, List, Optional, Sequence

from qiskit import QuantumCircuit
from qiskit.circuit import Gate
from qiskit.providers import Backend
from qiskit.providers.options import Options
from qiskit.pulse import ScheduleBlock
from qiskit.qobj.utils import MeasLevel, MeasReturnType
from qiskit_experiments.framework import BaseExperiment
from qiskit_experiments.library.characterization import MultiStateDiscriminationAnalysis
Expand Down Expand Up @@ -112,7 +111,7 @@ def __init__(
physical_qubits: Sequence[int],
backend: Optional[Backend] = None,
n_states: Optional[int] = None,
schedules: Optional[Dict[str, ScheduleBlock]] = None,
schedules: Optional[Dict[str, Any]] = None,
):
"""Setup an experiment to prepare different energy states on a given qubit.
Expand All @@ -121,14 +120,15 @@ def __init__(
experiment.
backend: Optional, the backend to run the experiment on.
n_states: The number of energy levels to prepare.
schedules: The schedules of the x gates between neighboring energy levels.
schedules: Deprecated and unused
"""

super().__init__(
physical_qubits, analysis=MultiStateDiscriminationAnalysis(), backend=backend
)

self.experiment_options.schedules = schedules
if schedules:
warnings.warn("MultiStateDiscrimination no longer supports custom pulse schedules.")

if n_states is not None:
self.set_experiment_options(n_states=n_states)
Expand All @@ -140,14 +140,6 @@ def circuits(self) -> List[QuantumCircuit]:
Returns:
A list of circuits preparing the different energy states.
"""
warnings.warn(
(
"Setting pulse schedules for x gates is deprecated as of "
"version 0.8 due to the deprecation of Qiskit Pulse. It will be "
"removed in a future release."
),
DeprecationWarning,
)
circuits = []
for level in range(self.experiment_options.n_states):
circuit = QuantumCircuit(1)
Expand Down
40 changes: 0 additions & 40 deletions qiskit_experiments/test/mock_iq_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,46 +563,6 @@ def compute_probabilities(self, circuits: List[QuantumCircuit]) -> List[Dict[str
return output_dict_list


class MockIQRamseyXYHelper(MockIQExperimentHelper):
"""Functions needed for Ramsey XY experiment on mock IQ backend"""

def __init__(
self,
t2ramsey: float = 100e-6,
freq_shift: float = 0,
iq_cluster_centers: Optional[List[Tuple[IQPoint, IQPoint]]] = None,
iq_cluster_width: Optional[List[float]] = None,
):
super().__init__(iq_cluster_centers, iq_cluster_width)
self.t2ramsey = t2ramsey
self.freq_shift = freq_shift

def compute_probabilities(self, circuits: List[QuantumCircuit]) -> List[Dict[str, float]]:
"""Return the probability of being in the excited state."""
t2ramsey = self.t2ramsey
freq_shift = self.freq_shift
output_dict_list = []
for circuit in circuits:
probability_output_dict = {}
series = circuit.metadata["series"]
delay = circuit.metadata["xval"]

if series == "X":
phase_offset = 0.0
else:
phase_offset = np.pi / 2

probability_output_dict["1"] = (
0.5
* np.exp(-delay / t2ramsey)
* np.cos(2 * np.pi * delay * freq_shift - phase_offset)
+ 0.5
)
probability_output_dict["0"] = 1 - probability_output_dict["1"]
output_dict_list.append(probability_output_dict)
return output_dict_list


class MockIQReadoutAngleHelper(MockIQExperimentHelper):
"""Functions needed for Readout angle experiment on mock IQ backend"""

Expand Down
17 changes: 2 additions & 15 deletions test/library/characterization/test_half_angle.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
from test.base import QiskitExperimentsTestCase
import copy

from qiskit import pulse, transpile
from qiskit.pulse import InstructionScheduleMap
from qiskit import transpile
from qiskit_ibm_runtime.fake_provider import FakeAthensV2

from qiskit_experiments.test.mock_iq_backend import MockIQBackend
Expand Down Expand Up @@ -48,24 +47,12 @@ def test_circuits(self):

qubit = 1

inst_map = InstructionScheduleMap()
for inst in ["sx", "x"]:
inst_map.add(inst, (qubit,), pulse.Schedule(name=inst))

hac = HalfAngle([qubit])
hac.set_transpile_options(inst_map=inst_map)

# mimic what will happen in the experiment.
transpile_opts = copy.copy(hac.transpile_options.__dict__)
transpile_opts["initial_layout"] = list(hac._physical_qubits)
circuits = transpile(hac.circuits(), FakeAthensV2(), **transpile_opts)

for idx, circ in enumerate(circuits):
for idx, circ in enumerate(hac.circuits()):
self.assertEqual(circ.count_ops()["sx"], idx * 2 + 2)
self.assertEqual(circ.calibrations["sx"][((qubit,), ())], pulse.Schedule(name="sx"))
if idx > 0:
self.assertEqual(circ.count_ops()["x"], idx)
self.assertEqual(circ.calibrations["x"][((qubit,), ())], pulse.Schedule(name="x"))

def test_experiment_config(self):
"""Test converting to and from config works"""
Expand Down
26 changes: 5 additions & 21 deletions test/library/characterization/test_multi_state_discrimination.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@

from ddt import ddt, data

from qiskit import pulse
from qiskit.exceptions import MissingOptionalLibraryError

from qiskit_experiments.library import MultiStateDiscrimination
from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend
from qiskit_experiments.test.mock_iq_backend import MockMultiStateBackend

from qiskit_experiments.framework.package_deps import HAS_SKLEARN

Expand Down Expand Up @@ -49,33 +48,18 @@ def setUp(self):
"""Setup test variables."""
super().setUp()

self.backend = SingleTransmonTestBackend(noise=False, atol=1e-3)
self.backend = MockMultiStateBackend(iq_centers=[1, 1j, -1], rng_seed=1234)

# Build x12 schedule
self.qubit = 0

anharm = self.backend.anharmonicity

d0 = pulse.DriveChannel(self.qubit)

sch_map = self.backend.defaults().instruction_schedule_map
pulse_x = sch_map.get("x", (self.qubit,)).instructions[0][1].pulse
amp_x = pulse_x.amp
dur_x = pulse_x.duration
sigma_x = pulse_x.sigma
with pulse.build(name="x12") as x12:
pulse.shift_frequency(anharm, d0)
pulse.play(pulse.Gaussian(dur_x, amp_x * self.backend.rabi_rate_12, sigma_x), d0)
pulse.shift_frequency(-anharm, d0)

self.schedules = {"x12": x12}

@data(2, 3)
@requires_sklearn
def test_circuit_generation(self, n_states):
"""Test the experiment circuit generation"""
exp = MultiStateDiscrimination(
[self.qubit], n_states=n_states, backend=self.backend, schedules=self.schedules
[self.qubit], n_states=n_states, backend=self.backend
)
self.assertEqual(len(exp.circuits()), n_states)

Expand All @@ -87,7 +71,7 @@ def test_circuit_generation(self, n_states):
def test_discrimination_analysis(self, n_states):
"""Test the discrimination analysis"""
exp = MultiStateDiscrimination(
[self.qubit], n_states=n_states, backend=self.backend, schedules=self.schedules
[self.qubit], n_states=n_states, backend=self.backend
)

exp_data = exp.run()
Expand All @@ -105,6 +89,6 @@ def test_discrimination_analysis(self, n_states):
def test_circuit_roundtrip_serializable(self):
"""Test round trip JSON serialization for the experiment circuits."""
exp = MultiStateDiscrimination(
[self.qubit], n_states=3, backend=self.backend, schedules=self.schedules
[self.qubit], n_states=3, backend=self.backend
)
self.assertRoundTripSerializable(exp._transpiled_circuits())
24 changes: 0 additions & 24 deletions test/library/randomized_benchmarking/test_interleaved_rb.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from test.library.randomized_benchmarking.mixin import RBTestMixin
from ddt import ddt, data, unpack

from qiskit import pulse
from qiskit.circuit import Delay, QuantumCircuit, Parameter, Gate
from qiskit.circuit.library import SXGate, CXGate, TGate, CZGate
from qiskit.exceptions import QiskitError
Expand Down Expand Up @@ -282,29 +281,6 @@ def test_interleaving_cnot_gate_with_non_supported_direction(self):
with self.assertRaises(QiskitError):
exp.circuits()

def test_interleaving_three_qubit_gate_with_calibration(self):
"""Test if circuits for 3Q InterleavedRB contain custom calibrations supplied via target."""
with pulse.build(self.backend) as custom_3q_sched: # meaningless schedule
pulse.play(pulse.GaussianSquare(1600, 0.2, 64, 1300), pulse.drive_channel(0))

physical_qubits = (2, 1, 3)
custom_3q_gate = self.ThreeQubitGate()
self.backend.target.add_instruction(
custom_3q_gate, {physical_qubits: InstructionProperties(calibration=custom_3q_sched)}
)

exp = rb.InterleavedRB(
interleaved_element=custom_3q_gate,
physical_qubits=physical_qubits,
lengths=[3],
num_samples=1,
backend=self.backend,
seed=1234,
)
circuits = exp._transpiled_circuits()
qubits = tuple(circuits[0].qubits[q] for q in physical_qubits)
self.assertTrue(circuits[0].has_calibration_for((custom_3q_gate, qubits, [])))


class TestRunInterleavedRB(QiskitExperimentsTestCase, RBTestMixin):
"""Test for running InterleavedRB."""
Expand Down

0 comments on commit a15e668

Please sign in to comment.