Open sbrandhsn opened 8 months ago
We have to be careful about changing what's stored inside a Layout
, because the Qubit
instances representing the virtual bits are a fixed part of its public interface, and removing that will cause its current __getitem__
method (and several other methods) to break.
Bits have been able to have no index
and register
for quite some time already, so in theory, many of these problems likely already have some sort parts of solutions in the library - for example, we've largely moved away from using Layout
as an input to transpiler passes (because of the serialisation problems), but it's still used when attached to a QuantumCircuit
as a context object, where serialisation and deserialisation (and copy/deepcopy) have the bit instances to hand to do the remapping.
For point 3, I definitely agree it's got all the information in one place, but the trick to me is that the register information shouldn't be part of any comparison here. Comparing the names of registers (which are just ad-hoc named collections of bits) is something that really only QuantumCircuit
would need to care about, if it decides (as it currently does) that circuits are equal if they have the same named structure to their bits. Duplicating that information in the Layout
effectively ends up in us duplicating checks and restricting the Layout
in ways that the user of Layout
would already have to be validating in other ways anyway - it introduces additional sync between different structures, and I'm not clear that it actually applies a benefit for what a layout is meant to represent.
Point 1 is what (imo) we should do if we were starting the class from afresh; Layout
represents a bi-directional mapping $V \leftrightarrow P$[^1], so all the information it needs to represent this is unique identifiers for virtual qubits and physical qubits. Whether we store the virtual qubit as an index or an tuple[index: int, locs: list[tuple[int, str]]]
depends on how restrictive about accepting representations a Layout
ought to be. Imo, it only makes sense to talk about virtual qubits in the context of a circuit, so then there's no advantage to having Layout
carry the information about circuit structures as well.
[^1]: I have a problem with our current assumption of a bijection on both counts - I don't think we should be requiring either an injection or surjection! - but that's for another time.
What should we add?
When the
Bit
class becomes opaque (see #10996 ), the reference ofQubit
s in a quantum circuit must stay consistent during the execution of the python session. However, we can not guarantee this in all use cases. One example is the parallel execution of transpilation jobs where the user provides an initial layout. In these cases, thepassmanager
is serialized, leading to newQubit
instances and a thus mismatch of reference of the qubits between the quantum circuit to be transpiled and theLayout
in the deserializedpassmanager
.Thus, a refactoring of the
Layout
class is required with three proposal (so far):Bits
fromLayout
and store the permutation only e.g. as a list or dictionary of integers. @levbishopQuantumRegister
whenever aLayout
is initialized and store this information internally.Layout
define the bijection $P \leftrightarrow V$ where $V$ is the set ofBitLocations
.BitLocations
is a tuple $(i, R)$ with $i$ being the index of a bit within its quantum circuit and $R$ being a list of tuples $(r_i, r)$ with a register $r$ and bit index within a register $r_i$I currently prefer proposal 3. as this gives you all information in one place.