A cQASM program (or any piece of computer code for that matter) needs to be compiled in order to be executed by the underlying hardware (or emulator), which is knows as the target
for execution. Compilation requires knowledge of the hardware that is used for the execution, such as information about the topology of the chip (the connections between the qubits), the native gate set (the gate operations that can be directly executed by the hardware), information about the gate durations and various constraints, such as timing constraints, constraints on the parallel execution of operation etc.
Various compilers for Quantum Computers exist, that all operate at different levels of the stack. Some are low level compilers, used for the generation of micro-instructions of the control hadrware or for the definition of microwave pulse envelopes. And some are more high level compilers, used for instance to convert a program written in a higher level of abstraction to lower levels of abstraction, or to decompose multi-qubit operations into single- and two-qubit operations. Examples of such higher level compilers are OpenQL and LibKet. We refer the user to these manuals to find out all details you need to know on compilation of quantum algorithms. Here we will limit ourselves to some basick compilation steps and we will use the OpenQL compiler as a basis.
Generally, the compilation process consists of the following steps:
- mapping;
- routing;
- decomposition;
- optimization;
- scheduling;
- code generation.
How to compile for a given target is known as the compilation strategy. More on compilation strategies can be found in the OpenQL manual.
Mapping
Mapping is the act of changing the qubit indices in the circuit such that the connectivity constraints of the target device are met. For complex circuits, it is not always possible to find a solution that matches with all constraints (or it may be too time-consuming to compute, as this is an NP problem).
Routing
In case mapping does not yield a satisfiable solution, a compiler could for instance insert SWAP gates to route non-nearest-neighbor qubits toward each other. Other solutions, depending on the hardware capabilities, could be to physically move qubits to another location where interactions are possible. Examples of moving qubits are the use of shuttlers in spin qubit systems, or the use of optical tweezers to relocate an atom to another position in neutral atom based quantum computers. Often, but not always, mapping and routing passes are combined into a single pass.
Decomposition
Decomposition is the act of converting gates that cannot be executed using a single instruction in the target gateset into a list of gates that have the same behavior. For example, a SWAP gate may be decomposed into three CNOT gates.
Optimization
Optimization tries to reduce the algorithm to a more compact form. This is particularly relevant after decomposition, as the decomposition rules may lead to sequences of gates that trivially cancel each other out. Other optimizations could be to commute operations (change the order if possible), to create operations which are easier to execute, remove irrelavant operations (such as Rz rotations after initialization of a qubit in the z-basis or just before a measurment of a qubist in the z-basis) or remove rotations which are so small, that they cannot be executed by a backend.
Scheduling
Scheduling is the act of assigning cycle numbers to each gate in a kernel. This can of course be done trivially by assigning monotonously increasing cycle numbers to each gate in the order in which they were written by the user, but this is highly inefficient; instead, heuristics and commutation rules are used to try to find a more optimal solution that makes efficient use of the parallelism provided by the control architecture.
Code generation
Finally, code generation takes the completed program and converts it to the assembly or machine-code format that the architecture-specific tools expect at their input.
Compilation strategy
A strategy consists of a list of passes, along with pass-specific configuration options for each pass. Often, a more optimal compile strategy will have iterations between these passes, as a optmization pass for instance, could lead to a circuit that can be more optimally mapped then the initial mapping.
OpenSquirrel provides default pass lists for the available architectures. You can modify this default strategy using API calls prior to compilation if need be, or you can override the defaults entirely by writing a compiler configuration file.
Using OpenSquirrel together with Quantum Inspire
Using OpenQL and LibKet together with Quantum Inspire
In the current version of Quantum Inspire, LibKet and OpenQl are not integrated with Quantum Inspire. However, both allow compilation of algorithms written in cQASM and compilation to Quantum Inspire targets. Qiskit also provides standard compilation passes which can be used together with the Quantum Inspire plugin for Qiskit. The interested user is referred to these programs to get the most out of Quantum Inspire.
Be aware that Quantum Inspire also has a built-in compilation strategy for each back-end. You can tell Quantum Inspire if you want it to only use specific compilation stages, e.g. when you already have a pre-compiled circuit.