MyQLM provides different tools and approaches to design your own quantum circuits.
The main component is a Python library for building quantum circuits, called PyAQASM (Python + Atos QASM).
The following picture gives an overview of the circuit generation process from the PyAQASM library.
Quantum circuits can be stored under two formats:
in a serialized format (.circ) - it is under this format that circuits are sent to simulation or optimization services, when command-line tools are used
as .aqasm text files (human readable)
Therefore, there are two ways to generate a .circ file from a
Program instance by:
directly generating a
Circuitinstance and serializing it (right path in the figure)
exporting your program to an .aqasm text file (human readable text format), and compiling it using the command-line tool aqasm2circ (left path in the figure)
Since the core of the QLM is purely based on Python, serialization is NOT a mandatory step, and is here only to facilitate advanced applications. Usually the
Circuit objects are directly fed to QPUs via a Python interface (see documentation of qat-core for examples).
If you still need a text format to describe your quantum circuits, please refer to the AQASM section : The AQASM format.
Writing quantum circuits¶
The pyAQASM library (
qat.lang.AQASM) provides a high-level interface to design quantum circuits.
from qat.lang.AQASM import Program my_program = Program()
Allocating qubit and classical registers:¶
Qubit registers are allocated by the Program using the
qbits_reg = my_program.qalloc(10)
Similarly, registers that hold classical bits can be allocated using the
cbits_reg = my_program.calloc(10)
Native gates, controls and daggers¶
The pyAQASM library provides a basic gate set to write your programs. Their names are rather self-explanatory:
Constant gates: X, Y, Z, H, S, T, CNOT, CCNOT, CSIGN, SWAP, SQRTSWAP, ISWAP
Parametrized gates: RX, RY, RZ, PH (phase shift)
(The mathematical definition of these gates is given in The AQASM format.)
These gates can be applied to the qubits from the qubit register:
my_program.apply(CNOT, qbits_reg, qbits_reg) my_program.apply(H, qbits_reg) my_program.apply(RZ(np.pi/2.), qbits_reg
From this initial gate set, one can also build new gates using control and dagger operations:
my_program.apply(PH(np.pi/2).ctrl(), qbits_reg, qbits_reg) my_program.apply(RX(np.pi/4).dag(), qbits_reg)
Of course, controls can be stacked:
By convention, the outermost control qubit is always the first argument in the
# Here qbits_reg is the control qbit: my_program.apply(H.ctrl(), qbits_reg, qbits_reg) # And here, qbits_reg and qbits_reg are the controls: my_program.apply(H.ctrl().ctrl(), qbits_reg, qbits_reg, qbits_reg)
Defining new parametrized gates: Abstract Gates¶
One might want to define new family of gates parametrized by some angle, or even by some vector (think about state preparation for instance). This can be done through the
Your code would look like this:
# A new 1-qbit gate parametrized by 2 angles C = AbstractGate("C", [float, float], arity=1) my_program.apply(C(np.pi/2, np.pi/4), qbits_reg)
Of course, you can also provide a way to generate the matrix corresponding to the gate:
def c_matrix(theta, phi): return np.cos(theta/2) * I - 1j * np.sin(theta/2) * (np.cos(phi) * X + np.sin(phi) * Y) C = AbstractGate("C", [float, float], arity=1, matrix_generator=c_matrix)
The resulting circuit contains the matrix and can be simulated on most of the available simulators in the QLM.
Custom gates are deprecated. Consider using constant valued
AbstractGate instead (defined in
the previous section).
PyAQASM offers the possibility to define your own gates from a matrix. This is done via the
mat = np.array([[-1, 0], [0, 1]]) my_minus_z = CustomGate(mat) my_program.apply(my_minus_z, qbits_reg)
PyAQASM provides a structure to describe subcircuits that can then be used as quantum gates.
This interface is provided by the
Inside these routines, qubits are inexistant: a routine is just a gate, thus it only knows about the incoming/outgoing wires. Wires are referred to using integers. The arity of the routine is updated dynamically depending on the used wires.
my_routine = QRoutine() my_routine.apply(H, 0) my_routine.apply(CNOT, 0, 1) my_program.apply(my_routine, qbits_reg, qbits_reg) # Since QRoutine are Gates, one can control/dagger them my_program.apply(my_routine.ctrl(), qbits_reg[0:3]) my_program.apply(my_routine.dag(), qbtis_reg[0:2])
Program structure supports various instructions:
measure(): measure a qubit during the computation (not to be used for final measurements)
reset(): reset a qubit or classical bit: it consists in measuring the qubit, and applying a bit flip (X gate) if the outcome is 1
cc_apply(): apply a gate conditionally, depending on the state of a classical bit
cbreak(): interrupt the computation depending on a condition on a set of classical bits
Quantum routine librairies¶
Some submodules of the pyAQASM library provide high-level routines or algorithms:
Generating the circuit¶
Once you are satisfied with your
Program, it can be exported to a circuit format that can be simulated. This is done using the
This method has parameters and can be fine-tuned to meet your needs. Please refer to the source code documentation for more information.