qibolab icon indicating copy to clipboard operation
qibolab copied to clipboard

Extend sequence creation with circuits

Open alecandido opened this issue 5 months ago • 0 comments

@stavros11 I better investigated, and it was false, it is correct without the self.channels.

My I didn't correctly express during the meeting, but the role of concatenate is to make to concatenated sequence starting altogether, but also as soon as possible. I.e. if a sequence contains multiple pulses starting at the same time, at the beginning of the sequence, they should start at the same time even in the concatenated sequence. On the other hand, if two sequences playing on non-overlapping channels are concatenated, they should start at the same time.

This second behavior could be desired in many cases, since pulses should be able to start in parallel. It is definitely desired in case of pulses (including gates) played on different qubits (or fully separate sets of qubits), but it is not for gates on the same qubit, which should be played in sequence (as in your example https://github.com/qiboteam/qibolab/issues/1003#issuecomment-2320387728). However, the behavior for gates on the same qubit involving completely different channels (like RX and MZ) is enforced by the compiler (as it requires a more advanced concept than the channel, i.e. the Qubit, which is not sufficiently simple to be included at the level of the PulseSequence and plain natives, requiring instead a Circuit).

However, I see the confusion which is generated, and | is not even the best simple, as it suggests juxtaposition (which is now achieved including | self.channels). My proposal is then to keep both: let's keep concatenate, but with a different operator alias (I'd take <<, inspired to C++ streams), and another method, say juxtapose, which is the one implemented in the suggestion, taking instead the | alias.

The last bit would be to add a bit of syntactic sugar for the compiler as well, in order to make it simpler to interleave sequences and circuits. E.g. we could support PulseSequence additions to a wrapped circuit, which in turn will compile the circuit to a pulse sequence, and then perform juxtaposition. A possible example syntax could be:

seq = (NativeCircuit(5, compiler=my_compiler) 
        | q0.RX() 
        | q3.RX12()
        << [("q0/drive", Delay(5))]
        | p03.CNOT()
        << [("q0/drive", Align()), ("q2/drive", Align())]
        + [X(2), X(3), Z(1)]
        | p23.CNOT()
        + [Z(q) for q in range(5)]
        + M(*range(5))
    )

where a wrapped circuit is initialized with a number of qubits and equipped with a compiler, but in practice maintaining internally a PulseSequence, just supporting Circuit additions through compilation (or better, Union[Circuit, Iterable[Gate]], since we just need a queue). We could even expand this objects with further advanced sugar (e.g. @ ("q0/drive", "q2/drive") to align channels, or @ (0, 2, 3) to directly align qubits), since the object will have everything at its disposal.

In any case, I'd fix the low-level interface in this PR (both concatenate and juxtapose, in the hope it will reduce the confusion), including their aliases (since they are just tiny shortcuts), and postpone anything more elaborate to future releases.

Originally posted by @alecandido in https://github.com/qiboteam/qibolab/pull/1026#discussion_r1748025471

concatenate and juxtapose (and their respective aliases) are already in place, the only missing part would be the one related to compilation, as the title says.

alecandido avatar Sep 13 '24 14:09 alecandido