Batch Jobs

The batch feature enables users to benefit from “ad-hoc” reservations. Circuits submitted together in a batch will run at one time. Once a batch hits the front of the queue, jobs in a batch will run uninterrupted until they are completed. Hence, chunks from other organizations’ jobs will not contaminate chunks in a batch.

Batching Requirements:

  • Only supported by Nexus Execute Jobs ().

  • Only compatible with Quantinuum hardware or emulator targets. Batching is not supported on syntax checkers or Nexus-hosted emulators.

  • Batching is supported across multiple Nexus execute jobs. Each Nexus execute job has a 300 circuit hard limit.

Batch termination conditions:

  • A user specifies the current job submission is the last job in the batch

  • 1 minute of inactivity

  • The total job cost in the batch exceeds 2,000 HQCs.

    • If the total HQCs for jobs in a batch hit this limit, those jobs will run as regular jobs in the queue instead of as a batch.

More information on batching in Nexus is available here.

The Bell state is prepared on 2-qubits with a final measurement on all qubits.

from pytket.circuit import Circuit

circuit = Circuit(2, name="Bell State")
circuit.H(0)
circuit.CX(0, 1)
circuit.measure_all()

The qnexus.QuantinuumConfig instance is configured to use the H1-1E emulator. This is a server-side emulator, but is not hosted in Nexus. The keyword argument attempt_batching is used to enable batching for all submitted to the emulator.

import qnexus as qnx

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

The Nexus project is initialized and a name suffix is defined.

import qnexus as qnx
import datetime

project = qnx.projects.get_or_create("Batching")
qnx.context.set_active_project(project)

name_suffix = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M_%S")

The Bell state circuit is uploaded to the Nexus database. The circuit reference is used to start a compile job.

ref_circuit = qnx.circuits.upload(
    circuit=circuit,
    name=f"pre-compiled-circuit-{name_suffix}"
)
ref_compile_job = qnx.start_compile_job(
    circuits=[ref_circuit],
    optimisation_level=2,
    backend_config=config,
    name=f"compile-job-{name_suffix}"
)
qnx.jobs.wait_for(ref_compile_job)
ref_compiled_circuit = qnx.jobs.results(ref_compile_job)[0].get_output()

The compiled circuit reference is used to submit an execute job with four instances of the Bell State, each circuit with a different number of shots. The execute job uses batching since it is specified QuantinuumConfig instance passed to the function.

n_shots = 100

ref_execute_job = qnx.start_execute_job(
    circuits=[ref_compiled_circuit for _ in range(4)],
    n_shots=[i*n_shots for i in range(1,5)],
    backend_config=config,
    name=f"execute-job-{name_suffix}"
)
qnx.jobs.wait_for(ref_execute_job)
results = [
    ref_result.download_result() 
    for ref_result in qnx.jobs.results(ref_execute_job)
]

The probability distribution of measurements is printed below.

for i, r in enumerate(results):
    print(f"result {i} with {n_shots * (i+1)} shots\n{r.get_distribution()}\n")