qat.lang : Programming tools¶
The Program class¶

class
qat.lang.AQASM.
Program
¶ Class for quantum programs.
 Parameters
default_gate_set (bool, optional) – If set to False, the Program is initialized with an empty gate set. The gate set is updated dynamically when one applies gates to the Program via the apply method. Default to True.

calloc
(size=1)¶ Allocates a new classical bit register of the given size. Returns the register.
 Parameters
size (int) – The number of classical bits to allocate.
 Returns
A fresh classical bit register of size size
 Return type

cbreak
(formula)¶ Conditional break. The program execution will stop if and only if the formula given as argument evaluates to 1.
 Parameters
formula (
BoolFormula
) – a boolean formula

cc_apply
(cbit, gate, *args)¶ Conditional application of a quantum gate. The quantum gate will be applied if and only if the control classical bit given as first argument evaluates to 1.

comment
(message)¶ Add a comment inside the circuit. The comment will appear in the AQASM export of the circuit.
 Parameters
message (str) – a string containing the comment

conjugate
(gate1, gate2, *args)¶ Apply a sequence of 3 gates. gate2 will be conjugated by gate1. The two gates are required to have the same arity.

export
(fname)¶ Exports the Program in AQASM text format.
 Parameters
fname (str) – A file name

logic
(cbit, formula)¶ Performs a classical logic operation using classical bits and stores the result in a classical bit.
 Parameters
cbit (
Cbit
) – the cbit that will store the resultformula (
BoolFormula
) – A boolean formula.

measure
(qbits, cbits=None)¶ Applies a measurement operator. All measurements are \(Z\) measurements (i.e in the computational basis). Qbits are simply collapsed and not destroyed (i.e they are still usable afterward).
 Parameters
qbits (list<Qbit>) – The qubits to measure specified as a list/register/array
cbits – (list<Cbit>, optional): The classical bits in which to store the result. Default to None. If defaulted/set to None, the results will be stored in classical bits with matching indices.

new_var
(var_type, var_name)¶ Constructs a new variable bound to the circuit.
 Parameters
var_type (type) – The type of the variable.
var_name (str) – The name of the variable. Raises a
VariableNameNotAvailable
if a variable with the same name is already bound to the circuit.
 Returns
A variable
 Return type

qalloc
(size=1, class_type=None, **kwargs)¶ Allocates a new qbit register of the given size. Returns the register.
If no constructor is provided, the register will simply behave as an array of qubits.
The two implemented quantum types are
QInt
andQBoolArray
.from qat.lang.AQASM import Program, QInt, QBoolArray prog = Program() qbits = prog.qalloc(5) print(qbits) qint = prog.qalloc(5, QInt) print(qint) qbools = prog.qalloc(5, QBoolArray) print(qbools)
QReg(q[0]..q[4]) QInt(q[5]..q[9]) QBoolArray(q[10]..q[14])
The main purpose of this wrapping process is to provide a higher level interface for some quantum register, depending on the application. This allows to generate complicated quantum circuits without having to deal with low level administrative constraints.
 Parameters
size (int) – the number of qbits to allocate.
class_type (type) – the quantum type of the register
kwargs – any keyword argument is passed to the constructor of the quantum type
 Returns
A fresh qbit register of size size
 Return type

reset
(qblist, cblist=None)¶ Resets the value of a set of qbits to \(0\rangle\). and/or a set of cbits to 0.
 Parameters
qblist (list<Qbit>) – The list of qbits
cblist (list<Cbit>, optional) – The list of cbits. Default to [].

to_circ
(include_matrices=True, include_locks=False, inline=False, do_link=True, comparison_eps=1e20, box_routines=False, **kwargs)¶ Return a
Circuit
implementing the program.The circuit extraction consists of three stages:
Circuit generation: a simple circuit is extracted from the Program object. Any call to an abstract gate will be left untouched. All circuit implementation attached to abstract gates definition will be ignored at this stage.
Linking: this simple circuit is then linked against:
the gate set aggregated by the program during its construction
any other gate set/abstract gate/python module passed as argument.
The linking process simply attach to each abstract gate a circuit implementation using the function specified at definition of the abstract gate.
Inlining: these implementations are then inlined in place, turning the circuit into a (potentially) very long sequence of gates/operations. By default this step is skipped, as it is very demanding.
All these steps can be controlled using various parameters detailed below.
 Parameters
