Quantum Transpilation is the transformation of a given abstract quantum circuit with the aim of:
- Matching the topology, native gate set, errors and other properties of a specific quantum device
- Optimizing the circuit for execution
Even at small scales, transpilation can become a key bottleneck in many complex quantum computing workflows, such as those in Error Mitigation or Quantum Machine Learning, where modular circuits are iteratively updated and transpiled or many instances of largely similar circuits are run. Rivet allows users to design and implement fast automated modular transpilation routines with the transpilation stack of their choice (via Stack Selection), providing tools such as caching and re-use and detailed control over transpilation passes. Despite its advanced functionality, Rivet is easy to use and includes features such as performance tracking and debugging.
The Rivet Transpiler allows users to design and implement fast automated modular transpilation routines with the transpilation stack of their choice. The goal is to allow users complete control over the process, allowing for greater flexibility and large reductions in transpilation time.
Despite its advanced functionality, Rivet Transpiler is easy to use and includes convenience features, such as performance tracking and debugging.
Subcircuit Transpilation and Stitching: Rivet allows circuits to be subdivided, and the parts transpiled separately and maintain the correct relation to the other subparts (qubit indices, mapping between logical and physical qubits, etc.). The pre-transpiled subcircuits can be cached and later consistently stitched together with other circuits (e.g. multiple basis changes) for execution, allowing drastic saving of computational resources.
Flexible Stack Selection: Users can transpile their entire circuit, or parts of a circuit, via one or a combination of transpilation passes from different stacks of their preference. This allows one to choose the optimal transpiling strategy for the given use case and circuit architecture. Supported stacks include:
- Qiskit
- BQSKit
- Pytket
Granular Transpilation Control: Rivet gives the User a high level of insight into, and control over the transpilation process, including the – typically invisible to the user – use of quantum resources, such as auxiliary qubits used in various transpilation passes, which can be constrained via the Qubit-Constrained Transpilation function. Combined with a debugging interface it allows to optimize the classical and quantum compute involved in the execution and shorten the development loop, especially in research and prototyping.
More details about these core features, as well as other useful tools, can be found in the Tutorials section below.
The package provides a family of functions for efficient transpilation of quantum circuits.
- Function
transpile
- transpilation function featuring: - Function
transpile_chain
- consistently transpile and "stitch" a chain of quantum circuits - Function
transpile_right
- transpile an additional circuit to the right part of the existing circuit - Function
transpile_left
- transpile an additional circuit to the left part of the existing circuit. Collectively these functions allow for users to transpile and stitch pieces of circuits. - Function
transpile_and_compress
- transpile and constrain the use of auxiliary qubits in all the transpilation passes of a circuit considering a coupling map of the selected backend
Setting up a local Python environment for each project is reccomemded in order to manage dependencies and versions more effectively. We highly recommend using Conda or Python virtual environments. Alternatively, you can install the requirements in your own Python environment and skip this step.
If you do not have Conda installed, follow the official Conda documentation to download and install Conda.
Once Conda is installed, create an environment for the rivet project:
conda create -y --name rivet python=3.10
conda activate rivet
If you do not have Virtualenv installed, follow the virtualenv documentation to download and install the latest version.
Once Virtualenv is installed, create an environment for the rivet project:
virtualenv venv --python=python3.10
source venv/bin/activate
To install Rivet Transpiler base version (support only qiskit transpilation stack), please run:
pip install 'rivet-transpiler @ git+https://github.com/haiqu-ai/rivet.git'
To install with all stacks, please run:
pip install 'rivet-transpiler[stacks] @ git+https://github.com/haiqu-ai/rivet.git'
To install only BQSKit or only Pytket support:
pip install 'rivet-transpiler[bqskit] @ git+https://github.com/haiqu-ai/rivet.git'
pip install 'rivet-transpiler[pytket] @ git+https://github.com/haiqu-ai/rivet.git'
To run Rivet Transpiler example notebooks, first clone the full repository and navigate to the rivet folder:
git clone https://github.com/haiqu-ai/rivet.git
cd rivet
Install the additional packages needed for the examples:
pip install 'rivet-transpiler[examples] @ git+https://github.com/haiqu-ai/rivet.git'
Run Jupyter and open examples notebooks:
jupyter lab
For more details about the Rivet Transpiler, please check the reference documentation.
An overview of transpilation, as well as other features Rivet offers (e.g. Hashing) are outlined in the links below. Shadow State Tomography and Fourier Adder are examples of the complex processes that could benefit from Rivet’s Subcircuit Transpilation and Stitching.
- Transpilation Overview, Stages, Functions
- Shadow State Tomography
- Big Shadow State Tomography
- Fourier Adder
- Qubit-Constrained Transpilation
- Hashing
- Circuit Stitching
- Quantum Circuit Synthesis
Transpilation includes placement of virtual qubits of a circuit to physical qubits of the quantum device or simulator. Additionally, SWAP gates can be included to route qubits around the backend topology.
Here we present a simple quantum circuit with 3 qubits before and after transpilation (using the function transpile_chain
which transpiles a chain of virtual circuits keeping qubits consistent).
from qiskit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeLimaV2
from rivet_transpiler import transpile_chain
backend = FakeLimaV2()
circuit = QuantumCircuit(3)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(0, 2)
circuit.barrier()
circuit.draw()
q_0: ──■─────────■──
┌─┴─┐ │
q_1: ┤ X ├──■────┼──
└───┘┌─┴─┐┌─┴─┐
q_2: ─────┤ X ├┤ X ├
└───┘└───┘
CHAIN = [circuit] * 3
transpiled_circuit = transpile_chain(
CHAIN,
backend,
seed_transpiler=1234
)
transpiled_circuit.draw(fold=-1)
┌───┐ ░ ┌───┐ ░ ┌───┐ ┌───┐ ┌───┐ ░
q_1 -> 0 ──■─────────■──┤ X ├──■────────░─┤ X ├─────────────────■────────░───■──┤ X ├──■───────┤ X ├───────────────┤ X ├─░─
┌─┴─┐ ┌─┴─┐└─┬─┘┌─┴─┐ ░ └─┬─┘┌───┐ ┌───┐┌─┴─┐┌───┐ ░ ┌─┴─┐└─┬─┘┌─┴─┐┌───┐└─┬─┘┌───┐ ┌───┐└─┬─┘ ░
q_2 -> 1 ┤ X ├──■──┤ X ├──■──┤ X ├──■───░───■──┤ X ├──■──┤ X ├┤ X ├┤ X ├─░─┤ X ├──■──┤ X ├┤ X ├──■──┤ X ├──■──┤ X ├──■───░─
└───┘┌─┴─┐└───┘ └───┘┌─┴─┐ ░ └─┬─┘┌─┴─┐└─┬─┘└───┘└─┬─┘ ░ └───┘ └───┘└─┬─┘ └─┬─┘┌─┴─┐└─┬─┘ ░
q_0 -> 2 ─────┤ X ├───────────────┤ X ├─░────────■──┤ X ├──■─────────■───░──────────────────■─────────■──┤ X ├──■────────░─
└───┘ └───┘ ░ └───┘ ░ └───┘ ░
ancilla_0 -> 3 ────────────────────────────────────────────────────────────────░───────────────────────────────────────────────░─
░ ░
ancilla_1 -> 4 ────────────────────────────────────────────────────────────────░───────────────────────────────────────────────░─
░ ░
We would like to thank:
- Qiskit Quantum SDK
- BQSKit Berkeley Quantum Synthesis Toolkit
- Pytket Python inteface for Quantinuum TKET compiler
- Mykhailo Ohorodnikov
- Yuriy Pryyma
- Vlad Bohun
- Vova Sergeyev
- Mariana Krasnytska
Haiqu Inc. [email protected]