Skip to main content

qirtoqasm: QIR to OpenQASM translator

Latest Version Supported Python Versions Build status codecov Documentation Status

This library translates QIR programs (the QIR Base Profile and Adaptive Profile) to Braket-compatible OpenQASM 3.0.

Why qirtoqasm?

qirtoqasm bridges the growing ecosystem of QIR-emitting quantum compilers to the OpenQASM 3 format that Amazon Braket accepts. Many quantum frontends emit QIR as their serialization format — qirtoqasm converts that QIR to a Braket-ready OpenQASM 3 program without any further rewriting required by the caller.

The implementation is a pure-Rust core with four public faces:

  • A Python package (qirtoqasm) built via PyO3 + maturin. Single one-stage public function: qirtoqasm.translate(qir_text, *, producer=None) returns Braket-compatible OpenQASM 3. Every tunable is a keyword-only kwarg, so new options can be added without breaking existing callers.
  • A Rust crate (qirtoqasm-core) exposing translate(qir_text, &TranslateOptions) plus a #[non_exhaustive] options struct with builder methods.
  • A C ABI (libqirtoqasm.{a,dylib,so}) whose qirtoqasm_translate(qir, &options, out, err) takes a versioned qirtoqasm_options_t struct (carrying its own struct_version / struct_size so fields can be appended without breaking existing callers). Pass NULL options for defaults.
  • A C++20 header (qirtoqasm/qirtoqasm.hpp) with translate(qir) and translate(qir, const Options&), designed for C++20 designated-initializer syntax.

No LLVM, llvmlite, or any Python runtime dependency — the only external dependency is the platform C runtime. The Python wheel is self-contained.

Braket-targeted by design

The output of qirtoqasm.translate can be handed directly to braket.ir.openqasm.Program — no further rewriting required. Several emit-name choices follow from this:

  • Two-qubit Ising rotations emit as xx / yy / zz (Braket aliases), not the OpenQASM stdgates.inc names rxx / ryy / rzz.
  • CNOT emits as cnot (not cx).
  • Toffoli emits as ccnot (not ccx).
  • Classical registers are declared as plain bit[N] c;, without the OpenQASM output qualifier.
  • No include "stdgates.inc"; is emitted.

Installation

pip install qirtoqasm

Python ≥ 3.11 is required. The wheel is self-contained — no Rust or LLVM is needed at install time. Wheels are published for Linux (manylinux x86_64 / aarch64 + musllinux x86_64), macOS (x86_64 + arm64), and Windows (x86_64).

Python quick start

import qirtoqasm

qasm = qirtoqasm.translate("""
    %Qubit = type opaque
    %Result = type opaque
    define void @main() #0 {
      call void @__quantum__qis__h__body(%Qubit* null)
      call void @__quantum__qis__cnot__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
      call void @__quantum__qis__mz__body(%Qubit* null, %Result* null)
      call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*))
      ret void
    }
    declare void @__quantum__qis__h__body(%Qubit*)
    declare void @__quantum__qis__cnot__body(%Qubit*, %Qubit*)
    declare void @__quantum__qis__mz__body(%Qubit*, %Result*) #1
    attributes #0 = { "entry_point" "qir_profiles"="base_profile" "requiredQubits"="2" "requiredResults"="2" }
    attributes #1 = { "irreversible" }
""")
print(qasm)

qirtoqasm.translate accepts QIR as a string. To read from a file, use the standard library:

from pathlib import Path
qasm = qirtoqasm.translate(Path("bell.ll").read_text())

Every output ends with a trailing // generated-by: {"name":"qirtoqasm",…} comment. Callers that wrap qirtoqasm inside a larger toolchain can pass an optional keyword-only producer string to surface their own tool name and version in the comment:

qasm = qirtoqasm.translate(ir_text, producer="mylib 0.1.2")
# last line: // generated-by: {"name":"qirtoqasm","version":"…","profile":"base_profile","producer":"mylib 0.1.2"}

Submitting to Amazon Braket

from pathlib import Path
from braket.devices import LocalSimulator
from braket.ir.openqasm import Program

program = Program(source=qirtoqasm.translate(Path("bell.ll").read_text()))
result = LocalSimulator().run(program, shots=1000).result()
print(result.measurement_counts)

Input format

qirtoqasm accepts QIR as LLVM textual IR (.ll text) only. LLVM bitcode (.bc) is not supported; if you have bitcode, convert it with llvm-dis first. This is deliberate: the Rust core has no LLVM link dependency, which keeps the wheel tiny (no 100+ MB LLVM payload) and keeps the build hermetic.

C++ quick start

Requires a C++20 compiler. The public surface is qirtoqasm::translate plus a small Options struct for tunables:

#include <qirtoqasm/qirtoqasm.hpp>

// Simplest: defaults.
std::string qasm = qirtoqasm::translate(qir_text);

// With options (C++20 designated initializers):
std::string qasm = qirtoqasm::translate(qir_text,
    qirtoqasm::Options{ .producer = "mylib 0.1.2" });
// throws qirtoqasm::TranslationError on failure

From CMake:

