diff --git a/qiskit/providers/__init__.py b/qiskit/providers/__init__.py index 7b1ef8527049..88ba2a7787e5 100644 --- a/qiskit/providers/__init__.py +++ b/qiskit/providers/__init__.py @@ -64,9 +64,9 @@ deprecation is to give providers enough time to do their own deprecation of a potential end user impacting change in a user facing part of the interface prior to bumping their version. For example, let's say we changed the signature -to ``Backend.run()`` in ``BackendV34`` in a backwards incompatible way, before -Aer could update its :class:`~qiskit.providers.aer.aerbackend.AerBackend` class -to use version 34 they'd need to deprecate the old signature prior to switching +to ``Backend.run()`` in ``BackendV34`` in a backwards incompatible way. Before +Aer could update its :class:`~qiskit_aer.AerSimulator` class +to be based on version 34 they'd need to deprecate the old signature prior to switching over. The changeover for Aer is not guaranteed to be lockstep with Terra so we need to ensure there is a sufficient amount of time for Aer to complete its deprecation cycle prior to removing version 33 (ie making version 34 @@ -734,13 +734,13 @@ def status(self): - * - ``backend.properties().readout_error(0)`` - ``backend.target["measure"][(0,)].error`` - - In :obj:`~BackendV2` the error rate for the :class:`~qiskit.circuit.Measure` + - In :obj:`~BackendV2` the error rate for the :class:`~qiskit.circuit.library.Measure` operation on a given qubit is used to model the readout error. However a :obj:`~BackendV2` can implement multiple measurement types and list them separately in a :class:`~qiskit.transpiler.Target`. * - ``backend.properties().readout_length(0)`` - ``backend.target["measure"][(0,)].duration`` - - In :obj:`~BackendV2` the duration for the :class:`~qiskit.circuit.Measure` + - In :obj:`~BackendV2` the duration for the :class:`~qiskit.circuit.library.Measure` operation on a given qubit is used to model the readout length. However, a :obj:`~BackendV2` can implement multiple measurement types and list them separately in a :class:`~qiskit.transpiler.Target`. diff --git a/qiskit/providers/backend.py b/qiskit/providers/backend.py index d570bfd4db60..5ff10b5f7f74 100644 --- a/qiskit/providers/backend.py +++ b/qiskit/providers/backend.py @@ -62,6 +62,11 @@ class BackendV1(Backend, ABC): ease the transition for users and provider maintainers to the new versioned providers. Expect, future versions of this abstract class to change the data model and interface. + + Subclasses of this should override the public method :meth:`run` and the internal + :meth:`_default_options`: + + .. automethod:: _default_options """ version = 1 @@ -113,7 +118,6 @@ def _default_options(cls): qiskit.providers.Options: A options object with default values set """ - pass def set_options(self, **fields): """Set the options fields for the backend @@ -217,7 +221,7 @@ class can handle either situation. Args: run_input (QuantumCircuit or Schedule or list): An individual or a - list of :class:`~qiskit.circuits.QuantumCircuit` or + list of :class:`~qiskit.circuit.QuantumCircuit` or :class:`~qiskit.pulse.Schedule` objects to run on the backend. For legacy providers migrating to the new versioned providers, provider interface a :class:`~qiskit.qobj.QasmQobj` or @@ -251,7 +255,7 @@ class QubitProperties: __slots__ = ("t1", "t2", "frequency") def __init__(self, t1=None, t2=None, frequency=None): - """Create a new ``QubitProperties`` object + """Create a new :class:`QubitProperties` object. Args: t1: The T1 time for a qubit in seconds @@ -282,8 +286,8 @@ class BackendV2(Backend, ABC): something like a ``shots`` field for a backend that runs experiments which would contain an int for how many shots to execute. - If migrating a provider from :class:`~qiskit.providers.BackendV1` or - :class:`~qiskit.providers.BaseBackend` one thing to keep in mind is for + If migrating a provider from :class:`~qiskit.providers.BackendV1` + one thing to keep in mind is for backwards compatibility you might need to add a configuration method that will build a :class:`~qiskit.providers.models.BackendConfiguration` object and :class:`~qiskit.providers.models.BackendProperties` from the attributes @@ -308,6 +312,11 @@ class BackendV2(Backend, ABC): that contains the custom compilation passes and then for the hook methods on the backend object to return the plugin name so that :func:`~.transpile` will use it by default when targetting the backend. + + Subclasses of this should override the public method :meth:`run` and the internal + :meth:`_default_options`: + + .. automethod:: _default_options """ version = 2 @@ -352,9 +361,15 @@ def __init__( raise AttributeError("Options field %s is not valid for this backend" % field) self._options.update_config(**fields) self.name = name + """Name of the backend.""" self.description = description + """Optional human-readable description.""" self.online_date = online_date + """Date that the backend came online.""" self.backend_version = backend_version + """Version of the backend being provided. This is not the same as + :attr:`.BackendV2.version`, which is the version of the :class:`~.providers.Backend` + abstract interface.""" self._coupling_map = None @property @@ -432,8 +447,8 @@ def dt(self) -> Union[float, None]: scheduling. Returns: - dt: The input signal timestep in seconds. If the backend doesn't - define ``dt`` ``None`` will be returned + The input signal timestep in seconds. If the backend doesn't define ``dt``, ``None`` will + be returned. """ return self.target.dt @@ -442,7 +457,7 @@ def dtm(self) -> float: """Return the system time resolution of output signals Returns: - dtm: The output signal timestep in seconds. + The output signal timestep in seconds. Raises: NotImplementedError: if the backend doesn't support querying the @@ -458,7 +473,7 @@ def meas_map(self) -> List[List[int]]: scheduling. Returns: - meas_map: The grouping of measurements which are multiplexed + The grouping of measurements which are multiplexed Raises: NotImplementedError: if the backend doesn't support querying the @@ -482,12 +497,12 @@ def qubit_properties( Args: qubit: The qubit to get the - :class:`~qiskit.provider.QubitProperties` object for. This can + :class:`.QubitProperties` object for. This can be a single integer for 1 qubit or a list of qubits and a list - of :class:`~qiskit.provider.QubitProperties` objects will be + of :class:`.QubitProperties` objects will be returned in the same order Returns: - qubit_properties: The :class:`~.QubitProperties` object for the + The :class:`~.QubitProperties` object for the specified qubit. If a list of qubits is provided a list will be returned. If properties are missing for a qubit this can be ``None``. @@ -623,15 +638,15 @@ class can handle either situation. Args: run_input (QuantumCircuit or Schedule or ScheduleBlock or list): An - individual or a list of - :class:`~qiskit.circuits.QuantumCircuit, - :class:`~qiskit.pulse.ScheduleBlock`, or - :class:`~qiskit.pulse.Schedule` objects to run on the backend. + individual or a list of :class:`.QuantumCircuit`, + :class:`~qiskit.pulse.ScheduleBlock`, or :class:`~qiskit.pulse.Schedule` objects to + run on the backend. options: Any kwarg options to pass to the backend for running the config. If a key is also present in the options attribute/object then the expectation is that the value specified will be used instead of what's set in the options object. + Returns: Job: The job object for the run """ diff --git a/qiskit/providers/basicaer/basicaerjob.py b/qiskit/providers/basicaer/basicaerjob.py index 0a71d7feb7b4..99c2f45bf86d 100644 --- a/qiskit/providers/basicaer/basicaerjob.py +++ b/qiskit/providers/basicaer/basicaerjob.py @@ -40,7 +40,7 @@ def result(self, timeout=None): """Get job result . Returns: - qiskit.Result: Result object + qiskit.result.Result: Result object """ if timeout is not None: warnings.warn( diff --git a/qiskit/providers/basicaer/qasm_simulator.py b/qiskit/providers/basicaer/qasm_simulator.py index f6557866dec6..fd5027e13cd7 100644 --- a/qiskit/providers/basicaer/qasm_simulator.py +++ b/qiskit/providers/basicaer/qasm_simulator.py @@ -336,7 +336,7 @@ def _validate_measure_sampling(self, experiment): """Determine if measure sampling is allowed for an experiment Args: - experiment (QobjExperiment): a qobj experiment. + experiment (QasmQobjExperiment): a qobj experiment. """ # If shots=1 we should disable measure sampling. # This is also required for statevector simulator to return the @@ -461,7 +461,7 @@ def run_experiment(self, experiment): """Run an experiment (circuit) and return a single experiment result. Args: - experiment (QobjExperiment): experiment from qobj experiments list + experiment (QasmQobjExperiment): experiment from qobj experiments list Returns: dict: A result dictionary which looks something like:: diff --git a/qiskit/providers/basicaer/unitary_simulator.py b/qiskit/providers/basicaer/unitary_simulator.py index e92d55730ed0..16b1f69f09ce 100644 --- a/qiskit/providers/basicaer/unitary_simulator.py +++ b/qiskit/providers/basicaer/unitary_simulator.py @@ -292,7 +292,7 @@ def run_experiment(self, experiment): """Run an experiment (circuit) and return a single experiment result. Args: - experiment (QobjExperiment): experiment from qobj experiments list + experiment (QasmQobjExperiment): experiment from qobj experiments list Returns: dict: A result dictionary which looks something like:: @@ -312,8 +312,8 @@ def run_experiment(self, experiment): } Raises: - BasicAerError: if the number of qubits in the circuit is greater than 24. - Note that the practical qubit limit is much lower than 24. + BasicAerError: if the number of qubits in the circuit is greater than 24. Note that the + practical qubit limit is much lower than 24. """ start = time.time() self._number_of_qubits = experiment.header.n_qubits diff --git a/qiskit/providers/fake_provider/__init__.py b/qiskit/providers/fake_provider/__init__.py index ed099fdd24c7..943869114f85 100644 --- a/qiskit/providers/fake_provider/__init__.py +++ b/qiskit/providers/fake_provider/__init__.py @@ -99,7 +99,8 @@ ---------------- Fake V2 backends are fake backends with IBM Quantum systems snapshots implemented with -:mod:`~qiskit.providers.backend.BackendV2` interface. +:mod:`~qiskit.providers.backend.BackendV2` interface. They are all subclasses of +:class:`FakeBackendV2`. .. autosummary:: :toctree: ../stubs/ @@ -224,6 +225,18 @@ FakeMumbaiFractionalCX ConfigurableFakeBackend +Fake Backend Base Classes +========================= + +The fake backends based on IBM hardware are based on a set of base classes: + +.. currentmodule:: qiskit.providers.fake_provider.fake_backend +.. autoclass:: qiskit.providers.fake_provider.fake_backend.FakeBackendV2 + +.. currentmodule:: qiskit.providers.fake_provider +.. autoclass:: FakeBackend +.. autoclass:: FakeQasmBackend +.. autoclass:: FakePulseBackend """ # Fake job and qobj classes @@ -231,6 +244,7 @@ from .fake_qobj import FakeQobj # Base classes for fake backends +from . import fake_backend from .fake_backend import FakeBackend from .fake_qasm_backend import FakeQasmBackend from .fake_pulse_backend import FakePulseBackend diff --git a/qiskit/providers/fake_provider/fake_backend.py b/qiskit/providers/fake_provider/fake_backend.py index 923196f58b9f..e1740368884c 100644 --- a/qiskit/providers/fake_provider/fake_backend.py +++ b/qiskit/providers/fake_provider/fake_backend.py @@ -211,7 +211,7 @@ def dtm(self) -> float: """Return the system time resolution of output signals Returns: - dtm: The output signal timestep in seconds. + The output signal timestep in seconds. """ dtm = self._conf_dict.get("dtm") if dtm is not None: @@ -227,7 +227,7 @@ def meas_map(self) -> List[List[int]]: scheduling. Returns: - meas_map: The grouping of measurements which are multiplexed + The grouping of measurements which are multiplexed """ return self._conf_dict.get("meas_map") @@ -316,7 +316,7 @@ def run(self, run_input, **options): Args: run_input (QuantumCircuit or Schedule or ScheduleBlock or list): An individual or a list of - :class:`~qiskit.circuits.QuantumCircuit, + :class:`~qiskit.circuit.QuantumCircuit`, :class:`~qiskit.pulse.ScheduleBlock`, or :class:`~qiskit.pulse.Schedule` objects to run on the backend. options: Any kwarg options to pass to the backend for running the @@ -324,11 +324,12 @@ def run(self, run_input, **options): attribute/object then the expectation is that the value specified will be used instead of what's set in the options object. + Returns: Job: The job object for the run + Raises: - QiskitError: If a pulse job is supplied and qiskit-aer is not - installed. + QiskitError: If a pulse job is supplied and qiskit-aer is not installed. """ circuits = run_input pulse_job = None diff --git a/qiskit/providers/models/__init__.py b/qiskit/providers/models/__init__.py index 37485b2b5002..a69038eb78c7 100644 --- a/qiskit/providers/models/__init__.py +++ b/qiskit/providers/models/__init__.py @@ -35,6 +35,8 @@ PulseDefaults Command JobStatus + GateProperties + Nduv """ from .backendconfiguration import ( @@ -44,7 +46,7 @@ UchannelLO, GateConfig, ) -from .backendproperties import BackendProperties +from .backendproperties import BackendProperties, GateProperties, Nduv from .backendstatus import BackendStatus from .jobstatus import JobStatus from .pulsedefaults import PulseDefaults, Command diff --git a/qiskit/providers/models/backendconfiguration.py b/qiskit/providers/models/backendconfiguration.py index e4c849728af4..75ee19c1eb35 100644 --- a/qiskit/providers/models/backendconfiguration.py +++ b/qiskit/providers/models/backendconfiguration.py @@ -285,7 +285,7 @@ def __init__( backend is a simulator credits_required (bool): True if backend requires credits to run a job. - online_date (datetime): The date that the device went online + online_date (datetime.datetime): The date that the device went online display_name (str): Alternate name field for the backend description (str): A description for the backend tags (list): A list of string tags to describe the backend @@ -593,7 +593,7 @@ def __init__( backend is a simulator credits_required (bool): True if backend requires credits to run a job. - online_date (datetime): The date that the device went online + online_date (datetime.datetime): The date that the device went online display_name (str): Alternate name field for the backend description (str): A description for the backend tags (list): A list of string tags to describe the backend diff --git a/qiskit/providers/models/backendproperties.py b/qiskit/providers/models/backendproperties.py index 9ebc9c3d3e93..1f5a190bd5de 100644 --- a/qiskit/providers/models/backendproperties.py +++ b/qiskit/providers/models/backendproperties.py @@ -35,7 +35,7 @@ def __init__(self, date, name, unit, value): """Initialize a new name-date-unit-value object Args: - date (datetime): Date field + date (datetime.datetime): Date field name (str): Name field unit (str): Nduv unit value (float): The value of the Nduv @@ -83,19 +83,19 @@ def __repr__(self): return f"Nduv({repr(self.date)}, {self.name}, {self.unit}, {self.value})" -class Gate: +class GateProperties: """Class representing a gate's properties Attributes: - qubits: qubits. - gate: gate. - parameters: parameters. + qubits: qubits. + gate: gate. + parameters: parameters. """ _data = {} def __init__(self, qubits, gate, parameters, **kwargs): - """Initialize a new Gate object + """Initialize a new :class:`GateProperties` object Args: qubits (list): A list of integers representing qubits @@ -126,7 +126,7 @@ def from_dict(cls, data): :func:`to_dict`. Returns: - Gate: The Nduv from the input dictionary. + GateProperties: The Nduv from the input dictionary. """ in_data = {} for key, value in data.items(): @@ -150,12 +150,16 @@ def to_dict(self): return out_dict def __eq__(self, other): - if isinstance(other, Gate): + if isinstance(other, GateProperties): if self.to_dict() == other.to_dict(): return True return False +# Backwards compatibility. +Gate = GateProperties + + class BackendProperties: """Class representing backend properties @@ -174,11 +178,11 @@ def __init__( Args: backend_name (str): Backend name. backend_version (str): Backend version in the form X.Y.Z. - last_update_date (datetime or str): Last date/time that a property was + last_update_date (datetime.datetime or str): Last date/time that a property was updated. If specified as a ``str``, it must be in ISO format. qubits (list): System qubit parameters as a list of lists of :class:`Nduv` objects - gates (list): System gate parameters as a list of :class:`Gate` + gates (list): System gate parameters as a list of :class:`GateProperties` objects general (list): General parameters as a list of :class:`Nduv` objects @@ -224,13 +228,11 @@ def from_dict(cls, data): """Create a new BackendProperties object from a dictionary. Args: - data (dict): A dictionary representing the BackendProperties to create. - It will be in the same format as output by - :func:`to_dict`. + data (dict): A dictionary representing the BackendProperties to create. It will be in + the same format as output by :meth:`to_dict`. Returns: - BackendProperties: The BackendProperties from the input - dictionary. + BackendProperties: The BackendProperties from the input dictionary. """ in_data = copy.copy(data) backend_name = in_data.pop("backend_name") @@ -242,7 +244,7 @@ def from_dict(cls, data): for nduv in qubit: nduvs.append(Nduv.from_dict(nduv)) qubits.append(nduvs) - gates = [Gate.from_dict(x) for x in in_data.pop("gates")] + gates = [GateProperties.from_dict(x) for x in in_data.pop("gates")] general = [Nduv.from_dict(x) for x in in_data.pop("general")] return cls( backend_name, backend_version, last_update_date, qubits, gates, general, **in_data diff --git a/qiskit/providers/models/jobstatus.py b/qiskit/providers/models/jobstatus.py index 4a52f0db56a5..2fc58e437ab9 100644 --- a/qiskit/providers/models/jobstatus.py +++ b/qiskit/providers/models/jobstatus.py @@ -41,8 +41,7 @@ def from_dict(cls, data): :meth:`to_dict`. Returns: - qiskit.providers.model.JobStatus: The ``JobStatus`` from the input - dictionary. + JobStatus: The ``JobStatus`` from the input dictionary. """ return cls(**data) diff --git a/qiskit/providers/models/pulsedefaults.py b/qiskit/providers/models/pulsedefaults.py index 2ee1594571e1..13becb1c956d 100644 --- a/qiskit/providers/models/pulsedefaults.py +++ b/qiskit/providers/models/pulsedefaults.py @@ -147,8 +147,7 @@ def from_dict(cls, data): :meth:`to_dict`. Returns: - qiskit.providers.model.Command: The ``Command`` from the input - dictionary. + Command: The ``Command`` from the input dictionary. """ # Pulse command data is nested dictionary. # To avoid deepcopy and avoid mutating the source object, create new dict here.