Source code for qiskit_aws_braket_provider.conversions_properties

# Copyright 2020 Carsten Blank
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from datetime import datetime
from typing import List, Dict

import pint
import qiskit
from braket.device_schema import DeviceCapabilities
from braket.device_schema.ionq import IonqDeviceCapabilities
from braket.device_schema.rigetti import RigettiDeviceCapabilities
from braket.device_schema.simulators import GateModelSimulatorDeviceCapabilities
from qiskit.providers import BaseBackend
from qiskit.providers.models import QasmBackendConfiguration, BackendProperties
from qiskit.providers.models.backendproperties import Nduv

logger = logging.getLogger(__name__)
units = pint.UnitRegistry()


# noinspection PyTypeChecker
[docs]def aws_ionq_to_properties(properties: IonqDeviceCapabilities, configuration: QasmBackendConfiguration) -> BackendProperties: updated_time: datetime = properties.service.updatedAt or datetime.now() general: List[Nduv] = [] qubits: List[List[Nduv]] = [] gates: List[qiskit.providers.models.backendproperties.Gate] = [] # FIXME: qiskit has an absolutely rediculous unit conversion mechanism, # see qiskit.providers.models.backendproperties.BackendProperties._apply_prefix, # which means that since we have seconds (s) we need to convert them to milli-seconds otherwise we get a # BackendPropertyError raised. # per qubit: T1, T2, frequency, anharmonicity, readout_error, prob_meas0_prep1, prob_meas1_prep0 # (if possible) qubits = [ [ Nduv(date=updated_time, name='T1', unit='ms', value=(properties.provider.timing.get('T1') * units.seconds).m_as(units.milliseconds)), Nduv(date=updated_time, name='T2', unit='ms', value=(properties.provider.timing.get('T2') * units.seconds).m_as(units.milliseconds)) ] for _ in range(configuration.n_qubits) ] # use native gates and all qubits possibilities: set gate_error and gate_length as parameters (Nduv) def get_fidelities(qubits): return properties.provider.fidelity.get('1Q' if len(qubits) == 1 else '2Q', {'mean': None}) \ .get('mean') def get_timings(qubits): return properties.provider.timing.get('1Q' if len(qubits) == 1 else '2Q') gates = [ qiskit.providers.models.backendproperties.Gate( gate=b.name, qubits=qubits, parameters=[ Nduv(date=updated_time, name='gate_error', unit='', value=1 - get_fidelities(qubits)), Nduv(date=updated_time, name='gate_length', unit='ms', value=(get_timings(qubits) * units.seconds).m_as(units.milliseconds)) ]) for b in configuration.gates for qubits in b.coupling_map ] # General Measurements maybe of interest / any other interesting measurement (like cross-talk) general = [ Nduv(date=updated_time, name='spam_fidelity', unit='', value=properties.provider.fidelity.get('spam', {'mean': None}).get('mean')), Nduv(date=updated_time, name='readout_time', unit='ms', value=(properties.provider.timing.get('readout') * units.seconds).m_as(units.milliseconds)), Nduv(date=updated_time, name='reset_time', unit='ms', value=(properties.provider.timing.get('reset') * units.seconds).m_as(units.milliseconds)) ] backend_properties: BackendProperties = BackendProperties( backend_name=configuration.backend_name, backend_version=configuration.backend_version, last_update_date=updated_time, qubits=qubits, gates=gates, general=general ) return backend_properties
# noinspection PyTypeChecker
[docs]def aws_rigetti_to_properties(properties: RigettiDeviceCapabilities, configuration: QasmBackendConfiguration) -> BackendProperties: updated_time: datetime = properties.service.updatedAt or datetime.now() general: List[Nduv] = [] qubits: Dict[str, List[Nduv]] = {} gates: List[qiskit.providers.models.backendproperties.Gate] = [] specs: Dict[str, Dict[str, Dict[str, float]]] = properties.provider.specs # TODO: check units!! # per qubit: T1, T2, frequency, anharmonicity, readout_error, prob_meas0_prep1, prob_meas1_prep0 # (if possible) one_qubit_specs: Dict[str, Dict[str, float]] = specs['1Q'] two_qubit_specs: Dict[str, Dict[str, float]] = specs['2Q'] qubits_dict = dict([ (q, [ # The default cannot be 0.0 exactly... TODO: find out what a good default value could be Nduv(date=updated_time, name='T1', unit='ms', value=(q_specs.get('T1', 1e-9) * units.seconds).m_as(units.milliseconds)), Nduv(date=updated_time, name='T2', unit='ms', value=(q_specs.get('T2', 1e-9) * units.seconds).m_as(units.milliseconds)), Nduv(date=updated_time, name='readout_error', unit='', value=q_specs.get('fRO')), ]) for q, q_specs in one_qubit_specs.items() ]) qubits = list(qubits_dict.values()) # use native gates and all qubits possibilities: set gate_error and gate_length as parameters (Nduv) def get_fidelities(qubits): if len(qubits) == 1: q = configuration.coupling_canonical_2_device[qubits[0]] stats: Dict[str, float] = one_qubit_specs[q] return stats.get('f1Q_simultaneous_RB') else: q = "-".join([configuration.coupling_canonical_2_device[q] for q in sorted(qubits)]) stats: Dict[str, float] = two_qubit_specs[q] return stats.get('fCZ') gates = [ qiskit.providers.models.backendproperties.Gate( gate=b.name, qubits=q, parameters=[ Nduv(date=updated_time, name='gate_error', unit='', value=1 - get_fidelities(q)), Nduv(date=updated_time, name='gate_length', unit='ns', value=60 if len(q) == 1 else 160 if len(q) else None) ]) for b in configuration.gates for q in b.coupling_map ] # General Measurements maybe of interest / any other interesting measurement (like cross-talk) general = [] backend_properties: BackendProperties = BackendProperties( backend_name=configuration.backend_name, backend_version=configuration.backend_version, last_update_date=updated_time, qubits=qubits, gates=gates, general=general ) # backend_properties._qubits = qubits return backend_properties
# noinspection PyTypeChecker
[docs]def aws_simulator_to_properties(properties: GateModelSimulatorDeviceCapabilities, configuration: QasmBackendConfiguration) -> BackendProperties: updated_time: datetime = properties.service.updatedAt or datetime.now() general: List[Nduv] = [] qubits: List[List[Nduv]] = [] gates: List[qiskit.providers.models.backendproperties.Gate] = [] backend_properties: BackendProperties = BackendProperties( backend_name=configuration.backend_name, backend_version=configuration.backend_version, last_update_date=updated_time, qubits=qubits, gates=gates, general=general ) return backend_properties
# noinspection PyTypeChecker
[docs]def aws_general_to_properties(properties: DeviceCapabilities, configuration: QasmBackendConfiguration) -> BackendProperties: updated_time: datetime = properties.service.updatedAt or datetime.now() general: List[Nduv] = [] qubits: List[List[Nduv]] = [] gates: List[qiskit.providers.models.backendproperties.Gate] = [] backend_properties: BackendProperties = BackendProperties( backend_name=configuration.name, backend_version=configuration.arn, last_update_date=updated_time, qubits=qubits, gates=gates, general=general ) return backend_properties