QuiZX is a command line tool and Rust library for circuit optimisation and classical simulation using the ZX-calculus. It began life as high-performance Rust port of the Python library PyZX and is largely inter-operable with that library using QuiZX's Python bindings.
There are three ways to use QuiZX: as a command-line tool, a Rust library, or via its Python bindings. Install the command line tool by running:
cargo install quizx
The quizx
command currently has two sub-commands quizx opt
for circuit optimisation and quizx sim
for classical simulation. For example, to run the circuit optimiser on a QASM file with default options, run:
quizx opt circuit.qasm -o circuit_opt.qasm
To run the classical simulator for 16 shots, run:
quizx sim circuit.qasm -s 16
Run quizx help
to get an overview of the available commands then quizx COMMAND --help
for command-specific help.
To use QuiZX from your Rust code, add it in the usual way to Cargo.toml
. See the docs for an overview of the Rust API, as well as mixed bag of examples in the examples folder.
To use QuiZX via Python bindings, simply pip install quizx
. You may wish to also run pip install pyzx
to use various functions from PyZX on QuiZX graphs, most notably drawing functions. See getting_started.ipynb for basic usage. QuiZX graphs expose the same public methods as PyZX graphs, so any function in PyZX that expects a pyzx.graph.BaseGraph
should also work fine (in theory) on QuiZX graphs. This is not thoroughly tested, so if you run into problems, please file an issue.
We are in the process of more rigorously benchmarking the performance of QuiZX. You can see the results so far in the benches folder. These are written using the Criterion benchmarking library and are runnable from the command line using cargo bench
.
As a very anecdotal example of the performance difference with PyZX, the program spider_chain
builds a chain of 1 million Z spiders and fuses them all. In PyZX, you can fuse all the spiders in a ZX-diagram as follows:
from pyzx.basicrules import *
success = True
while success:
success = any(fuse(g, g.edge_s(e), g.edge_t(e)) for e in g.edges())
In QuiZX, the Rust code is slightly more verbose, but similar in spirit:
use quizx::basic_rules::*;
loop {
match g.find_edge(|v0,v1,_| check_spider_fusion(&g, v0, v1)) {
Some((v0,v1,_)) => spider_fusion_unchecked(&mut g, v0, v1),
None => break,
};
}
On my laptop, the PyZX code takes about 98 seconds to fuse 1 million spiders, whereas the QuiZX code takes 17 milliseconds.
The library is available both as a Rust crate and a Python package. See the Python Changelog and the Rust Changelog for the latest updates.
See the CONTRIBUTING.md file for detailed instructions for building the libraries from source and contributing to the project. Pull requests are welcome!
This project is licensed under Apache License, Version 2.0 ([LICENSE][] or http://www.apache.org/licenses/LICENSE-2.0).