Skip to content

Commit

Permalink
Keep compiler tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
stavros11 committed Jan 19, 2024
1 parent f26a070 commit eb3c401
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 6 deletions.
5 changes: 2 additions & 3 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ circuits on quantum hardware. Qibolab includes:
1. :ref:`Platform API <main_doc_platform>`: support custom allocation of quantum hardware platforms / lab setup.
2. :ref:`Drivers <main_doc_instruments>`: supports commercial and open-source firmware for hardware control.
3. :ref:`Arbitrary pulse API <main_doc_pulses>`: provide a library of custom pulses for execution through instruments.
4. :ref:`Transpiler <main_doc_transpiler>`: compiles quantum circuits into pulse sequences matching chip topology.
5. :ref:`Quantum Circuit Deployment <tutorials_circuits>`: seamlessly deploys quantum circuit models on
quantum hardware.
4. :ref:`Compiler <main_doc_compiler>`: compiles quantum circuits into pulse sequences.
5. :ref:`Quantum Circuit Deployment <tutorials_circuits>`: seamlessly deploys quantum circuit models on quantum hardware.

Components
----------
Expand Down
2 changes: 1 addition & 1 deletion doc/source/main-documentation/qibolab.rst
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ The shape of the values of an integreted acquisition with 2 sweepers will be:
)
shape = (options.nshots, len(sweeper1.values), len(sweeper2.values))

.. _main_doc_transpiler:
.. _main_doc_compiler:

Transpiler and Compiler
-----------------------
Expand Down
4 changes: 2 additions & 2 deletions doc/source/tutorials/circuits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,5 @@ Returns the following plot:
:class: only-dark

.. note::
Executing circuits using the Qibolab backend results to automatic application of the transpilation and compilation pipelines (:ref:`main_doc_transpiler`) which convert the circuit to a pulse sequence that is executed by the given platform.
It is possible to modify these pipelines following the instructions in the :ref:`tutorials_transpiler` example.
Executing circuits using the Qibolab backend results to automatic application of the transpilation and compilation pipelines (:ref:`main_doc_compiler`) which convert the circuit to a pulse sequence that is executed by the given platform.
It is possible to modify these pipelines following the instructions in the :ref:`tutorials_compiler` example.
132 changes: 132 additions & 0 deletions doc/source/tutorials/compiler.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
.. _tutorials_compiler:

How to modify the default circuit transpilation.
================================================

A Qibolab platform can execute pulse sequences.
As shown in :ref:`tutorials_circuits`, Qibo circuits can be executed by invoking the :class:`qibolab.backends.QibolabBackend`, which is the object integrating Qibolab to Qibo.
When a Qibo circuit is executed, the backend will automatically transpile and compile it to a pulse sequence, which will be sent to the platform for execution.
The default transpiler and compiler outlined in the :ref:`main_doc_compiler` section will be used in this process.
In this tutorial we will demonstrate how the user can modify this process for custom applications.

The ``transpiler`` and ``compiler`` objects used when executing a circuit are attributes of :class:`qibolab.backends.QibolabBackend`.
Creating an instance of the backend provides access to these objects:

.. testcode:: python

from qibolab.backends import QibolabBackend

backend = QibolabBackend(platform="dummy")

print(type(backend.transpiler))
print(type(backend.compiler))

.. testoutput:: python
:hide:

<class 'qibo.transpiler.pipeline.Passes'>
<class 'qibolab.compilers.compiler.Compiler'>

The transpiler is responsible for transforming any circuit to one that respects
the chip connectivity and native gates. The compiler then transforms this circuit
to the equivalent pulse sequence.
The user can modify the default transpilation and compilation process by changing
the ``transpiler`` and ``compiler`` attributes of the ``QibolabBackend``.

.. testcode:: python

from qibo import gates
from qibo.models import Circuit
from qibolab.backends import QibolabBackend

# define circuit
circuit = Circuit(1)
circuit.add(gates.U3(0, 0.1, 0.2, 0.3))
circuit.add(gates.M(0))

backend = QibolabBackend(platform="dummy")
# disable the transpiler
backend.transpiler = None

# execute circuit
result = backend.execute_circuit(circuit, nshots=1000)

completely disables the transpilation steps and the circuit is sent directly to the compiler.

In this example, we executed circuits using the backend ``backend.execute_circuit`` method,
unlike the previous example (:ref:`tutorials_circuits`) where circuits were executed directly using ``circuit(nshots=1000)``.
It is possible to perform transpiler and compiler manipulation in both approaches.
When using ``circuit(nshots=1000)``, Qibo is automatically initializing a ``GlobalBackend()`` singleton that is used to execute the circuit.
Therefore the previous manipulations can be done as follows:

.. testcode:: python

import qibo
from qibo import gates
from qibo.models import Circuit
from qibo.backends import GlobalBackend

# define circuit
circuit = Circuit(1)
circuit.add(gates.U3(0, 0.1, 0.2, 0.3))
circuit.add(gates.M(0))

# set backend to qibolab
qibo.set_backend("qibolab", platform="dummy")
# disable the transpiler
GlobalBackend().transpiler = None

# execute circuit
result = circuit(nshots=1000)


Defining custom compiler rules
==============================

The compiler can be modified by adding new compilation rules or changing existing ones.
As explained in :ref:`main_doc_compiler` section, a rule is a function that accepts a Qibo gate and a Qibolab platform
and returns the pulse sequence implementing this gate.

The following example shows how to modify the transpiler and compiler in order to execute a circuit containing a Pauli X gate using a single pi-pulse:

.. testcode:: python

from qibo import gates
from qibo.models import Circuit
from qibolab.backends import QibolabBackend
from qibolab.pulses import PulseSequence

# define the circuit
circuit = Circuit(1)
circuit.add(gates.X(0))
circuit.add(gates.M(0))


# define a compiler rule that translates X to the pi-pulse
def x_rule(gate, platform):
"""X gate applied with a single pi-pulse."""
qubit = gate.target_qubits[0]
sequence = PulseSequence()
sequence.add(platform.create_RX_pulse(qubit, start=0))
return sequence, {}


# the empty dictionary is needed because the X gate does not require any virtual Z-phases

backend = QibolabBackend(platform="dummy")
# disable the transpiler
backend.transpiler = None
# register the new X rule in the compiler
backend.compiler[gates.X] = x_rule

# execute the circuit
result = backend.execute_circuit(circuit, nshots=1000)

Here we completely disabled the transpiler to avoid transforming the X gate to a different gate and we added a rule that instructs the compiler how to transform the X gate.

The default set of compiler rules is defined in :py:mod:`qibolab.compilers.default`.

.. note::
If the compiler receives a circuit that contains a gate for which it has no rule, an error will be raised.
This means that the native gate set that the transpiler uses, should be compatible with the available compiler rules.
If the transpiler is disabled, a rule should be available for all gates in the original circuit.
1 change: 1 addition & 0 deletions doc/source/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ In this section we present code examples from basic to advanced features impleme
pulses
circuits
calibration
compiler
instrument

0 comments on commit eb3c401

Please sign in to comment.