include_matrices (bool, optional) – if set to True, matrices will be generated and included in the circuit. Defaults to True.
include_locks (bool) – If set to True, additional gates will be added on the ancilla wire to signify lock and release of the ancilla. Defaults to False. This can be used to debug ancilla usage or further optimize the circuit later on. Lock/release operations can be removed from the circuit via the .remove_locks() method.
do_link (bool) – if set to False, skips the linking step. Default to True.
inline (bool) – if set to False, no inlining/linking will happen. Default to False.
comparison_eps (float) – Optional argument to set the matrix/gate parameters comparison threshold. If two parameters are comparison_eps close, they will be considered as identical, resulting in the indentification of their correspondig gates (thus saving space and time). Default value is 1e20.
box_routines (bool) – If set to True, routines will be systematically boxed before being included inside the initial circuit (the one generated during the Circuit generation step). Setting this option to True can save up a lot of time for repetitive circuits.
**kwargs – other arguments passed to the linker. See below.
 Keyword Arguments
submatrices_only (bool) –
if set to True, only submatrices will be generated and included in the circuit. Default to False.
Warning
Setting this argument to True will decrease (by a lot) the circuit generation time. For instance, using the default settings, a RZ rotation controlled 10 times will end up generating a matrix of size (\(2^{11} \times 2^{11}\)). By setting this argument to True, only a \(2\times 2\) matrix will be generated. However, not all simulators are able to infer a matrix from the structure of the gate. In particular, this means that you should set this option to True to simulate circuits on
PyLinalg
.keep (list<str>) – if set to a list of gate names, these gates won’t be inlined by the linker. Default to None.
link (list) – a list of
AbstractGate
,GateSet
, or python packages to pass to the linker.
 Returns
A circuit implementing the program
 Return type
Gate structures¶
All classes describing unitary operators inherit from the Gate
class.
This parent class contains very little information. Its primary function is to store information about control, dagger and other highlevel gate operations. Since this class is not made to be used directly, we skip some part of its documentation.

class
qat.lang.AQASM.gates.
Gate
¶ Mother class for all quantum gates/unitary operators. This class should never be instantiated directly.

conj
()¶ Builds a new gate that is the complex conjugate of the initial gate.
 Returns
The conjugate of the gate.
 Return type

ctrl
(nbctrls=1)¶ Builds a new gate that is a controlled version of the initial gate.
 Returns
The same gate, but controlled.
 Return type

dag
()¶ Builds a new gate that is the dagger of the initial gate.
 Returns
The dagger of the gate.
 Return type

