Quantinuum Simulators, Emulators and Quantum Hardware, via Nexus

This notebook outlines how to target and configure specific simulators, emulators and quantum hardware offered by Quantinuum.

Go to Full Example H-series Workflow using qnexus

For more extensive documentation on emulators and hardware, please see the H-series documentation

import qnexus as qnx

from qnexus.models.language import Language

Available Quantinuum Devices

You can select which Quantinuum device you’d like to target via the device_name parameter in the QuantinuumConfig you pass as part of a job submission.

Noiseless simulators (cloud-hosted by Nexus)

These are currently provided for all Nexus users. Usage is accounted for in your Simulation quota.

  • “H1-1LE”

  • “H2-1LE”

Syntax Checkers

We recommend these are used to verify your code before submission to hardware or emulators.

  • “H1-1SC”

  • “H2-1SC”

Noise-modelled Emulators

These attempt to accurately emulate the H-series hardware, with configurable error models. Currently we provide both cloud-hosted emulators and emulators running on our own hardware. These both use the same underlying software with nearly-identical noise-modelling so it is expected that results are comparable.

Cloud-hosted emulators require that your organisation has the ‘Emulator’ premium feature in Nexus, and usage is accounted for in your Simulation quota.

  • “H1-Emulator”

  • “H2-Emulator”

We also offer access to emulators running on our own hardware, these each require a specific H-series Plan and usage is accounted for in HQC.

  • “H1-1E”

  • “H2-1E”

Quantum Hardware

These are Quantinuum’s quantum computers. They each require a specific H-series Plan and usage is accounted for in HQC.

  • “H1-1”

  • “H2-1”

# Create a configuration to target the H1-1LE noiseless simulator
my_quantinuum_config = qnx.QuantinuumConfig(
    device_name="H1-1LE",
)

Calculating Cost (H-series and hardware-hosted emulators only)

Nexus provides the ability to find out the cost of running circuit executions on Quantinuum quantum computers (e.g. H1-1) and hardware-hosted emulators (e.g. H1-1E).

NB this is different from the cloud-hosted simulators (e.g. H1-1LE) or emulators (e.g. H1-Emulator) which are accounted for in your Simulation quota (measured in seconds), for which we do not offer cost estimation.

The syntax_checker argument should be the corresponding syntax checker device (e.g. “H1-1SC” for “H1-1E” or “H1-1”).

qnx.circuits.cost(
    circuit_ref=your_circuit_ref,
    n_shots=1000,
    backend_config=qnx.QuantinuumConfig(device_name="H1-1"),
    syntax_checker="H1-1SC",
)

# -> returns a float representing the cost in HQC

Emulator Error Configuration

By default, both the cloud-hosted (e.g. H1-Emulator) and hardware-hosted (e.g. H1-1E) emulators will model H-series quantum hardware. If desired this noise can be configured.

For documentation on noise configuration, please see the H-series emulator noise model documentation

from qnexus.models.h_series_noise import UserErrorParams

my_params = UserErrorParams(
    p1 = 0.1,
    p2 = 0.5,
    # adjust as needed according to noise model documentation
)

backend_config = qnx.QuantinuumConfig(
    device_name="H1-Emulator", # Or another emulator such as H1-1E
    error_params = my_params
)
# Alternatively you can pass in the noise model as a dictionary
backend_config = qnx.QuantinuumConfig(
    device_name="H1-Emulator",
    error_params = {"p1":0.1, "p2":0.5}
)

Compiler Options

By default, additional compliation will NOT occur in the H-series submission stack (e.g. for quantum hardware or hardware-hosted emulators like H1-1E). However if desired, additional compilition can be configured.

Certain compiler flags can be passed on to the compiler in the H-series submission stack. This is distinct from the TKET-based compilation that happens when you compile circuits in Nexus.

You can configure compiler options in the QuantinuumConfig by passing no_opt=False and QuantinuumCompilerOptions as arguments.

If you would like more information on the compilation configuration available, please get in touch with H-series suppport.

from quantinuum_schemas.models.backend_config import QuantinuumCompilerOptions

# Allow the H-series compiler to decide what 2-qubit gate to rebase to.
compiler_flags = {"noreduce": True}

