diff --git a/qiskit_ibm_provider/ibm_backend.py b/qiskit_ibm_provider/ibm_backend.py index e7055616e..87a5c3295 100644 --- a/qiskit_ibm_provider/ibm_backend.py +++ b/qiskit_ibm_provider/ibm_backend.py @@ -30,9 +30,7 @@ PulseBackendConfiguration, ) from qiskit.providers.options import Options -from qiskit.pulse import Schedule, LoConfig from qiskit.pulse.channels import ( - PulseChannel, AcquireChannel, ControlChannel, DriveChannel, @@ -332,9 +330,7 @@ def target_history(self, datetime: Optional[python_datetime] = None) -> Target: def run( self, - circuits: Union[ - QuantumCircuit, Schedule, str, List[Union[QuantumCircuit, Schedule, str]] - ], + circuits: Union[QuantumCircuit, str, List[Union[QuantumCircuit, str]]], dynamic: bool = None, job_tags: Optional[List[str]] = None, init_circuit: Optional[QuantumCircuit] = None, @@ -342,14 +338,6 @@ def run( header: Optional[Dict] = None, shots: Optional[Union[int, float]] = None, memory: Optional[bool] = None, - qubit_lo_freq: Optional[List[int]] = None, - meas_lo_freq: Optional[List[int]] = None, - schedule_los: Optional[ - Union[ - List[Union[Dict[PulseChannel, float], LoConfig]], - Union[Dict[PulseChannel, float], LoConfig], - ] - ] = None, meas_level: Optional[Union[int, MeasLevel]] = None, meas_return: Optional[Union[str, MeasReturnType]] = None, rep_delay: Optional[float] = None, @@ -366,10 +354,6 @@ def run( Args: circuits: An individual or a list of :class:`~qiskit.circuits.QuantumCircuit`. - :class:`~qiskit.pulse.Schedule` is no longer supported. Use ``pulse gates`` instead. - See `tutorial - `_ - on how to use pulse gates. dynamic: Whether the circuit is dynamic (uses in-circuit conditionals) job_tags: Tags to be assigned to the job. The tags can subsequently be used as a filter in the :meth:`jobs()` function call. @@ -389,11 +373,6 @@ def run( memory: If ``True``, per-shot measurement bitstrings are returned as well (provided the backend supports it). For OpenPulse jobs, only measurement level 2 supports this option. - qubit_lo_freq: List of default qubit LO frequencies in Hz. Will be overridden by - ``schedule_los`` if set. - meas_lo_freq: List of default measurement LO frequencies in Hz. Will be overridden - by ``schedule_los`` if set. - schedule_los: Experiment LO configurations, frequencies are given in Hz. meas_level: Level of the measurement output for pulse experiments. See `OpenPulse specification `_ for details: @@ -498,9 +477,6 @@ def run( header=header, shots=shots, memory=memory, - qubit_lo_freq=qubit_lo_freq, - meas_lo_freq=meas_lo_freq, - schedule_los=schedule_los, meas_level=meas_level, meas_return=meas_return, rep_delay=rep_delay, @@ -769,17 +745,16 @@ def __repr__(self) -> str: return "<{}('{}')>".format(self.__class__.__name__, self.name) def _deprecate_id_instruction( - self, circuits: List[Union[QuantumCircuit, Schedule]] - ) -> List[Union[QuantumCircuit, Schedule]]: + self, circuits: List[QuantumCircuit] + ) -> List[QuantumCircuit]: """Raise a DeprecationWarning if any circuit contains an 'id' instruction. Additionally, if 'delay' is a 'supported_instruction', replace each 'id' instruction (in-place) with the equivalent ('sx'-length) 'delay' instruction. Args: - circuits: The individual or list of :class:`~qiskit.circuits.QuantumCircuit` or - :class:`~qiskit.pulse.Schedule` objects passed to - :meth:`IBMBackend.run()`. Modified in-place. + circuits: The individual or list of :class:`~qiskit.circuits.QuantumCircuit` + passed to :meth:`IBMBackend.run()`. Modified in-place. Returns: A modified copy of the original circuit where 'id' instructions are replaced with @@ -844,22 +819,14 @@ def _check_circuits_attributes(self, circuits: List[QuantumCircuit]) -> None: """Check that circuits can be executed on backend. Raises: IBMBackendValueError: - - If Schedule is given as an input circuit. - If one of the circuits contains more qubits than on the backend.""" - schedule_error_msg = ( - "Class 'Schedule' is no longer supported as an input circuit. " - "Use 'pulse gates' instead. See `tutorial " - "https://qiskit.org/documentation/tutorials/circuits_advanced/05_pulse_gates.html` " - "on how to use pulse gates." - ) + if len(circuits) > self._max_circuits: raise IBMBackendValueError( f"Number of circuits, {len(circuits)} exceeds the " f"maximum for this backend, {self._max_circuits})" ) for circ in circuits: - if isinstance(circ, Schedule): - raise IBMBackendValueError(schedule_error_msg) if isinstance(circ, QuantumCircuit): if circ.num_qubits > self._configuration.num_qubits: raise IBMBackendValueError( diff --git a/qiskit_ibm_provider/job/ibm_circuit_job.py b/qiskit_ibm_provider/job/ibm_circuit_job.py index 0a7b2d63c..483b08a5c 100644 --- a/qiskit_ibm_provider/job/ibm_circuit_job.py +++ b/qiskit_ibm_provider/job/ibm_circuit_job.py @@ -18,7 +18,7 @@ import queue from concurrent import futures from datetime import datetime -from typing import Dict, Optional, Any, List, Union +from typing import Dict, Optional, Any, List import re import requests @@ -27,7 +27,6 @@ from qiskit.circuit.quantumcircuit import QuantumCircuit from qiskit.result import Result -from qiskit.pulse import Schedule from qiskit_ibm_provider import ibm_backend # pylint: disable=unused-import from .constants import IBM_COMPOSITE_JOB_TAG_PREFIX, IBM_MANAGED_JOB_ID_PREFIX @@ -611,11 +610,11 @@ def header(self) -> Dict: return self._params.get("header") return {} - def circuits(self) -> List[Union[QuantumCircuit, Schedule]]: - """Return the circuits or pulse schedules for this job. + def circuits(self) -> List[QuantumCircuit]: + """Return the circuits for this job. Returns: - The circuits or pulse schedules for this job. An empty list + The circuits or for this job. An empty list is returned if the circuits cannot be retrieved (for example, if the job uses an old format that is no longer supported). """ diff --git a/qiskit_ibm_provider/job/ibm_composite_job.py b/qiskit_ibm_provider/job/ibm_composite_job.py index 0f5e96da0..8eb305f8b 100644 --- a/qiskit_ibm_provider/job/ibm_composite_job.py +++ b/qiskit_ibm_provider/job/ibm_composite_job.py @@ -30,7 +30,6 @@ from qiskit.compiler import assemble from qiskit.providers.jobstatus import JOB_FINAL_STATES, JobStatus from qiskit.providers.models import BackendProperties -from qiskit.pulse import Schedule from qiskit.qobj import QasmQobj, PulseQobj from qiskit.result import Result from qiskit.result.models import ExperimentResult @@ -125,9 +124,7 @@ def __init__( job_id: Optional[str] = None, creation_date: Optional[datetime] = None, jobs: Optional[List[IBMCircuitJob]] = None, - circuits_list: Optional[ - List[Union[List[QuantumCircuit], List[Schedule]]] - ] = None, + circuits_list: Optional[List[List[QuantumCircuit]]] = None, run_config: Optional[Dict] = None, name: Optional[str] = None, tags: Optional[List[str]] = None, @@ -259,7 +256,7 @@ def from_jobs( def _submit_circuits( self, - circuit_lists: List[Union[List[QuantumCircuit], List[Schedule]]], + circuit_lists: List[List[QuantumCircuit]], run_config: Dict, ) -> None: """Assemble and submit circuits. @@ -873,11 +870,11 @@ def refresh(self) -> None: if job.status() not in JOB_FINAL_STATES: job.refresh() - def circuits(self) -> List[Union[QuantumCircuit, Schedule]]: - """Return the circuits or pulse schedules for this job. + def circuits(self) -> List[QuantumCircuit]: + """Return the circuits for this job. Returns: - The circuits or pulse schedules for this job. + The circuits for this job. """ if not self._circuits: qobj = self._get_qobj() diff --git a/qiskit_ibm_provider/job/ibm_job.py b/qiskit_ibm_provider/job/ibm_job.py index 8019be4ab..82c13f25f 100644 --- a/qiskit_ibm_provider/job/ibm_job.py +++ b/qiskit_ibm_provider/job/ibm_job.py @@ -20,7 +20,6 @@ from qiskit.circuit.quantumcircuit import QuantumCircuit from qiskit.providers.job import JobV1 as Job from qiskit.providers.models import BackendProperties -from qiskit.pulse import Schedule from qiskit.qobj import QasmQobj, PulseQobj from qiskit.result import Result @@ -198,11 +197,11 @@ def refresh(self) -> None: """Obtain the latest job information from the server.""" pass - def circuits(self) -> List[Union[QuantumCircuit, Schedule]]: - """Return the circuits or pulse schedules for this job. + def circuits(self) -> List[QuantumCircuit]: + """Return the circuits for this job. Returns: - The circuits or pulse schedules for this job. An empty list + The circuits for this job. An empty list is returned if the circuits cannot be retrieved (for example, if the job uses an old format that is no longer supported). """ diff --git a/qiskit_ibm_provider/utils/options.py b/qiskit_ibm_provider/utils/options.py index 9162dfb80..34874dfdb 100644 --- a/qiskit_ibm_provider/utils/options.py +++ b/qiskit_ibm_provider/utils/options.py @@ -13,10 +13,8 @@ """Backend run options.""" from dataclasses import asdict, dataclass -from typing import Dict, List, Union, Any, Optional +from typing import Dict, Union, Any, Optional from qiskit.circuit import QuantumCircuit -from qiskit.pulse import LoConfig -from qiskit.pulse.channels import PulseChannel from qiskit.qobj.utils import MeasLevel, MeasReturnType @@ -53,14 +51,6 @@ class QASM2Options(CommonOptions): """Options for the QASM2 path.""" header: Optional[Dict] = None - qubit_lo_freq: Optional[List[int]] = None - meas_lo_freq: Optional[List[int]] = None - schedule_los: Optional[ - Union[ - List[Union[Dict[PulseChannel, float], LoConfig]], - Union[Dict[PulseChannel, float], LoConfig], - ] - ] = None init_qubits: bool = True use_measure_esp: Optional[bool] = None # Simulator only diff --git a/test/integration/test_backend.py b/test/integration/test_backend.py index 38cc4895b..e809033ab 100644 --- a/test/integration/test_backend.py +++ b/test/integration/test_backend.py @@ -12,14 +12,13 @@ """IBMBackend Test.""" -from unittest import SkipTest, mock, skip +from unittest import mock, skip from unittest.mock import patch from qiskit import QuantumCircuit, transpile from qiskit.providers.models import QasmBackendConfiguration from qiskit.providers.exceptions import QiskitBackendNotFoundError from qiskit.test.reference_circuits import ReferenceCircuits -from qiskit.pulse import Schedule from qiskit_ibm_provider import IBMBackend, IBMProvider, least_busy from qiskit_ibm_provider.ibm_qubit_properties import IBMQubitProperties @@ -31,7 +30,6 @@ production_only, ) from ..ibm_test_case import IBMTestCase -from ..utils import get_pulse_schedule, cancel_job class TestIBMBackend(IBMTestCase): @@ -87,33 +85,6 @@ def test_backend_pulse_defaults(self): if backend.configuration().open_pulse: self.assertIsNotNone(defaults) - @skip("See Terra issue #9488") - def test_backend_options(self): - """Test backend options.""" - provider: IBMProvider = self.backend.provider - backends = provider.backends( - open_pulse=True, - operational=True, - instance=self.dependencies.instance, - ) - if not backends: - raise SkipTest("Skipping pulse test since no pulse backend found.") - - backend = backends[0] - backend.options.shots = 2048 - backend.set_options( - qubit_lo_freq=[4.9e9, 5.0e9], meas_lo_freq=[6.5e9, 6.6e9], meas_level=2 - ) - job = backend.run(get_pulse_schedule(backend), meas_level=1, foo="foo") - backend_options = provider.backend.retrieve_job(job.job_id()).backend_options() - self.assertEqual(backend_options["shots"], 2048) - # Qobj config freq is in GHz. - self.assertAlmostEqual(backend_options["qubit_lo_freq"], [4.9e9, 5.0e9]) - self.assertEqual(backend_options["meas_lo_freq"], [6.5e9, 6.6e9]) - self.assertEqual(backend_options["meas_level"], 1) - self.assertEqual(backend_options["foo"], "foo") - cancel_job(job) - def test_sim_backend_options(self): """Test simulator backend options.""" provider: IBMProvider = self.backend.provider @@ -201,18 +172,6 @@ def test_retrieve_backend_not_exist(self): with self.assertRaises(QiskitBackendNotFoundError): self.dependencies.provider.get_backend("nonexistent_backend") - def test_schedule_error_message(self): - """Test that passing a Schedule as input to Backend.run() raises an error.""" - backend = self.dependencies.provider.get_backend("ibmq_qasm_simulator") - schedule = Schedule() - for circuit in [schedule, [schedule]]: - with self.assertRaises(IBMBackendValueError) as err: - backend.run(circuit) - self.assertIn( - "Class 'Schedule' is no longer supported as an input circuit", - str(err.exception), - ) - def test_too_many_qubits_in_circuit(self): """Check error message if circuit contains more qubits than supported on the backend.""" backends = self.dependencies.provider.backends(