find_package(qirtoqasm REQUIRED)
target_link_libraries(my_target PRIVATE qirtoqasm::qirtoqasm)
target_compile_features(my_target PRIVATE cxx_std_20)

C quick start

For C-only consumers, the same C ABI is exposed via a header:

#include <qirtoqasm/qirtoqasm.h>

char *out = NULL, *err = NULL;

// Simplest: NULL options uses defaults.
if (qirtoqasm_translate(qir_text, NULL, &out, &err) != QIRTOQASM_OK) { /* … */ }

// With options — always call qirtoqasm_options_init first so future
// fields inherit correct defaults:
qirtoqasm_options_t opts;
qirtoqasm_options_init(&opts);
opts.producer = "mylib 0.1.2";
if (qirtoqasm_translate(qir_text, &opts, &out, &err) != QIRTOQASM_OK) { /* … */ }

qirtoqasm_free_string(out);
qirtoqasm_free_string(err);

See DEVELOPMENT.md for the native-library build workflow.

Supported QIR constructs

  • QIS gates that match the __quantum__qis__<name>__body naming convention: h, x, y, z, s, t, cnot/cx, cy, cz, swap, rx, ry, rz, ccx/ccnot, rxx, ryy, rzz, reset, measurement (mz / m / mresetz), phasedx, and the __adj adjoints for non-self-adjoint gates.
  • Mid-circuit measurement read via __quantum__qis__read_result__body(%Result*) and the alias __quantum__rt__read_result, driving conditional br i1.
  • Compound Boolean conditions. icmp <pred> i1/iN with all ten LLVM integer predicates (eq, ne, ult/slt, ule/sle, ugt/sgt, uge/sge); direct bitwise i1 and, or, xor (including the xor i1 %x, true logical-NOT idiom); select i1 (including clang's short-circuit shapes select %c, %b, false and select %c, true, %b); and phi i1 short-circuit merges. Covers common frontends' short-circuit encodings and the compound- Boolean forms clang emits for a && b, a || b, !a, a == b, a != b.
  • Integer arithmetic on classical SSA values: add, sub, mul (with the nuw/nsw/exact overflow-flag tokens allowed). The resulting expression is inlined at the use site, so the operands must resolve to classical-register reads, integer constants, or previously bound arithmetic.
  • phi i32 / phi i64 integer accumulation. The mutable count = 0; if r == One { set count = count + 1; } pattern compiles to chained two-incoming phis. The translator lowers the chain to a single OpenQASM 3 int cint_N = 0; classical variable plus conditional cint_N = cint_N + 1; assignments, plus if (cint_N >= T) { … } threshold branches via icmp.
  • select i1 %c, iN A, iN B integer cascade. Optimized QIR produced by LLVM's opt pipeline collapses the integer-accumulation chain into nested selects plus zext / add / icmp ugt on an integer counter. Lowers to the inline arithmetic form (cond) * A + (1 - cond) * B; downstream add / icmp flow through the expanded expression.
  • alloca / bitcast / getelementptr / store / load scalar constant folding for the common list[float] parameter pattern: eagerly-bound scalar values stashed in a local buffer get folded back to their numeric literals at the gate-argument use site, so rx(angles[0], q[0]) with angles=[0.1, 0.2] emits rx(0.1) q[0];.
  • Variadic multi-controlled dispatch via the generalizedInvokeWithRotationsControlsTargets intrinsic lowers to the matching Braket-native gate for the following inner callees: __quantum__qis__x__ctl with 1 or 2 controls (→ cnot / ccnot), y__ctl / z__ctl with 1 control (→ cy / cz), swap__ctl with 1 control and 2 targets (→ cswap), and phaseshift__ctl with 1 control (→ cphaseshift). The adjoint flag maps to inv @. Unmapped (op, numControls, numTargets) tuples produce a descriptive error pointing at upstream decomposition.
  • CFG reduction: sequential blocks, if / if-else, single-exit while loops (one back-edge), and short-circuit phi merges.
  • Structs %Qubit and %Result, plus inline struct-by-value parameter literals ({ double*, i64 }). Other user-defined struct types raise QirToQasmError.

Out of scope (produce a clear error)

All unsupported cases raise qirtoqasm.QirToQasmError with a message naming the root cause.

  • Nested or irreducible CFGs, multi-entry loops, nested loops the reducer cannot structure.
  • Runtime qubit allocation (__quantum__rt__qubit_allocate). All qubits must be assigned statically via inttoptr.
  • Value-typed select for floating-point (select i1 %c, double A, double B used to choose a rotation angle). OpenQASM 3 has no classical ternary in value position; split into if/else arms upstream or precompute. The integer analog select i1 %c, iN A, iN B IS supported via inline arithmetic.
  • Loop-carried phi — integer counters or booleans merging across a true back-edge loop latch. If-merge phis are supported.
  • Controlled-gate combinations not on the mapped list above (e.g. 3-control X, controlled-H). Decompose upstream, or open an issue with the missing mapping.

Contributing and sharing feedback

We welcome feature requests, bug reports, or general feedback, which you can share with us by opening up an issue. We also welcome pull requests — please open an issue describing your work when you get started, or comment on an existing issue with your intentions. For more details on contributing to qirtoqasm, please read the contributing guidelines.

For questions, you can get help via the Quantum Technologies section of AWS RePost. Please tag your question with "Amazon Braket" and mention qirtoqasm in the question title.

Tests

To run qirtoqasm's unit tests, run:

tox -e unit-tests

See DEVELOPMENT.md and the docs site for the full workflow (Rust build, maturin, CMake, coverage, all tox environments).

Security

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

qirtoqasm-0.1.0-cp311-abi3-win_amd64.whl (290.5 kB view details)

Uploaded CPython 3.11+Windows x86-64

qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_x86_64.whl (451.8 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_aarch64.whl (411.6 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

qirtoqasm-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (368.9 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

qirtoqasm-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl (344.6 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

qirtoqasm-0.1.0-cp311-abi3-macosx_11_0_arm64.whl (329.3 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

qirtoqasm-0.1.0-cp311-abi3-macosx_10_13_x86_64.whl (347.8 kB view details)

Uploaded CPython 3.11+macOS 10.13+ x86-64

File details

Details for the file qirtoqasm-0.1.0-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: qirtoqasm-0.1.0-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 290.5 kB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for qirtoqasm-0.1.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 427a5bf2c4e31c51d25b89d879ec58c571bc94516276efebe2c200b5e993a5ce
MD5 e93ada9b4953a5a8c121f2a4bbfad75f
BLAKE2b-256 994149644c2ad4a7d97fde9e7379bfed9ea28014e71cd9fe9c3816f2cf61b406

See more details on using hashes here.

Provenance

The following attestation bundles were made for qirtoqasm-0.1.0-cp311-abi3-win_amd64.whl:

Publisher: publish-to-pypi.yml on amazon-braket/qirtoqasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b3b5af72c4b48e7be02128c96cea88889f1f53a3485c71399b1dea5a09398087
MD5 ce0e9146658ef66a89636fa942a51b13
BLAKE2b-256 599d08d87c040e9431d35eed62e90dd475bb36dbacd4411c33166a4ce59c3169

See more details on using hashes here.

Provenance

The following attestation bundles were made for qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_x86_64.whl:

Publisher: publish-to-pypi.yml on amazon-braket/qirtoqasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 dcf20e33e284478d3ab1d8fb8a626987d5b4f7d3ccf5c48c3d2adc0b70c70df0
MD5 a4aafe6c5ec4b6d2da0e2c4a59e064e4
BLAKE2b-256 b20e17d4c961997bead888ee2ba9747e83f3da067b988844bad7eb38321ef7b8

See more details on using hashes here.

Provenance

The following attestation bundles were made for qirtoqasm-0.1.0-cp311-abi3-musllinux_1_2_aarch64.whl:

Publisher: publish-to-pypi.yml on amazon-braket/qirtoqasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qirtoqasm-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for qirtoqasm-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 0c3115b3c51330ecc7c282183efead3c665f558195cf2acc04d6731ba310c3da
MD5 feac6ee36662b4e6c6e78f681442c10f
BLAKE2b-256 146aa28da169c70b192102bb53a5f8a6bed0ed12fc786eb0567bec4868dabfc3

See more details on using hashes here.

Provenance

The following attestation bundles were made for qirtoqasm-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl:

Publisher: publish-to-pypi.yml on amazon-braket/qirtoqasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qirtoqasm-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for qirtoqasm-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 b59bb3d324cbe03ab8551d72f094a9d1155396e9d26ee44c880cc7783fd8b119
MD5 c61e42cfb62e8d5eabf79bbd785369b3
BLAKE2b-256 e62d97fe4f763abf33db7974ba8427d37f5a9ff30631e7146e65d289ad36bbce

See more details on using hashes here.

Provenance

The following attestation bundles were made for qirtoqasm-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl:

Publisher: publish-to-pypi.yml on amazon-braket/qirtoqasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qirtoqasm-0.1.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for qirtoqasm-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a866c6d698367a0f651285f3a4e10ef55f8fe8505e09adc327b667f3da98e3ca
MD5 b9741d4ade87c957ec0d6c2ede93e043
BLAKE2b-256 173a30bcd441ac2fa40df25f2302ab385fb55ee37d8f947bd78199661f8c54dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for qirtoqasm-0.1.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: publish-to-pypi.yml on amazon-braket/qirtoqasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qirtoqasm-0.1.0-cp311-abi3-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for qirtoqasm-0.1.0-cp311-abi3-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 1380831440970fa6c12fb03bd2bf492aa40a3b8b8daf85bfe7e35433a9c2626e
MD5 6a9a6b2e96eb2db025eafb76ff39a7ed
BLAKE2b-256 e2e9c4cc5bb971490ad942949592801aced6d51b2f7152f7366ad2d7672516d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for qirtoqasm-0.1.0-cp311-abi3-macosx_10_13_x86_64.whl:

Publisher: publish-to-pypi.yml on amazon-braket/qirtoqasm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

7 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page