Source code for qiskit_experiments.framework.backend_data
# This code is part of Qiskit.## (C) Copyright IBM 2021.## This code is licensed under the Apache License, Version 2.0. You may# obtain a copy of this license in the LICENSE.txt file in the root directory# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.## Any modifications or derivative works of this code must retain this# copyright notice, and modified files need to carry a notice indicating# that they have been altered from the originals."""Backend data access helper classSince `BackendV1` and `BackendV2` do not share the same interface, thisclass unifies data access for various data fields."""fromqiskit.providers.modelsimportPulseBackendConfigurationfromqiskit.providersimportBackendV1,BackendV2fromqiskit.providers.fake_providerimportFakeBackendfromqiskit.utils.deprecationimportdeprecate_functry:# Removed in Qiskit 1.0.fromqiskit.providers.fake_provider.fake_backendimportFakeBackendV2exceptImportError:classFakeBackendV2:"""Dummy class for when FakeBackendV2 import fails This class is only used in isinstance checks. If the import fails, then there won't be an instance of the class either so any dummy class is fine. """passtry:# Removed in Qiskit 1.0. Different from the other FakeBackendV2'sfromqiskit.providers.fake_providerimportQiskitFakeBackendV2exceptImportError:classQiskitFakeBackendV2:"""Dummy class for when FakeBackendV2 import fails This class is only used in isinstance checks. If the import fails, then there won't be an instance of the class either so any dummy class is fine. """passtry:# A copy of qiskit.providers.fake_provider.fake_backend.FakeBackendV2, at# least as of qiskit-ibm-runtime 0.18.0 and Qiskit 1.0fromqiskit_ibm_runtime.fake_provider.fake_backendimportFakeBackendV2asRuntimeFakeBackendV2exceptImportError:classRuntimeFakeBackendV2:"""Dummy class for when FakeBackendV2 import fails This class is only used in isinstance checks. If the import fails, then there won't be an instance of the class either so any dummy class is fine. """pass
[docs]classBackendData:"""Class for providing joint interface for accessing backend data"""def__init__(self,backend):"""Inits the backend and verifies version"""self._backend=backendself._v1=isinstance(backend,BackendV1)self._v2=isinstance(backend,BackendV2)ifself._v2:self._parse_additional_data()def_parse_additional_data(self):# data specific parsing not done yet in upstream qiskitifhasattr(self._backend,"_conf_dict")andself._backend._conf_dict["open_pulse"]:if"u_channel_lo"notinself._backend._conf_dict:self._backend._conf_dict["u_channel_lo"]=[]# to avoid qiskit bugself._pulse_conf=PulseBackendConfiguration.from_dict(self._backend._conf_dict)@propertydefname(self):"""Returns the backend name"""ifself._v1:returnself._backend.name()elifself._v2:returnself._backend.namereturnstr(self._backend)
[docs]defcontrol_channel(self,qubits):"""Returns the backend control channel for the given qubits"""try:ifself._v1:returnself._backend.configuration().control(qubits)elifself._v2:try:returnself._backend.control_channel(qubits)exceptNotImplementedError:returnself._pulse_conf.control(qubits)exceptAttributeError:return[]return[]
[docs]defdrive_channel(self,qubit):"""Returns the backend drive channel for the given qubit"""try:ifself._v1:returnself._backend.configuration().drive(qubit)elifself._v2:try:returnself._backend.drive_channel(qubit)exceptNotImplementedError:returnself._pulse_conf.drive(qubit)exceptAttributeError:returnNonereturnNone
[docs]defmeasure_channel(self,qubit):"""Returns the backend measure channel for the given qubit"""try:ifself._v1:returnself._backend.configuration().measure(qubit)elifself._v2:try:returnself._backend.measure_channel(qubit)exceptNotImplementedError:returnself._pulse_conf.measure(qubit)exceptAttributeError:returnNonereturnNone
[docs]defacquire_channel(self,qubit):"""Returns the backend acquire channel for the given qubit"""try:ifself._v1:returnself._backend.configuration().acquire(qubit)elifself._v2:try:returnself._backend.acquire_channel(qubit)exceptNotImplementedError:returnself._pulse_conf.acquire(qubit)exceptAttributeError:returnNonereturnNone
@propertydefgranularity(self):"""Returns the backend's time constraint granularity"""try:ifself._v1:returnself._backend.configuration().timing_constraints.get("granularity",1)elifself._v2:returnself._backend.target.granularityexceptAttributeError:return1return1@propertydefmin_length(self):"""Returns the backend's time constraint minimum duration"""try:ifself._v1:returnself._backend.configuration().timing_constraints.get("min_length",0)elifself._v2:returnself._backend.target.min_lengthexceptAttributeError:return0return0@propertydefpulse_alignment(self):"""Returns the backend's time constraint pulse alignment"""try:ifself._v1:returnself._backend.configuration().timing_constraints.get("pulse_alignment",1)elifself._v2:returnself._backend.target.pulse_alignmentexceptAttributeError:return1return1@propertydefacquire_alignment(self):"""Returns the backend's time constraint acquire alignment"""try:ifself._v1:returnself._backend.configuration().timing_constraints.get("acquire_alignment",1)elifself._v2:returnself._backend.target.acquire_alignmentexceptAttributeError:return1return1@propertydefdt(self):"""Returns the backend's input time resolution"""ifself._v1:try:returnself._backend.configuration().dtexceptAttributeError:returnNoneelifself._v2:returnself._backend.dtreturnNone@propertydefmax_circuits(self):"""Returns the backend's max experiments value"""ifself._v1:returngetattr(self._backend.configuration(),"max_experiments",None)elifself._v2:returnself._backend.max_circuitsreturnNone@propertydefcoupling_map(self):"""Returns the backend's coupling map"""ifself._v1:returngetattr(self._backend.configuration(),"coupling_map",[])elifself._v2:coupling_map=self._backend.coupling_mapifcoupling_mapisNone:returncoupling_mapreturnlist(coupling_map.get_edges())return[]@propertydefversion(self):"""Returns the backend's version"""ifself._v1:returngetattr(self._backend,"version",None)elifself._v2:returnself._backend.versionreturnNone@propertydefprovider(self):"""Returns the backend's provider"""try:ifself._v1:returnself._backend.provider()elifself._v2:returnself._backend.providerexceptAttributeError:returnNonereturnNone@propertydefdrive_freqs(self):"""Returns the backend's qubit drive frequencies"""ifself._v1:returngetattr(self._backend.defaults(),"qubit_freq_est",[])elifself._v2:ifself._backend.target.qubit_propertiesisNone:return[]return[property.frequencyforpropertyinself._backend.target.qubit_properties]return[]@propertydefmeas_freqs(self):"""Returns the backend's measurement stimulus frequencies. .. note:: The qiskit base classes do not provide this information as a standard backend property, but it is available from some providers in the data returned by the ``Backend.defaults()`` method. """ifnothasattr(self._backend,"defaults"):return[]returngetattr(self._backend.defaults(),"meas_freq_est",[])@propertydefnum_qubits(self):"""Returns the backend's number of qubits"""ifself._v1:returnself._backend.configuration().num_qubitselifself._v2:# meas_freq_est is currently not part of the BackendV2returnself._backend.num_qubitsreturnNone@property@deprecate_func(is_property=True,since="0.6",additional_msg=("is_simulator is deprecated because BackendV2 does not provide a ""standard way for checking this property. Calling code must ""determine if a backend uses a simulator from context."),package_name="qiskit-experiments",)# Note: remove all FakeBackend imports when removing this codedefis_simulator(self):"""Returns True given an indication the backend is a simulator .. note:: For `BackendV2` we sometimes cannot be sure, because it lacks a `simulator` field, as was present in `BackendV1`'s configuration. We still check whether the backend inherits `FakeBackendV2`, for either of its existing implementations in Qiskit. """ifself._v1:ifself._backend.configuration().simulatororisinstance(self._backend,FakeBackend):returnTrueifself._v2:ifisinstance(self._backend,(FakeBackendV2,QiskitFakeBackendV2,RuntimeFakeBackendV2)):returnTruereturnFalse
[docs]defqubit_t1(self,qubit:int)->float:"""Return the T1 value for a qubit from the backend properties Args: qubit: the qubit index to return T1 for Returns: The T1 value """ifself._v1:returnself._backend.properties().qubit_property(qubit)["T1"][0]ifself._v2:returnself._backend.qubit_properties(qubit).t1returnfloat("nan")