Bell State

This is a showcase of connecting to tergite via the tergite SDK, running a basic two-qubit circuit to generate the bell state \(|\Psi\rangle = |00\rangle + |11\rangle\), and retrieving the measurement results.

Install dependencies

This example depends on:

Install these dependencies

%pip install qiskit
%pip install tergite

Import the basic dependencies

import time
import qiskit.circuit as circuit
import qiskit.compiler as compiler
from tergite.qiskit.providers import Tergite
from tergite.qiskit.providers.provider_account import ProviderAccount

Configure Session

Before we get any further, we will take the time to define some of the parameters we will use for our tergite job.

# the Tergite API URL e.g. "https://api.tergite.example"
API_URL = "https://api.qal9000.se"
# API token for connecting to tergite
API_TOKEN = "API-TOKEN"
# The name of the Quantum Computer to use from the available quantum computers
BACKEND_NAME = "SimulatorC"
# the name of this service. For your own bookkeeping.
SERVICE_NAME = "local"
# the timeout in seconds for how long to keep checking for results
POLL_TIMEOUT = 300

Get the Tergite Backend

The backend object can now be obtained. A detailed list of the backend properties — such as the available gate set, coupling map and number of qubits — is availablde by printing the backend object.

# provider account creation can be skipped in case you already saved
# your provider account to the `~/.qiskit/tergiterc` file.
# See below how that is done.
account = ProviderAccount(service_name=SERVICE_NAME, url=API_URL, token=API_TOKEN)

provider = Tergite.use_provider_account(account)
# to save this account to the `~/.qiskit/tergiterc` file, add the `save=True`
# provider = Tergite.use_provider_account(account, save=True)

# Get the tergite backend in case you skipped provider account creation
# provider = Tergite.get_provider(service_name=SERVICE_NAME)
backend = provider.get_backend(BACKEND_NAME)
backend.set_options(shots=1024)
print(backend)

Create the Qiskit Circuit

To test our connection, we will implement a short test circuit. The circuit we will run produces the Bell state \(|\Psi\rangle = |00\rangle + |11\rangle.\)

qc = circuit.QuantumCircuit(2)
qc.h(0)
qc.cx(0,1)

We can visualize and verify our circuit with Qiskit’s built in draw() method. The output format of qc.draw() can be changed, see https://docs.quantum.ibm.com/build/circuit-visualization. Note the two added measurements and corresponding classical bit registers meas_0 and meas_1.

qc.draw()

To measure the prepared Bell state we add explicit measurements to all qubits using qc.measure_all(). This will perform a meaurement in the so-called computational basis, \(\langle q_n|Z|q_n\rangle\), mapping the eigenvalues \(\{-1,1\}\) to the classical binary values \(\{0,1\}\). Drawing the final circuit shows the additional measurement operations and the classical bit register meas_0 and meas_1.

qc.measure_all()
qc.draw()

Compile Circuit

In order to execute the circuit on physical hardware, the circuit needs to be compiled (or transpiled) to the target architecture. At the least, transpilation accounts for the QPU’s native gate set and the qubit connectivity on the QPU. Many transpilers also offer some level of optimization, reducing the circuit size.

tc = compiler.transpile(qc, backend=backend)
tc.draw()

Run the Circuit

Once the cicruit has been compiled to the native gate set and connectivity, we use it to submit a job to the backend.

job = backend.run(tc, meas_level=2, meas_return="single")

See the Results

When the job has been submitted, we will need to wait potential queue time and time required to execute the job.

elapsed_time = 0
result = None
while result is None:
    if elapsed_time > POLL_TIMEOUT:
        raise TimeoutError(f"result polling timeout {POLL_TIMEOUT} seconds exceeded")

    time.sleep(1)
    elapsed_time += 1
    result = job.result()

result.get_counts()

Acknowledgement

This notebook was prepared by:

Back to top