-
Notifications
You must be signed in to change notification settings - Fork 28
The staq compiler
All of the main functionality of the staq library is packaged up in a command line executable, staq
. In particular, staq
provides support for reading in OpenQASM (.qasm
) files, performing a series of transformations, and outputting either resource estimates, or the resulting circuit in several common circuit description languages. This page provides details and examples of its usage to perform circuit synthesis, optimization, resource estimation and compilation tasks.
To give an overview of some of the features of the staq compiler (and library), consider the below QASM circuit, found in the examples/ directory.
foo@bar:$ cat showcase.qasm
OPENQASM 2.0;
include "qelib1.inc";
oracle tof4 a,b,c,d,e { "toffoli_4.v" }
qreg a[6];
tof4 a[0],a[1],a[2],a[3],a[4];
tof4 a[0],a[1],a[2],a[3],a[5];
This circuit uses a syntax extension of OpenQASM to allow importing Verilog files as quantum oracles. To perform most operations on the above circuit, we first need to compile or synthesize the tof4
gate, which we can add as a compiler pass via the command line option --synthesize
or just -S
.
foo@bar:$ staq --synthesize showcase.qasm
OPENQASM 2.0;
include "qelib1.inc";
gate tof4 a,b,c,d,e {
ancilla anc[1];
h anc[0];
cx b,anc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx b,nc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx a,b;
tdg b;
cx a,b;
t a;
t b;
h anc[0];
h a;
t a;
cx d,a;
tdg a;
cx c,a;
t a;
cx d,a;
tdg a;
h a;
h e;
cx e,a;
tdg a;
cx anc[0],a;
t a;
cx e,a;
tdg a;
cx anc[0],a;
t a;
h a;
t a;
cx d,a;
tdg a;
cx c,a;
t a;
cx d,a;
tdg a;
h a;
tdg a;
cx anc[0],a;
t a;
cx e,a;
tdg a;
cx anc[0],a;
t a;
cx e,a;
h e;
h anc[0];
cx b,anc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx b,anc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx a,b;
tdg b;
cx a,b;
t a;
t b;
h anc[0];
}
qreg a[6];
tof4 a[0],a[1],a[2],a[3],a[4];
tof4 a[0],a[1],a[2],a[3],a[5];
Rather than print out the entire circuit back in QASM format, it is frequently useful to just get a list of gate and depth counts of the circuit. This can be done by specifying the --format
or -f
flag with the argument resources
.
foo@bar:$ staq -S --format resources showcase.qasm
Resource estimates for showcase.qasm:
depth: 112
t: 60
qubits: 6
cx: 52
h: 20
ancillas: 2
With the oracle synthesized, we can begin adding passes to optimize the quantum circuit. In particular, staq offers an implementation of phase folding (M. Amy, Formal Methods in Quantum Circuit Design, F. Zhang, J. Chen, Optimizing T gates in Clifford+T circuit as π/4 rotations around Paulis) via the --rotation-fold
or -r
flag.
foo@bar:$ staq -S --rotation-fold -f resources showcase.qasm
Resource estimates for showcase.qasm:
depth: 110
cx: 52
s: 2
t: 52
qubits: 6
h: 20
ancillas: 2
From the resource counts it can be seen that the rotation folding optimization has reduced the number of t
gates by 8. However, to get a better sense of what's happening it's helpful to look at the full circuit.
foo@bar:$ staq -S -r showcase.qasm
OPENQASM 2.0;
include "qelib1.inc";
gate tof4 a,b,c,d,e {
ancilla anc[1];
h anc[0];
cx b,anc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx b,anc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx a,b;
tdg b;
cx a,b;
t a;
h anc[0];
h a;
t a;
cx d,a;
tdg a;
cx c,a;
t a;
cx d,a;
tdg a;
h a;
h e;
cx e,a;
tdg a;
cx anc[0],a;
t a;
cx e,a;
tdg a;
cx anc[0],a;
t a;
h a;
t a;
cx d,a;
tdg a;
cx c,a;
t a;
cx d,a;
tdg a;
h a;
cx anc[0],a;
t a;
cx e,a;
tdg a;
cx anc[0],a;
t a;
cx e,a;
h e;
h anc[0];
cx b,anc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx b,anc[0];
tdg anc[0];
cx a,anc[0];
t anc[0];
cx a,b;
tdg b;
cx a,b;
s b;
h anc[0];
}
qreg a[6];
tof4 a[0],a[1],a[2],a[3],a[4];
tof4 a[0],a[1],a[2],a[3],a[5];
The compiler has optimized the implementation of tof4
itself, removing 4 t
gates, but it's missed other gate cancellations between the two instances of tof4
in the circuit body -- such optimizations are interprocedural or whole-program optimizations. To apply optimizations across the whole program with staq, the can be inlined first via the --inline
or -i
flag. In this case, inlining before applying the rotation folding optimization removes another 10 t
gates.
foo@bar:$ staq -S --inline -r -f resources showcase.qasm
Resource estimates for showcase.qasm:
h: 20
cx: 52
t: 42
s: 8
qubits: 7
depth: 106
Rotation folding can often result in adjacent gates which are inverse, and can then be cancelled. To catch these additional optimizations activated by rotation folding, it is often useful to add a gate cancellation pass via the flag --simplify
or -s
. In this case, two h
and cx
each can be removed.
foo@bar:$ staq -S -i -r --simplify -f resources showcase.qasm
Resource estimates for showcase.qasm:
h: 18
cx: 50
t: 42
s: 8
qubits: 7
depth: 103
This common inline, rotation-fold, simplify sequence can be applied simply with the -O2
optimization flag, while -O1
applies the comparable intraprocedural (i.e., not inlined) optimization. The resulting circuit compiled with -O2
can be viewed below.
Click to expand
foo@bar:$ staq -S -O2 showcase.qasm
OPENQASM 2.0;
include "qelib1.inc";
qreg anc[1];
qreg a[6];
h anc[0];
cx a[1],anc[0];
tdg anc[0];
cx a[0],anc[0];
t anc[0];
cx a[1],anc[0];
tdg anc[0];
cx a[0],anc[0];
t anc[0];
cx a[0],a[1];
tdg a[1];
cx a[0],a[1];
t a[0];
h anc[0];
h a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
cx a[2],a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
h a[0];
h a[4];
cx a[4],a[0];
tdg a[0];
cx anc[0],a[0];
t a[0];
cx a[4],a[0];
tdg a[0];
cx anc[0],a[0];
t a[0];
h a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
cx a[2],a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
h a[0];
tdg a[0];
cx anc[0],a[0];
t a[0];
cx a[4],a[0];
tdg a[0];
cx anc[0],a[0];
t a[0];
cx a[4],a[0];
h a[4];
h anc[0];
cx a[1],anc[0];
cx a[0],anc[0];
cx a[1],anc[0];
cx a[0],anc[0];
s a[1];
cx a[1],anc[0];
sdg anc[0];
cx a[0],anc[0];
s anc[0];
cx a[1],anc[0];
sdg anc[0];
cx a[0],anc[0];
s anc[0];
cx a[0],a[1];
sdg a[1];
cx a[0],a[1];
s a[0];
h anc[0];
h a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
cx a[2],a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
h a[0];
h a[5];
cx a[5],a[0];
tdg a[0];
cx anc[0],a[0];
t a[0];
cx a[5],a[0];
tdg a[0];
cx anc[0],a[0];
t a[0];
h a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
cx a[2],a[0];
t a[0];
cx a[3],a[0];
tdg a[0];
h a[0];
cx anc[0],a[0];
t a[0];
cx a[5],a[0];
tdg a[0];
cx anc[0],a[0];
t a[0];
cx a[5],a[0];
h a[5];
h anc[0];
cx a[1],anc[0];
tdg anc[0];
cx a[0],anc[0];
t anc[0];
cx a[1],anc[0];
tdg anc[0];
cx a[0],anc[0];
t anc[0];
cx a[0],a[1];
tdg a[1];
cx a[0],a[1];
s a[1];
h anc[0];
While in some cases it may be desirable to optimize a circuit and return it for use in other contexts, one may also want to map the circuit to a particular physical device with constraints on which qubits can be coupled -- in particular, between which qubits a CX
gate may be applied. QASM circuits can be mapped to a physical device via the --map-to-device
or -m
flag.
foo@bar:$ staq -S -O2 --map-to-device -f resources showcase.qasm
Resource estimates for showcase.qasm:
qubits: 7
CX: 47
U(0,0,0.785398): 21
U(0,0,-0.785398): 21
U(1.5708,0,3.14159): 18
U(0,0,1.5708): 5
U(0,0,-1.5708): 3
depth: 101
To map to a physical device, all gates are inlined to the primitive QASM gates CX
and U
. In this case, the number of CX
gates has not been increased by the mapping as the default device is fully-connected. On the other hand, consider switching to the ibm_tokyo.json
device found in the qpus/
directory (by passing it as an argument to the --device
or -d
option). The number of CX
gates increases dramatically:
foo@bar:$ staq -S -O2 -m --device ibm_tokyo.json -f resources showcase.qasm
Resource estimates for showcase.qasm:
qubits: 20
CX: 112
U(0,0,0.785398): 21
U(0,0,-0.785398): 21
U(1.5708,0,3.14159): 18
U(0,0,1.5708): 5
U(0,0,-1.5708): 3
depth: 164
To decrease the CX
counts, the staq compiler offers a variety of algorithms for generating both and initial mapping from logical to physical qubits (--layout
,-l
), and for mapping the remaining decoupled CX
gates (--mapping-alg
,-M
). In this case the linear
and swap
algorithms give a worse CX
count:
foo@bar:$ staq -S -O2 -m -d ibm_tokyo.json -l linear -M swap -f resources showcase.qasm
Resource estimates for showcase.qasm:
qubits: 20
CX: 155
U(0,0,-0.785398): 21
U(1.5708,0,3.14159): 18
U(0,0,1.5708): 5
U(0,0,0.785398): 21
U(0,0,-1.5708): 3
depth: 159
Typically it is best to try a compilation task with a few choices of algorithms and see what works best. The resulting circuit with the lower CX
count can be viewed below
Click to expand
foo@bar:$ staq -S -O2 -m -d ibm_tokyo.json showcase.qasm
OPENQASM 2.0;
include "qelib1.inc";
qreg q[20];
U(pi/2,0,pi) q[1];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[6],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
U(0,0,-pi/4) q[1];
CX q[6],q[1];
U(0,0,pi/4) q[1];
CX q[2],q[1];
U(0,0,pi/4) q[1];
CX q[6],q[1];
U(0,0,-pi/4) q[1];
CX q[1],q[2];
CX q[6],q[1];
CX q[1],q[2];
CX q[6],q[1];
CX q[2],q[1];
U(pi/2,0,pi) q[1];
U(pi/2,0,pi) q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[3],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
U(pi/2,0,pi) q[2];
U(pi/2,0,pi) q[4];
U(0,0,pi/4) q[2];
CX q[3],q[2];
CX q[4],q[3];
CX q[3],q[2];
U(0,0,-pi/4) q[2];
CX q[1],q[2];
U(0,0,pi/4) q[2];
CX q[3],q[2];
CX q[4],q[3];
CX q[3],q[2];
U(0,0,-pi/4) q[2];
CX q[1],q[2];
U(pi/2,0,pi) q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[3],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
U(pi/2,0,pi) q[2];
U(0,0,-pi/4) q[2];
CX q[3],q[2];
CX q[4],q[3];
CX q[3],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[3],q[2];
CX q[4],q[3];
CX q[3],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
U(pi/2,0,pi) q[4];
U(pi/2,0,pi) q[1];
U(0,0,pi/2) q[6];
U(0,0,pi/2) q[2];
CX q[1],q[2];
CX q[6],q[1];
CX q[1],q[2];
U(0,0,-pi/2) q[2];
U(0,0,-pi/2) q[1];
CX q[6],q[1];
U(0,0,pi/2) q[1];
CX q[2],q[1];
U(0,0,pi/2) q[1];
CX q[6],q[1];
U(0,0,-pi/2) q[1];
CX q[1],q[2];
CX q[6],q[1];
CX q[1],q[2];
CX q[6],q[1];
CX q[2],q[1];
U(pi/2,0,pi) q[1];
U(pi/2,0,pi) q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[3],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
U(pi/2,0,pi) q[2];
U(pi/2,0,pi) q[0];
U(0,0,pi/4) q[2];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,pi/4) q[2];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[1],q[2];
CX q[0],q[1];
U(pi/2,0,pi) q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[3],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[5],q[0];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
U(pi/2,0,pi) q[2];
CX q[1],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,-pi/4) q[2];
CX q[0],q[1];
CX q[1],q[2];
U(0,0,pi/4) q[2];
CX q[1],q[2];
CX q[0],q[1];
CX q[1],q[2];
CX q[0],q[1];
U(pi/2,0,pi) q[0];
U(pi/2,0,pi) q[1];
U(0,0,pi/2) q[6];
CX q[1],q[6];
CX q[2],q[1];
CX q[1],q[6];
U(0,0,-pi/4) q[6];
U(0,0,-pi/4) q[1];
CX q[6],q[1];
U(0,0,-pi/4) q[1];
CX q[2],q[1];
U(0,0,pi/4) q[1];
CX q[6],q[1];
U(0,0,pi/4) q[1];
CX q[1],q[6];
CX q[2],q[1];
CX q[1],q[6];
CX q[2],q[1];
U(pi/2,0,pi) q[1];
By default staq
outputs QASM code to standard output. However, circuits can also be translated to Quil, ProjectQ, Q# or Cirq format with the -f
option, and further optionally written to a file by specifying --output
or -o
, followed by a filename. The code block below shows the resulting circuit compiled for the 8 qubit Rigetti Agave device, and output in Quil format
Click to expand
foo@bar:$ staq -S -O2 -m -d rigetti_agave.json -l eager -M steiner -f quil showcase.qasm
DEFGATE X:
0, 1
1, 0
DEFGATE CNOT:
1, 0, 0, 0
0, 1, 0, 0
0, 0, 0, 1
0, 0, 1, 0
DEFGATE U(%theta, %phi, %lambda):
EXP(-i*(%phi+%lambda)/2)*COS(%theta/2), -EXP(-i*(%phi-%lambda)/2)*SIN(%theta/2)
EXP(i*(%phi-%lambda)/2)*SIN(%theta/2), EXP(i*(%phi+%lambda)/2)*COS(%theta/2)
DEFCIRCUIT CLEAR q scratch_bit:
MEASURE q scratch_bit
JUMP-UNLESS @end scratch_bit
X q
LABEL @end
U(pi/2, 0, pi) 6
U(0, 0, pi/4) 7
CNOT 6 7
CNOT 5 6
CNOT 6 7
U(0, 0, -pi/4) 7
U(0, 0, -pi/4) 6
CNOT 7 6
U(0, 0, -pi/4) 6
CNOT 5 6
U(0, 0, pi/4) 6
CNOT 7 6
U(0, 0, pi/4) 6
CNOT 6 7
CNOT 5 6
CNOT 6 7
CNOT 5 6
U(pi/2, 0, pi) 6
U(pi/2, 0, pi) 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, pi/4) 7
CNOT 0 7
U(pi/2, 0, pi) 7
U(pi/2, 0, pi) 2
U(0, 0, pi/4) 7
CNOT 6 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(0, 0, pi/4) 7
CNOT 6 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(pi/2, 0, pi) 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, pi/4) 7
CNOT 0 7
U(pi/2, 0, pi) 7
U(0, 0, -pi/4) 7
CNOT 6 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 6 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(pi/2, 0, pi) 2
U(pi/2, 0, pi) 6
U(0, 0, pi/2) 7
U(0, 0, pi/2) 6
CNOT 7 6
U(0, 0, -pi/2) 6
U(0, 0, pi/2) 5
CNOT 6 5
CNOT 7 6
CNOT 6 5
U(0, 0, -pi/2) 5
CNOT 6 5
U(0, 0, pi/2) 5
CNOT 6 5
CNOT 7 6
CNOT 6 5
U(0, 0, -pi/2) 5
CNOT 7 6
CNOT 6 5
U(pi/2, 0, pi) 6
U(pi/2, 0, pi) 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, pi/4) 7
CNOT 0 7
U(pi/2, 0, pi) 7
U(pi/2, 0, pi) 3
U(0, 0, pi/4) 7
CNOT 6 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 3 2
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(0, 0, pi/4) 7
CNOT 6 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 3 2
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(pi/2, 0, pi) 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 0 7
U(0, 0, pi/4) 7
CNOT 0 7
U(pi/2, 0, pi) 7
CNOT 6 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 3 2
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(0, 0, -pi/4) 7
CNOT 6 7
U(0, 0, pi/4) 7
CNOT 0 7
CNOT 1 0
CNOT 2 1
CNOT 3 2
CNOT 2 1
CNOT 1 0
CNOT 0 7
U(pi/2, 0, pi) 3
U(pi/2, 0, pi) 6
U(0, 0, pi/4) 6
CNOT 7 6
U(0, 0, -pi/4) 6
U(0, 0, pi/2) 5
CNOT 6 5
CNOT 7 6
CNOT 6 5
U(0, 0, -pi/4) 5
CNOT 6 5
U(0, 0, pi/4) 5
CNOT 6 5
CNOT 7 6
CNOT 6 5
U(0, 0, -pi/4) 5
CNOT 7 6
CNOT 6 5
U(pi/2, 0, pi) 6
Usage:
staq [PASSES/OPTIONS] FILE.qasm
Passes are individual compiler transformations on the circuit. A pass may be applied any number of times, and the order of passes given via the command line gives the order of their application to the circuit.
Pass | Description |
---|---|
-i,--inline |
Inline all gate applications |
-S,--synthesize |
Synthesize oracles into regular gates |
-r,--rotation-fold |
Perform a rotation-folding optimization |
-c,--cnot-resynth |
Apply a CNOT optimization pass |
-s,--simplify |
Perform a gate cancellation optimization |
-m,--map-to-device |
Map the circuit onto a physical device |
-O1 |
Light optimization pass. Equivalent to -r -s
|
-O2 |
Heavy optimization pass. Equivalent to -i -s -r -s
|
-O3 |
Non-monotonic optimization pass |
The remaining options control output formats and options for the various transformations. The options are described below
Option | Description |
---|---|
-o,--output FILE |
Specify a file to write to. Otherwise output will be given on standard out. |
-f,--format (qasm⎮quil⎮projectq⎮qsharp⎮cirq⎮resources) |
The format to output the circuit in. Resources gives a listing of the resources used in the circuit. Default=qasm . |
-d,--device |
The device to map to (JSON file). |
-l,--layout (linear⎮eager⎮bestfit) |
The algorithm used to generate the initial layout. Default=bestfit . |
-M,--mapping-alg (swap⎮steiner) |
The algorithm used to map CX gates to a device. Default=steiner . |
--disable_layout_optimization |
Disables an expensive layout optimization pass when using the steiner mapper. |
--no-expand-registers |
Disables expanding gates applied to registers rather than qubits. |
--no-rewrite-expressions |
Disables evaluation of parameter expressions. |
--evaluate-all |
Evaluate all parameter expressions as real numbers. |
For more information on the various functions of the compiler, as well as more fine-grain control over passes and transformations, see the staq tool suite.
Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved.