qiboteam / qibolab

Quantum hardware module and drivers for Qibo.
https://qibo.science
Apache License 2.0
41 stars 10 forks source link

Compiler rule fails when running Qibo example circuit on Qibolab 0.1.8 #927

Open sorewachigauyo opened 2 weeks ago

sorewachigauyo commented 2 weeks ago

When setting up Qibolab 0.1.8 for the emulator VM, I encountered an issue running a simple Qibo example. I was able to replicate the issue on my own machine

import qibo
from qibo import Circuit, gates

qibo.set_backend("qibolab", platform="default_q0")

c = Circuit(2)
c.add(gates.X(0))

# Add a measurement register on both qubits
c.add(gates.M(0, 1))

# Execute the circuit with the default initial state |00>.
result = c(nshots=100)

which fails with this error

[Qibo 0.2.9|ERROR|2024-07-08 16:10:29]: Compiler rule not available for <class 'qibo.gates.gates.X'>.
Traceback (most recent call last):
  File "C:\Users\pault\Documents\repos\qibolab\src\qibolab\compilers\compiler.py", line 71, in __getitem__
    return self.rules[item]
           ~~~~~~~~~~^^^^^^
KeyError: <class 'qibo.gates.gates.X'>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\pault\Documents\repos\qibo\src\qibo\models\circuit.py", line 1119, in __call__
    return self.execute(initial_state=initial_state, nshots=nshots)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pault\Documents\repos\qibo\src\qibo\models\circuit.py", line 1115, in execute
    return GlobalBackend().execute_circuit(self, initial_state, nshots)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pault\Documents\repos\qibolab\src\qibolab\backends.py", line 100, in execute_circuit
    sequence, measurement_map = self.compiler.compile(circuit, self.platform)
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pault\Documents\repos\qibolab\src\qibolab\compilers\compiler.py", line 156, in compile
    gate_sequence, gate_phases = self._compile_gate(
                                 ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pault\Documents\repos\qibolab\src\qibolab\compilers\compiler.py", line 105, in _compile_gate
    rule = self[gate.__class__]
           ~~~~^^^^^^^^^^^^^^^^
  File "C:\Users\pault\Documents\repos\qibolab\src\qibolab\compilers\compiler.py", line 73, in __getitem__
    raise_error(KeyError, f"Compiler rule not available for {item}.")
  File "C:\Users\pault\Documents\repos\qibo\src\qibo\config.py", line 46, in raise_error
    raise exception(message)
KeyError: "Compiler rule not available for <class 'qibo.gates.gates.X'>."

I also had this issue when using the dummy platform.

alecandido commented 2 weeks ago

This is expected, and even [documented], though the error is not necessarily that helpful.

Qibolab is not transpiling any longer, and you should explicitly transpile using Qibo. The idea to improve the process is to make a transpiler part of the Qibo GlobalBackend (as much as a backend is already part of it), but it has not been done yet. Cf. #883 and #884

So, you are receiving an error because the circuit has not been transpiled, and the compiler does not know about the X gate.

Definitely poor UX, and maybe correspondingly poor docs, for the time being. I'm sorry for that.

stavros11 commented 2 weeks ago

In principle we could add the X gate in the default compiler, since it's pulse representation is quite straighforward (it's exactly the pi-pulse saved in the platform runcard). However, this opens another discussion of which gates are considered as native by default.

Another issue is that some algorithms/routines are affected by how the compilation is done, eg. RB results could be different if X is used and compiled as one or two pulses. This is why we decided to use GPI2 as the only native single qubit gate, since it is always mapped to a single pulse (+ virtual phases) and unlike X it is sufficient to implement any other gate.

alecandido commented 2 weeks ago

Another issue is that some algorithms/routines are affected by how the compilation is done, eg. RB results could be different if X is used and compiled as one or two pulses. This is why we decided to use GPI2 as the only native single qubit gate, since it is always mapped to a single pulse (+ virtual phases) and unlike X it is sufficient to implement any other gate.

Indeed, and that's why I'd keep it like that.

It is true that there is not a unique definition of native gates, but I would keep the minimal universal set. Instead, we could support specialized compilation through compiler extensions, that should already be available (I would not invest much in that right now, but just keep that in mind for the future).