qstack is a research framework for building quantum compiler stacks on top of xdsl. It provides a linear quantum IR, a surface language based on a subset of OpenQASM 3, compiler passes, verification, and execution backends in one Python codebase.
qstack focuses on the quantum part of hybrid quantum-classical programs. All classical computation, such as decoders, branch conditions, or arithmetic on measurement results, sits behind opaque callbacks: the IR records which measurement bits flow into each callback and which quantum behavior it may select, but never the callback's body. Callbacks are host-language implementations registered by name, and compiler passes and verifiers never inspect them. As a result, qstack works with any hybrid program regardless of what evaluates its classical side, whether that is Python, a decoder library, an FPGA, or a separate classical runtime, and its passes and verification can concentrate entirely on quantum structure while preserving every callback boundary exactly.
A central goal of qstack is pass verification across every layer of the stack. Each transformation should produce IR whose structure, types, and linear use of quantum and classical values can be checked before the next lowering layer consumes it. This makes verification part of the compiler pipeline rather than a final validation step.
The project is primarily intended for researchers and developers working on:
- quantum error-correction transformations;
- circuit optimization and decomposition passes;
- qubit layout and hardware-lowering passes; and
- compiler analyses for hybrid quantum-classical programs.
Programs enter qstack through the supported OpenQASM 3 subset or direct IR construction. Compiler passes progressively lower them through instruction-set dialects, with verification boundaries between layers. The resulting modules can be evaluated with the included state-vector and Stim-backed runtimes.
To learn more about using qstack, take a look at the examples folder.
The compiler entry point returns a CompilationResult rather than a bare
module:
from qstack.surface import compile_qasm
from qstack.passes import lower_cliffords_to_h2
from qstack.verification import verify
source = compile_qasm(qasm_text)
target = lower_cliffords_to_h2(source)
target = target.save("step.qstack.json")
report = verify(target)verify independently checks a compiler pass using its source, target, and
transformation witness. It reports VERIFIED, REFUTED, or UNSUPPORTED;
encoded/QEC verification is not yet supported.
For circuit checks, install a verifier such as
Quivalence (pip install ./verifiers/quivalence) or
MQT QCEC. Installed verifiers are discovered automatically.
See the verification design for details.
qstack requires Python 3.12 or newer. To install it in a fresh virtual environment:
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install .For an editable development installation with the test and build tools:
python -m pip install -e '.[dev]'Jupyter support can be installed separately:
python -m pip install -e '.[jupyter]'src/qstack/dialect/defines the core IR and instruction-set dialects.src/qstack/passes/contains decomposition and QEC transformations.src/qstack/surface/parses and lowers the supported OpenQASM 3 subset.src/qstack/runtime/provides execution, noise, and callback infrastructure.src/qstack/verifier.pyenforces qstack-specific IR invariants.verifiers/contains independently installable circuit-rule verifiers.tests/contains unit and end-to-end compiler tests.
The notebooks in examples/ demonstrate application construction, compilation,
and evaluation. They are end-to-end usage examples rather than tutorials for
implementing new compiler passes.
qstack.visualize emits Mermaid flowcharts directly from a kernel's SSA
dataflow. Operations are nodes, SSA values are labeled with their IR names,
qubits are solid wires, measurement bits are bold wires, and the derived host
state is a dotted wire.
Direct calls are inlined by default, so their wires flow through the callee's
operations within an @kernel region. Recursive calls remain references to
keep diagrams finite. Pass inline_calls=False to show called definitions
within their call-site subgraphs instead.
from qstack.visualize import dataflow
diagram = dataflow(module, kernel="main")
print(diagram.to_mermaid())
diagram.display()display() emits Mermaid-fenced Markdown for Jupyter frontends that support
Mermaid rendering. to_mermaid() is always available for copying into another
Mermaid-compatible renderer. After %load_ext qstack.jupyter, dataflow is
already available in the notebook namespace.
Run the test suite from the repository root:
pytestBuild the source distribution and wheel with:
python -m buildFor the IR design and project motivation, see DESIGN.md and POSITIONING.md.
qstack is available under the MIT License.