Open dorisraeli opened 2 years ago
I think the main inconsistency is that barrier
is variadic, while reset
isn't. All the others are quite natural, to me at least:
gphase
applies to zero qubits on its own, but it's like a gate and can take modifiers like ctrl
, which increase the number of operandsreset
, barrier
and measure
are all instructions, but look kind of like gate calls. I don't think it's inconsistent for them to have fixed numbers of operands, and since they can't have modifiers attached, the reference AST can represent them in a fixed form.Personally I'd have thought "implementation-aware improvements" like grouping measures should be handled by those specific implementations' compilers. The sequential measure
statements should contain the same information and the spec allows reordering of instructions. We have the barrier
statement that means "don't re-order these instructions", so it's not 100% clear to me why we'd need a second explicit form for that. That said, I'm very aware that it's easier for implementations if the intent is spelled out by the programmer.
Perhaps this is a course of action that keeps everyone happy:
barrier
and make it take exactly one argument - we already have broadcasting over registers to represent variadicitymeasure
to also operate on registers (as opposed to single qubits), with an evaluated type of bit[n]
{q[0], q[3], q[7]}
and ++
-concatenation) to be used in quantum-instruction contexts to create "alias literals" without being bound to a name. The rules about needing to be a compile-time constant would be the same as let
statements (currently they aren't spelled out, though).I haven't thought through all the ramifications of that (it could be slightly confusing with regard to arrays, perhaps?), but something like it could be a way to enforce the idea of "quantum instructions all have a fixed number of operands, but broadcast over registers", which is good for consistency, while allowing more ad-hoc groupings of qubits and bits.
That would mean that instead of barrier q0, q1;
, we'd have barrier {q0, q1};
and reset {q0, q1};
, but then it'd go further. The following operations are all logically already valid OpenQASM 3 statements:
qubit[10] q;
bit[10] c;
reset {q[0], q[7]};
barrier q[0:2] ++ q[4:6];
CX {q[5], q[3]}, {q[1], q[2]};
it's just that the user has to manually write
let _temp_0 = {q[0], q[7]};
let _temp_1 = q[0:2] ++ q[4:6];
let _temp_2 = {q[5], q[3]};
let _temp_3 = {q[1], q[2]};
reset _temp_0;
barrier _temp_1;
CX _temp_2, _temp_3;
The new syntax for I'm suggesting for these particular operations is just sugar that pushes this mechanical transformation onto the compilers rather than the programmers.
The new part of the steps I had above is the overload of measure
to allow it to operate on registers instead of only bits, for example as
measure {q[6], q[8]} -> c[0:1];
{c[1], c[4]} = measure {q[4], q[9]};
This is a much more contentious point as the spec stands right now, because the type of alias expressions and the assignment semantics between them aren't currently defined. That would need some careful consideration, but I think we could work together to make something consistent if it'll enhance OpenQASM 3's usability for real-world applications in the near term.
What is the expected behavior?
Currently, the allowed behavior of gates, phases, and barriers is different than resets and measurements; One can apply a gate/phase/barrier on a list of singular qubits or quantum registers but can only reset or measure a singular qubit or a single quantum register. This is also apparent in the AST:
List[Union[IndexedIdentifier, Identifier]]
vs.Union[IndexedIdentifier, Identifier]
.This feature request proposes that resets and measurements will also accept a list of qubits or quantum registers, as in:
measure q1, q7, myQubits;
,reset q1, q7, myQubits;
.This will: