Skip to content

Reconcile qubit and cbit implementations #7470

Open
@daxfohl

Description

@daxfohl

Is your design idea/issue related to a use case or problem? Please explain

Despite the fact that qubits and cbits (measurement keys) are both kinds of bits, they are implemented in very different ways. A couple things that I can think of offhand:

  • Qubits are well-defined, structured objects with name, type, dimension, and so forth. cbits are just strings.
  • When creating operations, Qubits are checked for shape and compatibility with the operation. Cbits have no such checks, and could end up storing different shapes of measurements unintentionally.
  • Qubits are set at the Operation layer; gates don't know about qubits. Cbits are set directly at the Gate layer on measurement gates.
  • Cbits allow distinction between target (measurment_keys) and control (control_keys), which makes commutativity checks easier, whereas qubits do not.

Describe your design idea/issue

It seems like these should be reconciled in some way. There are multiple ways to proceed.

For the first two issues, we could "dumb down" qubits and have them just be numeric indexes rather than structured objects. This would give them more of a performance advantage as mentioned in the "important side note" of #7465. It would also be more in-line with the goal of #3808 for measurement keys. But it might make qudit support clunkier since the index alone doesn't tell you the dimension, so whereas with Qids, creating a shape-mismatched operation would fail, with indexes it wouldn't fail until you added it to a circuit. Maybe that's fine. Alternatively we could "smarten up" cbits and make them roughly equivalent to qubits, containing type, dimension and any other relevant data, and smarten up the Gate.on() method to also accept cbit objects, and do similar compatibility checks on those that it currently does on qubits. More flexibility, but a performance cap due to the dictionary lookups. A third option could be to use dumb indexes for both at the operation or even circuit level, and only use the structured Qids/Cids at the device level (or circuit level), allowing good performance in simulations, but structured integrity checks at the higher levels. Any of these would probably have to be a 2.0 change; maintaining complete backwards compatibility would be a huge challenge and eliminate many of the benefits.

For the third issue, probably the right thing to do is to set cbits (measurement and control keys) at the Operation layer like we do with qubits. The other option would be to eliminate the Operation layer entirely, and just have the Gate base class contain qubits and cbits directly (whether in index or in structured-object form). I generally like having Gate and Operation being distinct (though wish there wasn't an Operation hierarchy per #7465), but it's not strictly necessary. Either of these is also likely too big for a 1.x release, and would fit better in a 2.0.

For the forth issue, it'd be great if gates could support the target and control distinction for qubits like they do for cbits. This kind of overlaps with #7469; rather than protocols, I think it'd be best if both were supported by plain abstract methods/properties on the Gate and Operation classes. At a minimum, it would benefit the commutes protocol because control qubit overlaps don't affect commutativity. This could plausibly be done in a 1.x release.

Note

One place where qubits and cbits currently diverge and should probably continue to do so is that measurement keys have an optional "path", i.e. "scope". This was added to support things like reusable subcircuits and loops. If you think of subcircuits as a call stack, and measurements within subcircuits as allocating a result, then measuring x in subciruit1 stores it as subcircuit1.x, and if within the same main circuit, you have a separate subcircuit that measures an unrelated x, the main circuit stores that as subcircuit2.x, so as to avoid name collisions in the result. Qubits OTOH are persistent resources and aren't "allocated" in the same way. They follow "pass by reference" semantics throughout the circuit, subcircuits, loops, etc. So "path" would never be relevant to qubits.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions