qirtoqasm: QIR to OpenQASM translator
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) exposingtranslate(qir_text, &TranslateOptions)plus a#[non_exhaustive]options struct with builder methods. - A C ABI (
libqirtoqasm.{a,dylib,so}) whoseqirtoqasm_translate(qir, &options, out, err)takes a versionedqirtoqasm_options_tstruct (carrying its ownstruct_version/struct_sizeso fields can be appended without breaking existing callers). PassNULLoptions for defaults. - A C++20 header (
qirtoqasm/qirtoqasm.hpp) withtranslate(qir)andtranslate(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 OpenQASMstdgates.incnamesrxx/ryy/rzz. - CNOT emits as
cnot(notcx). - Toffoli emits as
ccnot(notccx). - Classical registers are declared as plain
bit[N] c;, without the OpenQASMoutputqualifier. - 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>__bodynaming 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__adjadjoints for non-self-adjoint gates. - Mid-circuit measurement read via
__quantum__qis__read_result__body(%Result*)and the alias__quantum__rt__read_result, driving conditionalbr i1. - Compound Boolean conditions.
icmp <pred> i1/iNwith all ten LLVM integer predicates (eq,ne,ult/slt,ule/sle,ugt/sgt,uge/sge); direct bitwise i1and,or,xor(including thexor i1 %x, truelogical-NOT idiom);select i1(including clang's short-circuit shapesselect %c, %b, falseandselect %c, true, %b); andphi i1short-circuit merges. Covers common frontends' short-circuit encodings and the compound- Boolean forms clang emits fora && b,a || b,!a,a == b,a != b. - Integer arithmetic on classical SSA values:
add,sub,mul(with thenuw/nsw/exactoverflow-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 i64integer accumulation. Themutable 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 3int cint_N = 0;classical variable plus conditionalcint_N = cint_N + 1;assignments, plusif (cint_N >= T) { … }threshold branches viaicmp.select i1 %c, iN A, iN Binteger cascade. Optimized QIR produced by LLVM's opt pipeline collapses the integer-accumulation chain into nestedselects pluszext/add/icmp ugton an integer counter. Lowers to the inline arithmetic form(cond) * A + (1 - cond) * B; downstreamadd/icmpflow through the expanded expression.alloca/bitcast/getelementptr/store/loadscalar constant folding for the commonlist[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, sorx(angles[0], q[0])withangles=[0.1, 0.2]emitsrx(0.1) q[0];.- Variadic multi-controlled dispatch via the
generalizedInvokeWithRotationsControlsTargetsintrinsic lowers to the matching Braket-native gate for the following inner callees:__quantum__qis__x__ctlwith 1 or 2 controls (→cnot/ccnot),y__ctl/z__ctlwith 1 control (→cy/cz),swap__ctlwith 1 control and 2 targets (→cswap), andphaseshift__ctlwith 1 control (→cphaseshift). The adjoint flag maps toinv @. 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
%Qubitand%Result, plus inline struct-by-value parameter literals ({ double*, i64 }). Other user-defined struct types raiseQirToQasmError.
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 viainttoptr. - Value-typed
selectfor floating-point (select i1 %c, double A, double Bused to choose a rotation angle). OpenQASM 3 has no classical ternary in value position; split intoif/elsearms upstream or precompute. The integer analogselect i1 %c, iN A, iN BIS 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.
Metadata
Release files for qirtoqasm 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qirtoqasm-0.2.0.tar.gz | 103.8 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| qirtoqasm-0.2.0-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details |
| qirtoqasm-0.2.0-cp311-abi3-musllinux_1_2_x86_64.whl | CPython 3.11 | abi3 | Linux musl 1.2+ x86-64 | Details |
| qirtoqasm-0.2.0-cp311-abi3-musllinux_1_2_aarch64.whl | CPython 3.11 | abi3 | Linux musl 1.2+ ARM64 | Details |
| qirtoqasm-0.2.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| qirtoqasm-0.2.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| qirtoqasm-0.2.0-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details |
| qirtoqasm-0.2.0-cp311-abi3-macosx_10_13_x86_64.whl | CPython 3.11 | abi3 | macOS 10.13+ x86-64 | Details |
Total release size: 2.7 MB
Release files / qirtoqasm-0.2.0.tar.gz
| Download URL | qirtoqasm-0.2.0.tar.gz |
|---|---|
| Size | 103.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ed6029211f08a543ada43bee2202ec04237def2504f2a59f65a83b769699297f
|
|
BLAKE2b-256 checksum How to use checksums |
8abe2b3f463d8d1317a34d8c66a7a3244725873170241b55f8fada4444a5ed5b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / qirtoqasm-0.2.0-cp311-abi3-win_amd64.whl
| Download URL | qirtoqasm-0.2.0-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 296.5 kB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
96971e2b54bf0ae560b552a9d9a5fe920f35abe0fd018f111950902deb4700f4
|
|
BLAKE2b-256 checksum How to use checksums |
45b94db99d119360f46760ff981f573856ec342b44b5560a265cc3b100c5d136
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / qirtoqasm-0.2.0-cp311-abi3-musllinux_1_2_x86_64.whl
| Download URL | qirtoqasm-0.2.0-cp311-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 457.3 kB |
| Tags | CPython 3.11 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
746f33830d68d49b214b852fbfed184236cbdb0bb32524d60cc5895b7497fa9e
|
|
BLAKE2b-256 checksum How to use checksums |
94daef7441ba5a9836fef3c727647fe0ea3777ab86c33818fa4b74de13859e6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / qirtoqasm-0.2.0-cp311-abi3-musllinux_1_2_aarch64.whl
| Download URL | qirtoqasm-0.2.0-cp311-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 418.3 kB |
| Tags | CPython 3.11 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
d5c617f40d67392d46d3a7c235fa84555e085b82a9fd30a919b1eaf7e3b6e281
|
|
BLAKE2b-256 checksum How to use checksums |
3b7a158894fd318ebd0fe7d1aad143bd9ad25f3055abd466e1ebd3bfece274f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / qirtoqasm-0.2.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
| Download URL | qirtoqasm-0.2.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
|---|---|
| Size | 374.4 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
ceafb141c57246108e5fded0eee682086c7264f49e7aab768fbe57c0c28576a0
|
|
BLAKE2b-256 checksum How to use checksums |
766b77d060c8712982add01ade9e657b6671920e12b0b8022f3d272b03f23f95
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / qirtoqasm-0.2.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
| Download URL | qirtoqasm-0.2.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl |
|---|---|
| Size | 350.1 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
a0420c99fbd868b806f31bfcbf0bf5f7d30eae4b8465800bc6d0864366ccc79a
|
|
BLAKE2b-256 checksum How to use checksums |
9d78088f0d8a024f8c705f53ed429c37effdd846e1877c2155acceb971a10938
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / qirtoqasm-0.2.0-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | qirtoqasm-0.2.0-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 334.8 kB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
363f8df2f596da2e79a38882f7ae8db1fb1abc64faf7d3e15dc96cf959fa5db1
|
|
BLAKE2b-256 checksum How to use checksums |
6944d1c3a7cb7b98a4a1b2f7ee9e0414a4268678fe8923391ab43ec02a3de734
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / qirtoqasm-0.2.0-cp311-abi3-macosx_10_13_x86_64.whl
| Download URL | qirtoqasm-0.2.0-cp311-abi3-macosx_10_13_x86_64.whl |
|---|---|
| Size | 353.5 kB |
| Tags | CPython 3.11 abi3 macOS 10.13+ x86-64 |
|
SHA-256 checksum How to use checksums |
c62714e8e4075fbfc19e749518edf0d7cd778402e20e8bb180637fee6bdbded4
|
|
BLAKE2b-256 checksum How to use checksums |
cf7d675eea4f48dd561cc2010c0a42d85ea78e5e71d803339b88445203a790d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency log