Skip to content

Commit

Permalink
Merge pull request #763 from qiboteam/remove-transpiler-tutorial
Browse files Browse the repository at this point in the history
Remove transpiler-related tutorial
  • Loading branch information
alecandido authored Jan 20, 2024
2 parents 1723585 + c1596a3 commit 0d019bb
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 74 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,8 +128,8 @@ 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.

QASM Execution
--------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
.. _tutorials_transpiler:
.. _tutorials_compiler:

How to modify the transpiler?
=============================
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 transpilers and compiler outlined in the :ref:`main_doc_transpiler` section will be used in this process.
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`.
Expand All @@ -27,10 +27,11 @@ Creating an instance of the backend provides access to these objects:
<class 'qibo.transpiler.pipeline.Passes'>
<class 'qibolab.compilers.compiler.Compiler'>

The transpiler is responsible for transforming the circuit to respect the chip connectivity and native gates,
while the compiler transforms the circuit to the equivalent pulse sequence.
The user can modify these attributes before executing a circuit.
For example:
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

Expand All @@ -50,47 +51,41 @@ For example:
# execute circuit
result = backend.execute_circuit(circuit, nshots=1000)

completely disables the transpilation steps. In this case the circuit will be sent directly to the compiler, to be compiled to a pulse sequence.
Instead of completely disabling, custom transpilation steps can be given:
completely disables the transpilation steps and the circuit is sent directly to the compiler.

.. testcode:: python

from qibolab.backends import QibolabBackend

from qibo.transpiler.unroller import NativeGates, Unroller

backend = QibolabBackend(platform="dummy")
backend.transpiler = Unroller(native_gates=NativeGates.CZ)
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

Now circuits will only be transpiled to native gates, without any connectivity matching steps.
The transpiler used in this example assumes Z, RZ, GPI2 or U3 as the single-qubit native gates, and supports CZ and iSWAP as two-qubit natives.
In this case we restricted the two-qubit gate set to CZ only.
If the circuit to be executed contains gates that are not included in this gate set, they will be transformed to multiple gates from the gate set.
Arbitrary single-qubit gates are typically transformed to U3.
Arbitrary two-qubit gates are transformed to two or three CZ gates following their `universal CNOT decomposition <https://arxiv.org/abs/quant-ph/0307177>`_.
The decomposition of some common gates such as the SWAP and CNOT is hard-coded for efficiency.
import qibo
from qibo import gates
from qibo.models import Circuit
from qibo.backends import GlobalBackend

Multiple transpilation steps can be implemented using the transpiler ``Passes``:
# define circuit
circuit = Circuit(1)
circuit.add(gates.U3(0, 0.1, 0.2, 0.3))
circuit.add(gates.M(0))

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

from qibo.transpiler import Passes
from qibo.transpiler.unroller import NativeGates, Unroller
from qibo.transpiler.star_connectivity import StarConnectivity
# execute circuit
result = circuit(nshots=1000)

backend = QibolabBackend(platform="dummy")
backend.transpiler = Passes(
[
StarConnectivity(middle_qubit=2),
Unroller(native_gates=NativeGates.CZ),
]
)

In this case circuits will first be transpiled to respect the 5-qubit star connectivity, with qubit 2 as the middle qubit. This will potentially add some SWAP gates. Then all gates will be converted to native.
Defining custom compiler rules
==============================

The compiler can be modified similarly, by adding new compilation rules or modifying existing ones.
As explained in :ref:`main_doc_transpiler` section, a rule is a function that accepts a Qibo gate and a Qibolab platform and returns the corresponding pulse sequence implementing this gate.
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:

Expand Down Expand Up @@ -119,7 +114,7 @@ The following example shows how to modify the transpiler and compiler in order t
# the empty dictionary is needed because the X gate does not require any virtual Z-phases

backend = QibolabBackend(platform="dummy")
# disable the transpiler (the default transpiler will attempt to convert X to U3)
# disable the transpiler
backend.transpiler = None
# register the new X rule in the compiler
backend.compiler[gates.X] = x_rule
Expand All @@ -135,29 +130,3 @@ The default set of compiler rules is defined in :py:mod:`qibolab.compilers.defau
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.

In the above examples 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)
2 changes: 1 addition & 1 deletion doc/source/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ In this section we present code examples from basic to advanced features impleme
pulses
circuits
calibration
transpiler
compiler
instrument

0 comments on commit 0d019bb

Please sign in to comment.