backend_config = qnx.QuantinuumConfig(
    device_name="H1-1",
    no_opt=False,
    compiler_options=QuantinuumCompilerOptions(**compiler_flags),
)

Submission Language selection

You can specify the submission language for execute job submissions to H-series, available options include QIR, AUTO and OPENQASM 2.0.

execute_job_ref = qnx.start_execute_job(
    circuits=my_circuit_ref,
    name=f"My Execute Job from {datetime.now()}",
    n_shots=[100],
    backend_config=backend_config,
    project=my_project_ref,
    language="QIR",
)

Queueing for H-Series hardware and emulators

Quantinuum Nexus is the default platform for submitting to H-series emulators and hardware, however H-series hardware and emulators have their own dedicated job queue.

When you submit a job to H-series hardware or emulators, they will be entered into a fair-share queuing system. When the selected device is available the fair-share queueing algorithm will select a job approximately as follows:

  • Select jobs queued for active batches.

  • Select an Organisation that has used the device the least in recent history.

    • Select a job from that Organisation that was submitted under a User Group with the highest Group priority (1 being highest, 5 being default, 10 being lowest).

    • Select a job from that Organisation that was submitted by a User with the highest User priority (same ordering as above).

Your organization admin can help assign the appropriate priority to you or a User Group you are a member of.

Batching

If you expect to run multiple circuits, or several circuits in succession (such as during a variational project) you can request that the H-series submission queue ‘batches’ your circuits together so they avoid queueing seperately. Circuits submitted to an existing batch will run immediately, provided they are submitted within 60 seconds of the completion of the last circuit you submitted to the batch.

If desired Nexus will attempt to automatically handle the batching of circuits when submitted in a list (such as an execute job with multiple circuits) or in succession (multiple execute job submissions).

You can request that Nexus attempts to batch your circuits by setting the attempt_batching flag in the QuantinuumConfig:

backend_config = qnx.QuantinuumConfig(
    device_name="H1-1E", attempt_batching=True
)

Example H-series workflow

The following is a minimal example workflow targetting the H-series emulator H1-1E to compile and execute a circuit with a custom noise model configuration.

import qnexus as qnx
from pytket import Circuit
from datetime import datetime
# View Quantinuum devices that are available to the logged in user
qnx.devices.get_all(issuers=["QUANTINUUM"]).df()
my_project_ref = qnx.projects.get_or_create(name="My H1-1E Project")
# Specify our config to target the H1-1E device, with a custom noise model

my_params = UserErrorParams(
    # Linearly scale the probability of dephasing causing a fault.
    memory_scale = 0.5,
)

backend_config = qnx.QuantinuumConfig(
    device_name="H1-1E"
    error_params = my_params
)
circuit = Circuit(2).H(0).CX(0,1).measure_all()

my_circuit_ref = qnx.circuits.upload(
    name=f"My H-series Circuit from {datetime.now()}",
    circuit = circuit,
    project = my_project_ref,
)
# Compile the circuit on Nexus using our hosted TKET compilation service

compiled_circuits = qnx.compile(
    circuits=[my_circuit_ref],
    name=f"My Compile Job from {datetime.now()}",
    optimisation_level=1,
    backend_config=backend_config,
    project=my_project_ref,
)

compiled_circuits.df()
# Double check the HQC cost of running the circuit
execution_cost = qnx.circuits.cost(
    circuit_ref=compiled_circuits[0],
    n_shots=1000,
    backend_config=qnx.QuantinuumConfig(device_name="H1-1E"),
    syntax_checker="H1-1SC",
)

print(execution_cost)
# Submit the job for execution on the H1-Emulator

execute_job_ref = qnx.start_execute_job(
    circuits=compiled_circuits,
    name=f"My Execute Job from {datetime.now()}",
    n_shots=[100]* len(compiled_circuits),
    backend_config=backend_config,
    project=my_project_ref,
    language=Language.QIR,
)

execute_job_ref.df()
qnx.jobs.wait_for(execute_job_ref)
# Retrieve a ExecutionResultRef for every Circuit that was executed
execute_job_result_refs = qnx.jobs.results(execute_job_ref)

# Get a pytket BackendResult for the execution
result = execute_job_result_refs[0].download_result()

result.get_counts()