qiboteam / qibolab

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

QubitId: drop `str` for internal usage #759

Open alecandido opened 7 months ago

alecandido commented 7 months ago

Since long, we're supporting both int and str for QubitId:

https://github.com/qiboteam/qibolab/blob/7056c84f28a7c0191f26b29f71a505b9c1b4cf9a/src/qibolab/qubits.py#L9-L10

However, this requires a lot of dedicated code to support str usage.

Instead, I would split two different QubitIds types: one for internal usage, and one for external. In particular:

The external one we could even avoid naming, just accept Any (default type when missing), and fail if unhashable. Otherwise, we could use an alias for typing.Hashable.

EDIT: it doesn't have to even hashable, since the outgoing mapping will just be a list[Hashable] (no reason to have non-consecutive non-zero-base ints internally), but if hashable we could cache the inverse one in a dictionary, by doing something like

reverse_index = {name: qubit for qubit, name in enumerate(qubits)}
alecandido commented 3 weeks ago

Currently, the compiler is using its own fix for this: https://github.com/qiboteam/qibolab/blob/7f8e47f58c70db75869de78991fdfe337d1fe8fb/src/qibolab/compilers/compiler.py#L113-L134 i.e. it relies on Platform.get_qubit().

However, on its turn, Platform.get_qubit() adopts a trial and error approach: https://github.com/qiboteam/qibolab/blob/7f8e47f58c70db75869de78991fdfe337d1fe8fb/src/qibolab/platform/platform.py#L337-L340

Instead, we should standardize usage of integer IDs, and always retrieve the names through the parameters. In any case, names are only useful to address the natives (since it is convenient to save their with their full names) and qubits objects (since it is where these names appear, in the platform definition). But if you have access to multiple natives, you should have access to them all (and then you can rely on the order they are saved in there). Similar story for the qubits in the platform.

Long story short: we should always enumerate the qubits internally (drivers and compiler), and translate qubit names immediately during circuits' execution. I.e. we could pre-process gates by translating the names, generating gates' copies with the integers for qubits (in case we want to support string names for qubits in Qibo) or by reading a list with the desired order (as an extra argument to Backend.execute_circuit(), possibly). For sequences, there may be no need, since we are currently directly using the channels' names. Otherwise, another translation may occur, even for direct execute().