dvlab-ntu / qsyn Goto Github PK
View Code? Open in Web Editor NEWA C++-based growing software system for synthesizing, optimizing, and verifying quantum circuits
License: Apache License 2.0
A C++-based growing software system for synthesizing, optimizing, and verifying quantum circuits
License: Apache License 2.0
Minimum reproducing test file:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
cx q[0], q[0];
Currently, the qcir package is hard to use mainly because it fails to account for the variability of different types of gates. For example, we can’t model a matrix or a boolean oracle to a gate;
Also, some gates expose inappropriate interfaces; the SWAP gate---currently implemented through a GateRotationCategory
of swap---exposes get_phase()
, and before a previous refactoring, a T gate exposes set_phase()---which causes problems in identifying gate type.
I’ve investigated how Qiskit structures their qk.QuantumCircuit
. Roughly speaking, their abstraction is as follows:
A QuantumCircuit
contains a list of CircuitInstruction
s.
A CircuitInstruction
is composed of an Operation and its operands. For example, a cx q[0], q[1]
; instruction is composed of the operation cx
and operand q[0], q[1]
;
An Operation
can be a quantum gate, measurements, barriers, etc.
Note that in the above, none of the above hierarchy maintains the gate connectivity explicitly because QuantumCircuit
always sorts its CircuitInstruction
in the topological order. Qiskit also has another class called DAGCircuit
for applications that require further knowledge of the connections.
Currently, our abstraction is as follows:
A QCir
contains a list of QCirGate
s.
A QCirGate
is an instruction and knows its connection to the predecessors/successors.
A GateType
represents a quantum gate and is a helper class in instantiating QCirGate. Note that each QCirGate
does not own a GateType
but takes the latter’s information into the former’s members.
I propose to
QCir
. QCirGate
will become local to its pertinent QCir
and is always accessed by its IDs. This should not be too problematic because when we care about predecessors and successors, we often need the whole circuit anyway.Operation
class that represents an operation and can be owned by a QCirGate
.QCirGate
to Instruction
to better reflect its role in the code base.More specifically, here’s a plan of how we would achieve that:
QCir
and starting to support ID-based access to instructions. #89QCirGate
as an instruction abstraction, add an Operation as an operation instruction, and repurpose the current GateType as a legacy gate type inheriting Operation
. #94QCirGate
with device::Operation
and duostra::Gate
. #94Operation
. #98 #100 #101QCirGate
as the interface to the gate's predecessors and successors. #98QCir
#98QCirGate
to Instruction
.QCirGate*
as the accessor to all gates in the QCir
.For some reason, after zx2qc
sometimes the Duostra mapper will segfault as of v0.6.2. Here's the dofile, also available in tests/conversion/duostra/v0.6.2-bug.dof
:
device read benchmark/topology/casablanca.layout
// This qcir won't fail
qcir qubit add 3
qcir gate add h 0
qcir gate add h 1 --prepend
qcir gate add cz 0 2 --prepend
qcir gate add cz 1 2 --prepend
qcir gate add h 0 --prepend
qcir gate add h 1 --prepend
qcir gate add h 2 --prepend
qcir gate add h 2 --prepend
qcir print -d
duostra -c
// This one will, even though these two are supposedly the same circuit???
qcir new
qcir qubit add 3
qcir gate add cx 2 1
qcir gate add cx 2 0
qc2zx
zxopt
zx2qc
qcir print -d
duostra -c
quit -f
ZXLive seems to be a convenient tool for visualizing ZX-diagrams. It would be greatly beneficial if we supported the .zxg
format it uses.
The current extraction routine suffers from a too-greedy heuristic. The algorithm extracts all gates it sees without considering circuit depths and other metrics. It would be cool if the extractor knew how to consider the parallelity of quantum circuits.
As title, an error occurred while running the following dofile.
Shortest_path.txt
The error message:
std::tuple<QubitIdType, QubitIdType> qsyn::device::Device::get_next_swap_cost(QubitIdType, QubitIdType): Assertion "q_source.is_adjacency(q_next)" failed. Aborted (core dumped)
Now that we support short/long-form arguments, it would be great if we could specify many of them at once.
For example,
<cmd> -q -c -v
--> <cmd> -qcv
.
If, however, -qcv
corresponds to another argument, should that argument take precedence? I guess so but it's best to check other implementations.
It would be greatly convenient if the user could provide some .qsynrc
file, to define their own aliases, variables, and other things.
The .qsynrc
file can be implemented as just regular dofiles. When qsyn
launches, it would try to read the file from ~/.config/
directory
Alternatively, the user could provide a custom path through the command-line flag, for example, --qsynrc-path
.
The folder now consists of mainly benchmarks from the older versions.
qcir print -d
should be aware of ID lengthQCirGate::get_type_str
As title. In particular the yquant
package is much more readable than qcircuit
and quantikz
.
Error dofile
extract config --optimize-level 0
qc read benchmark/SABRE/large/cm82a_208.qasm
qc2zx
zx opt
usage
logger info
zx2qc
usage
qc print
qc2zx
zx adjoint
zx list
zx com 0
zx opt
usage
zx test -i
zx print -q
zx2ts
ts print 0
q -f
Also, zx2ts segfault
While our representation of device topology is more concise, reading IBM's device file directly may be more convenient.
The program produces an incorrect usage when mutually exclusive groups contain (optional) positional arguments. For example,
auto mutex1 = parser.addMutuallyExclusiveGroup();
auto mutex2 = parser.addMutuallyExclusiveGroup();
mutex2.addArgument<int>("c")
.nargs(NArgsOption::OPTIONAL);
mutex1.addArgument<int>("a")
.nargs(NArgsOption::OPTIONAL);
mutex1.addArgument<string>("-b");
mutex2.addArgument<string>("-d");
Usage: Argparse [[<int a>] | -B <string B>] [[<int c>] | -D <string D>]
Description:
ArgParse package sandbox
Positional Arguments:
int c
int a
Options:
string -B B
string -D D
The error is that argument c
should be before a
, but the mutex grouping does not know how to order the groups properly. Worse still, sometimes it is just not possible to get the right order. Consider if the first group contains positional arguments 1 and 3, and the second group contains positional argument 2.
Fortunately, this should be an edge case error since it is more intuitive to define the arguments in the same groups together, thereby preventing such bad ordering from happening in the first place.
I've looked at how Python argparse
handles this, and it seems like they choose to respect the positional order at the cost of breaking argument grouping. This should not be hard, but it is a bit tedious. Therefore, I've chosen to open this issue instead of trying to fix it now.
If reading .qasm
file with SWAPs, some commands (for example qcir print
) will still panic, and the qc2ts
does not seem to result in a correct transformation.
For example, if printing usage for qcir read
, the usage should print Usage: qcir read [-h] [-r] <string filepath>
.
Currently the qcir
part is missing.
The Stabilizer Tableau proposed in the paper Improved simulation of stabilizer circuits seems to be immensely helpful for linking ZX-diagrams and other quantum circuit optimization approaches. I will open a branch to work on this one.
The benchmark/
folder is so large that our project is filled with .qasm
files. It would be better if we separated the folder into another repo. Benchmarks that the tests need can live inside tests/
.
Currently, qsyn
always tries to read the qsynrc
files from ~/.config/qsynrc
.
It is good if we allow the user to set a series of paths.
In particular, the user can export QSYNRC_PATHS
to the environments, and qsyn
can tries to find qsynrc
in those directories.
dim>2 ??
For example, the convert
command has an option called decomp_mode
, with a default value 3. However, it is not marked correctly as optional args, as can be seen from the usage: ... [size_t decomp_mode]
qpp | xtensor | qsyn support |
---|---|---|
real | xt::real(a) | real |
imag | xt::imag(a) | imag |
conjugate | xt::conj(a) | conjugate+transpose = adjoint |
transpose | xt::transpose(a, {1, 0, 2}) | transpose |
adjoint | adjoint | |
determinant | xt::linalg::det(a) | TODO |
trace | xt::linalg::trace(a) | TODO |
eigenvectors, eigenvalues | xt::linalg::eig(a) | TODO |
read matrix | tensor_read | |
write matrix | tensor_write | |
disp |
tensor/
For a unified calling interface, it's best to unify the short/long forms of the arguments.
auto new_graph = std::move(graph.value())
auto new_graph = std::move(graph).value()
The ids are different
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.