Source code for pytket.extensions.qiskit.tket_backend
# Copyright Quantinuum## 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.importinspectfromtypingimportAnyfrompytket.architectureimportFullyConnectedfrompytket.backendsimportBackendfrompytket.extensions.qiskitimportAerStateBackend,AerUnitaryBackendfrompytket.extensions.qiskit.qiskit_convertimport_gate_str_2_optype_rev,qiskit_to_tkfrompytket.extensions.qiskit.tket_jobimportJobInfo,TketJobfrompytket.passesimportBasePassfrompytket.predicatesimportCompilationUnit,GateSetPredicatefromqiskit.circuit.library.standard_gatesimport(# type: ignoreget_standard_gate_name_mapping,)fromqiskit.circuit.quantumcircuitimportQuantumCircuit# type: ignorefromqiskit.providersimportOptions# type: ignorefromqiskit.providers.backendimportBackendV2# type: ignorefromqiskit.transpilerimportCouplingMap,Target# type: ignoredef_extract_basis_gates(backend:Backend)->list[str]:standard_gate_mapping=get_standard_gate_name_mapping()forpredinbackend.required_predicates:iftype(pred)isGateSetPredicate:basis_gates=[]# Restrict to the gate set accepted by the backend, the converters,# and the Target.from_configuration() method.foroptypeinpred.gate_set:ifoptypein_gate_str_2_optype_rev:gate_name=_gate_str_2_optype_rev[optype]ifgate_nameinstandard_gate_mapping:gate_obj=standard_gate_mapping[gate_name]ifgate_obj.num_qubitsin[1,2]orinspect.isclass(gate_obj):basis_gates.append(gate_name)returnbasis_gatesreturn[]
[docs]classTketBackend(BackendV2):"""Wraps a :py:class:`~pytket.backends.backend.Backend` as a :py:class:`qiskit.providers.BackendV2` for use within the Qiskit software stack. Each :py:class:`qiskit.circuit.quantumcircuit.QuantumCircuit` passed in will be converted to a :py:class:`~pytket._tket.circuit.Circuit` object. If a :py:class:`~pytket._tket.passes.BasePass` is provided for ``comp_pass``, this is applied to the :py:class:`~pytket._tket.circuit.Circuit`. Then it is processed by the :py:class:`~pytket.backends.backend.Backend`, wrapping the :py:class:`~pytket.backends.resulthandle.ResultHandle` s in a :py:class:`~pytket.extensions.qiskit.tket_job.TketJob`, retrieving the results when called on the job object. The required predicates of the :py:class:`~pytket.backends.backend.Backend` are presented to the Qiskit transpiler to enable it to perform the compilation in many cases. This may not always be possible due to unsupported gatesets or additional constraints that cannot be captured in Qiskit's transpiler, in which case a custom :py:class:`qiskit.transpiler.TransformationPass` should be used to map into a tket- compatible gateset and set ``comp_pass`` to compile for the backend. To compile with tket only, set ``comp_pass`` and just use Qiskit to map into a tket-compatible gateset. For examples, see the `user manual <https://docs.quantinuum.com/tket/user-guide/manual/manual_backend.html#embedding-into- qiskit>`_ or the `Qiskit integration example <https://docs.quantinuum.com/tket/user- guide/examples/backends/qiskit_integration.html>`_. """
[docs]def__init__(self,backend:Backend,comp_pass:BasePass|None=None):"""Create a new :py:class:`TketBackend` from a :py:class:`~pytket.backends.backend.Backend`. :param backend: The device or simulator to wrap up :param comp_pass: The (optional) tket compilation pass to apply to each circuit before submitting to the :py:class:`~pytket.backends.backend.Backend`, defaults to None """arch=backend.backend_info.architectureifbackend.backend_infoelseNonecoupling:list[list[Any]]|Noneifisinstance(arch,FullyConnected):coupling=[[n1.index[0],n2.index[0]]forn1inarch.nodesforn2inarch.nodesifn1!=n2]else:coupling=([[n.index[0],m.index[0]]forn,minarch.coupling]ifarchelseNone)super().__init__(name=("statevector_"ifbackend.supports_stateelse"")+"pytket/"+str(type(backend)),backend_version="0.0.1",)self._backend=backendself._comp_pass=comp_passself._target=Target.from_configuration(basis_gates=_extract_basis_gates(backend),num_qubits=len(arch.nodes)ifarchandarch.nodeselse40,coupling_map=CouplingMap(coupling),)