Batch Jobs¶
Note
Batching is only supported on the Helios-1. For batching on System Model H2, see here.
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 (
nexus:qnexus.jobs.ExecuteJob()).Only compatible with Helios-1. Batching is not supported on syntax checkers or Helios 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.
The main method synthesizes an 8-qubit log-depth GHZ circuit, and compiles the guppy source into a Heirarchical Unified Graph Representation (HUGR) binary. HUGR is a compact intermediate representation for Guppy programs.
from guppylang import guppy
from guppylang.std.quantum import cx, h, measure_array, qubit
from guppylang.std.builtins import array, result, comptime, barrier
n_qubits = 8
@guppy
def main() -> None:
"""
Create a GHZ circuit with log depth.
"""
qubit_array: array[qubit, comptime(n_qubits)] = array(qubit() for _ in range(comptime(n_qubits)))
h(qubit_array[0])
barrier(qubit_array)
qubits_used: int = 1
i: int = 0
while qubits_used < comptime(n_qubits):
i += 1
for k in range(qubits_used):
cx(qubit_array[k], qubit_array[qubits_used])
qubits_used += 1
barrier(qubit_array)
mresults = measure_array(qubit_array)
result("measurementResults", mresults[0])
hugr = main.compile()
The max_cost keyword argument in the QuantinuumConfig constructor is used to stop HQC consumption if a threshold is exceeded during batch execution. The device_name corresponds to the emulation target Various Helios backends can be specified via device_name. The keyword argument attempt_batching is used to enable batching for all nexus:qnexus.jobs.ExecuteJob() submitted to the emulator.
import qnexus as qnx
config = qnx.models.QuantinuumConfig(device_name="Helios-1", max_cost=500, simulator="stabilizer")
The Nexus project is initialized and a name suffix is defined.
import qnexus as qnx
import datetime
project = qnx.projects.get_or_create("release/helios", f"HUGR to support Quantinuum Helios Release.")
qnx.context.set_active_project(project)
name_suffix = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M_%S")
The HUGR binary is uploaded to Nexus with a unique name (datetime) using the qnx.hugr module. The HUGR upload requires a user friendly name, which does not need to be unique across the Nexus project. A HUGR reference is returned after uploading to the Nexus database. This reference is required for execute jobs.
from importlib.metadata import version
pkg_version = version('hugr') # replace 'numpy' with your package name
hugr_ref = qnx.hugr.upload(
hugr_package=hugr,
name=f"ghz-{datetime.strftime('%Y-%m-%d_%H-%M-%S')}",
description=f"Log-depth GHZ circuit using {n_qubits} qubits. HUGR version {pkg_version}.",
)
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=[hugr_ref 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")