pytket-qiskit#

IBM’s Qiskit is an open-source framework for quantum computation, ranging from high-level algorithms to low-level circuit representations, simulation and access to the IBMQ Experience devices.

pytket-qiskit is an extension to pytket that allows pytket circuits to be run on IBM backends and simulators, as well as conversion to and from Qiskit representations.

pytket-qiskit is available for Python 3.10, 3.11 and 3.12, on Linux, MacOS and Windows. To install, run:

pip install pytket-qiskit

This will install pytket if it isn’t already installed, and add new classes and methods into the pytket.extensions namespace.

An example using the shots-based AerBackend simulator is shown below.

from pytket.extensions.qiskit import AerBackend
from pytket import Circuit

backend = AerBackend()
circ = Circuit(2).H(0).CX(0, 1).measure_all()

# Compilation not needed here as both H and CX are supported gates
result = backend.run_circuit(circ, n_shots=1000)

This simulator supports a large set of gates and by default has no architectural constraints or quantum noise. However the user can pass in a noise model or custom architecture to more closely model a real quantum device.

The AerBackend also supports GPU simulation which can be configured as follows.

from pytket.extensions.qiskit import AerBackend

backend = AerBackend()
backend._qiskit_backend.set_option("device", "GPU")

Note

Making use of GPU simulation requires the qiskit-aer-gpu package. This can be installed with the command

pip install qiskit-aer-gpu

Access and Credentials#

With the exception of the Aer simulators, accessing devices and simulators through the pytket-qiskit extension requires an IBM account. An account can be set up here: https://quantum-computing.ibm.com/login.

Once you have created an account you can obtain an API token which you can use to configure your credentials locally.

In this section we are assuming that you have set the following variables with the corresponding values:

# Replace the placeholders with your actual values
ibm_token = '<your_ibm_token_here>'
hub = '<your_hub_here>'
group = '<your_group_here>'
project = '<your_project_here>'

Note

The documentation below is correct as of pytket-qiskit version 0.40.0 and newer. In the 0.40.0 release pytket-qiskit moved to using the qiskit-ibm-provider. In pytket-qiskit versions 0.39.0 and older the parameters hub, group and project were handled separately instead of a single instance string as in 0.40.0 and newer.

from pytket.extensions.qiskit import set_ibmq_config

set_ibmq_config(ibmq_api_token=ibm_token)

After saving your credentials you can access pytket-qiskit backend repeatedly without having to re-initialise your credentials.

If you are a member of an IBM hub then you can add this information to set_ibmq_config as well.

from pytket.extensions.qiskit import set_ibmq_config

set_ibmq_config(ibmq_api_token=ibm_token, instance=f"{hub}/{group}/{project}")

Alternatively you can use the following qiskit commands to save your credentials locally without saving the token in pytket config:

Note

If using pytket-qiskit 0.39.0 or older you will have to use the deprecated IBMQ.save_account() instead of IBMProvider.save_account() in the code below.

from qiskit_ibm_provider import IBMProvider
from qiskit_ibm_runtime import QiskitRuntimeService

IBMProvider.save_account(token=ibm_token)
QiskitRuntimeService.save_account(channel="ibm_quantum", token=ibm_token)

To see which devices you can access you can use the available_devices method on the IBMQBackend or IBMQEmulatorBackend. Note that it is possible to pass optional instance and provider arguments to this method. This allows you to see which devices are accessible through your IBM hub.

from pytket.extensions.qiskit import IBMQBackend
from qiskit_ibm_provider import IBMProvider

my_instance=f"{hub}/{group}/{project}"
ibm_provider = IBMProvider(instance=my_instance)
backend = IBMQBackend("ibmq_nairobi") # Initialise backend for an IBM device
backendinfo_list = backend.available_devices(instance=my_instance, provider=ibm_provider)
print([backend.device_name for backend in backendinfo_list])

Backends Available Through pytket-qiskit#

The pytket-qiskit extension has several types of available Backend. These are the IBMQBackend and several types of simulator.

Backend

Type

IBMQBackend

Interface to an IBM quantum computer.

IBMQEmulatorBackend

Emulator for a chosen IBMBackend (Device specific).

AerBackend

A noiseless, shots-based simulator for quantum circuits [1]

AerStateBackend

Statevector simulator.

AerUnitaryBackend

Unitary simulator

  • [1] AerBackend is noiseless by default and has no architecture. However it can accept a user defined NoiseModel and Architecture.

  • In addition to the backends above the pytket-qiskit extension also has the TketBackend. This allows a tket Backend to be used directly through qiskit. see the notebook example on qiskit integration.

Default Compilation#

Every Backend in pytket has its own default_compilation_pass method. This method applies a sequence of optimisations to a circuit depending on the value of an optimisation_level parameter. This default compilation will ensure that the circuit meets all the constraints required to run on the Backend. The passes applied by different levels of optimisation are specified in the table below.

Default compilation pass for the IBMQBackend and IBMQEmulatorBackend#

optimisation_level = 0

optimisation_level = 1

optimisation_level = 2 [1]

DecomposeBoxes

DecomposeBoxes

DecomposeBoxes

self.rebase_pass [2]

SynthesiseTket

FullPeepholeOptimise

CXMappingPass [3]

CXMappingPass [3]

CXMappingPass [3]

NaivePlacementPass

NaivePlacementPass

NaivePlacementPass

self.rebase_pass [2]

SynthesiseTket

KAKDecomposition(allow_swaps=False)

RemoveRedundancies

self.rebase_pass [2]

CliffordSimp(allow_swaps=False)

RemoveRedundancies

SynthesiseTket

self.rebase_pass [2]

RemoveRedundancies

  • [1] If no value is specified then optimisation_level defaults to a value of 2.

  • [2] self.rebase_pass is a rebase to the gateset supported by the backend, For IBM quantum devices that is {X, SX, Rz, CX}.

  • [3] Here CXMappingPass maps program qubits to the architecture using a NoiseAwarePlacement

Note: The default_compilation_pass for AerBackend is the same as above.

Backend Predicates#

Circuits must satisfy certain conditions before they can be processed on a device or simulator. In pytket these conditions are called predicates.

All pytket-qiskit backends have the following two predicates.

  • GateSetPredicate - The circuit must contain only operations supported by the :py:class`Backend`. To view supported Ops run BACKENDNAME.backend_info.gate_set.

  • NoSymbolsPredicate - Parameterised gates must have numerical values when the circuit is executed.

The IBMQBackend and IBMQEmulatorBackend may also have the following predicates depending on the capabilities of the specified device.