Another important class is the AbstractGate
class. This class provides a way to define new parametrized gates. Basically, an abstract gate describes a family of gates parametrized by a list of values of various types. The current list of admissible types contains: int
, float
, str
For instance, to declare a new AbstractGate
that describes a \(R_z\) rotation, we would write:
my_rz = AbstractGate("RZ", [float], arity=1)
and use this new abstract gate as follows:
my_program.apply(my_rz(0.4), qbits_reg[0])
It is possible to attach a matrix generator to the abstract gate in order to generate and include a matrix in the final circuit (if you want to be able to simulate the circuit for instance).
def matrix_gen(theta):
return np.array([[1, 0], [0, np.exp(1j * theta)])
my_rz = AbstractGate("RZ", [float], arity=1,
matrix_generator=matrix_gen)

class
qat.lang.AQASM.gates.
AbstractGate
¶ Warning
This class is for advanced usage.
Abstract gate class. Abstract gates are used to define gate constructors such as Rx, Ry, Rz, etc.
They behave as quantum gate constructing functions.
This class extends
qat.core.gate_set.GateSignature
.
set_dag
(func)¶ Attaches a dagger recipe to the abstract gate. The function passed as argument should:
take as argument a sequence of parameters
return a new sequence of parameters corresponding to the dagger of the gate.
my_rz = AbstractGate("MY_RZ", [float]) my_rz.set_dag(lambda theta: [theta])
This function will be called when a .dag() method is called on some
ParamGate
.If the dag is not set, the abstract gate will make no assumption on the structure of the dagger, and the standard recursive structure from
Gate
will be used.

ParamGate
is generated through AbstractGate
. An abstract gate instantiated by a set of parameters (such as the my_rz(0.4) from above) returns a ParamGate
carrying all the necessary information to build the correct abstract syntax tree of the gate.

class
qat.lang.AQASM.gates.
ParamGate
¶ Class for parametrized gates instantiated by some set of parameters. Members of this class should be automatically instantiated by the AbstractGate structure. Only instantiate if you know what you are doing.
 Parameters
abstract_gate (
AbstractGate
) – the mother abstract gatearity (int) – the arity of the gate (can be set to None)
*parameters (list<any>) – the list of parameters of the gate
Finally, the notion of gate is also extended to subcircuits via the QRoutine
class.

class
qat.lang.AQASM.routines.
QRoutine
¶ QRoutine
represent subcircuits that behave as a Gate object.The constructor takes no required arguments.
Applying a Gate or a
QRoutine
inside another routine is done through theapply()
method. Since aQRoutine
can exist independently from any Program there are is no notion of qbit allocation in aQRoutine
. Gates are thus applied on indexes refering to the inbound wires of the routine.
apply
(gate, *args)¶ Apply a quantum gate on a set of wires. Wires are refered using integers.
 Parameters
gate (
Gate
) – the quantum gate to apply*args (any iterator over int) – the wires to apply the gate on

compute
()¶ Opens a computation scope and returns a reference to this fresh scope.
Warning
All scopes are lost when controlling/daggering a QRoutine.
Note
This method is designed to be called inside a with statement in order for the scope to be cleanly closed.
with rout.compute(): rout.apply(CNOT, 0, 1) # here the scope is closed rout.uncompute()
Directly calling the method will result in the scope never being closed.

free_ancillae
(args)¶ Return the ancillae qubits to an unused pool so that they can be reused again in the routine. It is important that the ancilla qubits are in product \(0\rangle\) state when they are freed.
 Parameters
args (int/list<int>/quantum register) – the set of ancillae to release

get_free_ancillae
(length=1, class_name=None)¶ Returns a list of ancillae qubits of length length. If there are currently unused ancillae qubits in the list freed_ancillae, they will be returned first. Then, allocate new wires if needed and set them as ancillae.
 Parameters
length (optional, int) – the number of ancillae to allocate (default to 1)
class_name (optional, type) – optionally, a quantum type to wrap the allocated ancillae (e.g QInt, QBool, etc)

new_wires
(length, class_name=None, **kwargs)¶ Returns a list of fresh wires of length length.
 Parameters
length (int) – the number of fresh wires to return
class_name (type) – a quantum type (optional)
kwargs – additinal arguments are passed to the quantum type
 Returns
a quantum register
 Return type

set_ancillae
(*args)¶ Tags some wires as ancillae. This has two effects:
the public arity of the routine will be reduced to only consider the nontagged wires as input/output wires
ancillae will be allocated at circuit generation (in consequence, the final number of qubits of the circuit might be larger than the number of qubits allocated inside the program)
For example, in the following code:
rout = QRoutine() w1, w2 = rout.new_wires() rout.set_ancillae(w1)
rout is a routine of arity 1 (since w1 has been tagged as ancilla). In particular the following code will be a valid program:
prog = Program() qbits = prog.qalloc(1) prog.apply(rout, qbits) circuit = prog.to_circ()
Moreover, the resulting circuit will be a circuit over 2 qubits (the ancilla will be allocated during the contruction of the circuit).

uncompute
()¶ Uncomputes the first computation scope on the scope stack and pops it from the scope stack.

Quantum Types¶
Quantum boolean and expressions¶

class
qat.lang.AQASM.qbool.
QBool
¶ Class for quantum boolean type.
This class is not designed to be instantiated by hand, but rather via the .qalloc method of the
Program
class or the .new_wires method of theQRoutine
class.Moreover, since allocation happens at the register level, the
QBoolArray
class should be used.from qat.lang.AQASM.qbool import QBoolArray from qat.lang.AQASM import QRoutine rout = QRoutine() qbool_array = rout.new_wires(2, QBoolArray) print(type(qbool_array)) print(type(qbool_array[0]))
<class 'qat.lang.AQASM.qbool.QBoolArray'> <class 'qat.lang.AQASM.qbool.QBool'>
See documentation of the
QClause
class for more information. Parameters
Instance attributes:

cast
(val)¶ Cast an integer value as a boolean.
This method is used when casting execution samples to proper python values.
 Parameters
val (int) – some integer
 Returns
a boolean value
 Return type
bool

cast_to
(cls, **kwargs)¶ Cast the register to another type.
 Parameters
cls (type) – another quantum type class
 Returns
some object constructed via cls
 Return type
object
For instance, the following piece of code casts a quantum boolean to a quantum integer:
from qat.lang.AQASM.qbool import QBoolArray from qat.lang.AQASM.qint import QInt from qat.lang.AQASM import QRoutine rout = QRoutine() array = rout.new_wires(2, QBoolArray) qbool = array[0] qint = qbool.cast_to(QInt)

evaluate
(output=None)¶ Evaluate the QBool as an expression. Since QBools are trivial expression, this simply returns self and the output argument is ignored (it is here simply for compatibility with more complicated expressions).

phase
()¶ Flips the phase of the state if and only if the QBool is set to True. Effectively applies a \(Z\) gate on self.

qbits_list
()¶ Returns the list of underlying qubits (i.e [self])

class
qat.lang.AQASM.qbool.
QBoolArray
¶ Class describing an array of
QBool
.This class is not designed to be instantiated by hand, but rather via the .qalloc method of the
Program
class or the .new_wires method of theQRoutine
class.See documentation of the
QClause
class for more information.from qat.lang.AQASM.qbool import QBoolArray from qat.lang.AQASM import QRoutine rout = QRoutine() qbool_array = rout.new_wires(2, QBoolArray) print(type(qbool_array))
<class 'qat.lang.AQASM.qbool.QBoolArray'>
 Parameters
 Instance attributes:
index (int): the index of the underlying qbit
qbits (list of
QBool
): a list of quantum booleans

cast
(val)¶ Cast some integer value as a list of bools.
This method is used when casting execution samples to proper python values.
 Parameters
val (int) – some integer
 Returns
a list of boolean values
 Return type
list of bools

class
qat.lang.AQASM.qbool.
QClause
¶ Class describing boolean formulae to manipulate qubits.
This class is not designed to be instantiated by hand.
Clauses are created by using the boolean operators (and, or, xor, neg) applied on (an)other formula(e) or qubits. Qubits are implicitly cast toward boolean formulae.
Example:
from qat.lang.AQASM import QRoutine from qat.lang.AQASM.qbool import QBoolArray rout = QRoutine() wires = rout.new_wires(2, QBoolArray) and_formula = wires[0] & wires[1] print(type(and_formula))
<class 'qat.lang.AQASM.qbool.QClause'>
A formula should be manipulated via:
the .evaluate method, in order to compute its value in superposition
the .phase method in order to perform a phase flip of all the basis states that evaluate the formula to true
a with statement (see the example below)
Example of evaluate:
from qat.lang.AQASM import QRoutine from qat.lang.AQASM.qbool import QBoolArray rout = QRoutine() wires = rout.new_wires(2, QBoolArray) and_formula = wires[0] & wires[1] # By directly allocating an ancilla result = and_formula.evaluate() # Or by prior allocation of a result qubit result = rout.new_wires(1) and_formula.evaluate(output=result) # At this stage, `result` carries the logical AND between our two inputs
Example of phase:
from qat.lang.AQASM import QRoutine from qat.lang.AQASM.qbool import QBoolArray rout = QRoutine() wires = rout.new_wires(2, QBoolArray) and_formula = wires[0] & wires[1] and_formula.phase() # At this stage, all classical states such that the first two qubits # are set to 1 have their phase flipped
Example of with statement conditional:
from qat.lang.AQASM import QRoutine, CNOT from qat.lang.AQASM.qbool import QBoolArray rout = QRoutine() wires = rout.new_wires(2, QBoolArray) and_formula = wires[0] & wires[1] output = rout.new_wires(1) with and_formula as condition: CNOT(condition, output) # We evaluated the expression, got a qbit `condition` carrying the result # and store the result in `output`

evaluate
(output=None)¶ Builds a circuit evaluating the expression.

phase
()¶ Flips the phase if and only if the expression/qbits evaluates to True.

qbits_list
()¶ Returns a list of underlying qbits.
 Returns
a list of qbits
 Return type
list of Qbits
Quantum integers¶

class
qat.lang.AQASM.qint.
QInt
¶ Class for quantum integer type. The qubit list in a QInt is by default encoded such that the most significant bit is on the left. The order can be reversed using the reverse_bit_order argument.
As other quantum types, this class is not designed to be constructed by hand, but rather via the .qalloc method of the
Program
class or the .new_wires method of theQRoutine
class.Example:
from qat.lang.AQASM.qint import QInt from qat.lang.AQASM import QRoutine rout = QRoutine() qint = rout.new_wires(10, QInt) print(qint, type(qint)) # or, with reversed bit order: qint = rout.new_wires(10, QInt, reverse_bit_order=True)
QInt(q[0]..q[9]) <class 'qat.lang.AQASM.qint.QInt'>
Quantum integers have two sets of overloaded operators:
arithmetic operators (+ and *): combine
QInt
and/orQArithExp
to produce aQArithExp
. See documentation ofQArithExp
for more details.comparison operators (<,>,<=,>=,==,!=): combine a
QInt
/QArithExp
and or a classicalint
in order to produce a comparison expression,QCompExp
, that behave similarly to aQClause
and can be thus used to construct oracles or conditionals.
Moreover, the += and = operators are also overloaded and triggers a circuit evaluating the righthand term and adding it to the quantum integer.
from qat.lang.AQASM.qint import QInt from qat.lang.AQASM import QRoutine rout = QRoutine() qint1 = rout.new_wires(10, QInt) qint2 = rout.new_wires(10, QInt) qint3 = rout.new_wires(10, QInt) # This does nothing qint1 + qint2 # This generates a circuit that adds qint1 in qint3 and qint2 in qint3 qint3 += qint1 + qint2 # This generates a circuit that adds qint1 in qint3 and qint2 in qint3 qint3 = qint1 + qint2
Comparisons results can be used exactly as
QClause
:from qat.lang.AQASM.qint import QInt from qat.lang.AQASM import QRoutine rout = QRoutine() qint1 = rout.new_wires(10, QInt) qint2 = rout.new_wires(10, QInt) # Flips the phase of states such that qint1 is smaller than 3 (qint1 < 3).phase() # Flips the phase of states such that qint1 + qint2 is smaller than 14 (qint1 + qint2 < 14).phase()
 Parameters
Instance attributes:

cast
(val)¶ Casts some integer value into some other integer value with the correct bitorder. This is used when casting execution samples.
 Parameters
val (int) – some integer

evaluate
(nbqbit=None)¶ Evaluate the QInt as a formula. Effectively does nothing and returns a copy of self.

qbits_list
()¶ Returns the underlying list of qubits.
 Returns
a list of quantum booleans
 Return type
list of
Qbit

set_value
(val)¶ Sets the QInt to some classical value.
Note
This method assumes that the QInt is unitialized (i.e is still in state \(0\rangle\)). Effectively, the register is xored with the classical value.
 Parameters
val (int) – some integer value

class
qat.lang.AQASM.qint.
QArithExp
¶ Class describing arithmetic expressions whose operands contain quantum integers.
This class is not designed to be instantiated by hand, but rather built via the addition, substraction, and multiplication of quantum integers with other quantum integers or python integers.
from qat.lang.AQASM import QRoutine, QInt rout = QRoutine() qint = rout.new_wires(10, QInt) print(type(qint + 33))
<class 'qat.lang.AQASM.qint.QArithExp'>

evaluate
(nbqbit=None)¶ Builds a piece of circuit evaluating the arithmetic expression.
 Parameters
nbqbits (optional, int) – the number of qbits of the output register.


class
qat.lang.AQASM.qint.
QCompExp
¶ Class describing quantum comparison expressions to manipulate quantum integers.
This class is not designed to be instantiated by hand, but rather built via comparison of quantum integers (with other quantum integers or classical values) using the standard comparison operators.
from qat.lang.AQASM import QRoutine, QInt rout = QRoutine() qint = rout.new_wires(10, QInt) print(type(qint < 33))
<class 'qat.lang.AQASM.qint.QCompExp'>

evaluate
(output=None)¶ Evaluates the comparison operator and stores the result in a temporary Qbit.

phase
()¶ Flips the phase if and only if the expression evaluates to True.

qbits_list
()¶ Returns the underlying list of qubits

Other structures¶

class
qat.lang.AQASM.bits.
Qbit
¶ Class for qbits.

class
qat.lang.AQASM.bits.
QRegister
¶ Class for registers of qbits. They should only be declared through the qalloc method of the Program class. Qbits inside a register can be accessed similarly to elements of an array (i.e using brackets and slices).

class
qat.lang.AQASM.bits.
CRegister
¶ Class for registers of classical bits. They should only be declared through the calloc method of the AQASM class Cbits inside a register can be accessed similarly to elements of an array (i.e using brackets and slices).
Classical bits and Boolean formulae¶

class
qat.lang.AQASM.bits.
Cbit
¶ Class for cbits.
Cbits can be composed via logical operator to form Boolean formulae.
See
BoolFormula
for examples. Parameters
index (int) – the index of the classical bit

class
qat.lang.AQASM.bits.
BoolFormula
¶ Class describing boolean formulae to manipulate classical bits.
This class is not designed to be instantiated by hand, but rather via composition of
Cbit
via logical operators.Formulae are created by using the classical boolean operators (and, or, xor, neg) applied on (an)other formula(e) or classical bits.
from qat.lang.AQASM import Program prog = Program() cbits = prog.calloc(2) and_expr = cbits[0] & cbits[1] print(type(and_expr)) print(and_expr)
<class 'qat.lang.AQASM.bits.BoolFormula'> (c[0] & c[1])
These objects are used in various pyAQASM instructions.

cbits_list
()¶ Returns the list of cbits appearing in the formula.
 Returns
a list of
Cbit
 Return type
list

to_thrift
()¶ Returns a thrift compatible string representation of the formula.
This method is called in order to produce a seralizable representation of the expression.
 Returns
a string representation of the formula
 Return type
str

Utilities¶
This module contains a few utilitaries

qat.lang.AQASM.util.
suppr_ctrl
(rout, depth=1)¶ Builds a functionally equivalent quantum routine such that no gate in this routine has more that “depth” control qbits. It uses an ancillary register to Toffolifold the control qbits. The number of ancillas to add is (in the worst case) equal to (maximum number of ctrl to remove) 1.

qat.lang.AQASM.util.
toffoli_fold
(nb_qbits)¶ Returns a quantum routine that, given a data register of length \(n\) and an ancilla register, applies Toffoli gates on the data register in order to compute a logical AND of all its qbits inside a single ancillary qbit. May use up to \(n1\) ancillary qbits (worst case scenario). The resulting qbits is always the last qbit (hence of index arity  1).
 Parameters
nb_qbits (int) – the size of the register to fold
 Returns
a quantum routine performing the fold
 Return type
Gate set management and generation¶
This module contains various tools and decorator to turn functions into gates

qat.lang.AQASM.misc.
generate_gate_set
(*args, safe=False)¶ Generates a gate set from a list of various arguments. Arguments can be:
GateSignature/AbstractGates
build_gates wrappers
python modules
In this case it iterates through its scope and gathers all the build_gate objects (i.e all the decorated functions).

class
qat.lang.AQASM.misc.
build_gate
¶ A wrapper class lifting functions into AbstractGates with a circuit implementation.
 Parameters
func (function) – an annotated function returning a QRoutine
Note
Calling the decorated function will return an AbstractGate.
The underlying QRoutine can be referred to by using a tilde before the function:
@build_gate def my_gate(a : int) > 'FOO': rout = QRoutine() return rout my_gate(10) # will return an AbstractGate object, instantiated # with parameter 10 (~my_gate)(10) # will return a QRoutine object