Getting Started

Installation

Install from PyPI:

pip install hugr-qir

Python

The main Python entrypoint is hugr_to_qir.

Example with conversion and submission
 1import datetime
 2import qnexus as qnx  # type: ignore
 3from qnexus.exceptions import AuthenticationError  # type: ignore [import-not-found]
 4from typing import no_type_check
 5from guppylang import guppy, qubit
 6from guppylang.std.builtins import output
 7from guppylang.std.quantum import measure, x
 8from hugr_qir.hugr_to_qir import hugr_to_qir
 9from hugr_qir.output import OutputFormat
10from hugr_qir.h_series_helpers.results import backendresult_to_qsysresult
11
12
13# Define Guppy program
14@guppy
15@no_type_check
16def main() -> None:
17    q0 = qubit()
18    q1 = qubit()
19    x(q0)
20    x(q1)
21    b0 = measure(q0).read()
22    b1 = measure(q1).read()
23    b2 = b0 ^ b1
24    output("0", b2)
25
26# Generate QIR
27hugr_package = main.compile()
28qir_bitcode = hugr_to_qir(hugr_package, validate_qir=True, output_format=OutputFormat.BITCODE)
29
30# Get or create a Nexus project to submit jobs in
31try:
32    project = qnx.projects.get_or_create(name="HUGR-QIR-Demo")
33except AuthenticationError:
34    qnx.login()
35    project = qnx.projects.get_or_create(name="HUGR-QIR-Demo")
36qnx.context.set_active_project(project)
37
38# Run job on Nexus
39# Use the H2-1 syntax checker (emits dummy results)
40# Switch to H2-1E or H2-2E for actual emulation
41device_name = "H2-1SC"
42qir_name = "HUGR-QIR"
43jobname_suffix = datetime.datetime.now().strftime("%Y_%m_%d-%H-%M-%S")
44job_name = f"execution-job-qir-{qir_name}-{device_name}-{jobname_suffix}"
45qir_program_ref = qnx.qir.upload(qir=qir_bitcode, name=qir_name, project=project)
46config = qnx.QuantinuumConfig(device_name=device_name)
47ref_execute_job = qnx.start_execute_job(
48    programs=[qir_program_ref],
49    n_shots=[10],
50    backend_config=config,
51    name=job_name,
52)
53qnx.jobs.wait_for(ref_execute_job)
54qir_result = qnx.jobs.results(ref_execute_job)[0].download_result()
55
56# Convert Pytket BackendResult to QSysResult
57qsysres = backendresult_to_qsysresult(qir_result)
58
59# Print QSysResult
60for i, shot in enumerate(qsysres.results):
61    print(f"{i}: {shot.entries}")

This example shows the full flow:

  1. define a Guppy program

  2. compile it to a HUGR package with main.compile()

  3. convert that HUGR package to QIR with hugr_to_qir

  4. submit QIR via qnexus to the device

  5. download results and convert it to a qsys result via backendresult_to_qsysresult

hugr_to_qir accepts either a hugr.package.Package or serialized HUGR bytes. In this example, qir is a string containing LLVM IR.

CLI

The installed package also provides a CLI:

hugr-qir input.hugr

To write LLVM IR to a file:

hugr-qir input.hugr -f llvm-ir -o output.ll

To see the full set of options:

hugr-qir --help

Guppy to HUGR

If you want to compile a Guppy program and feed it into hugr-qir, a simple pattern is:

if __name__ == "__main__":
    import sys

    sys.stdout.buffer.write(main.compile().to_bytes())

Then:

python my_program.py > program.hugr
hugr-qir program.hugr -f llvm-ir

Examples

See the working examples in Examples.