feat: Add HUGR extension for toy_k2 architecture - #321
PabloAndresCQ wants to merge 11 commits into
Conversation
| /// Decode a qubit measurement of a ToyK2 block. | ||
| decode_qubit_measurement, | ||
| /// Decode a block measurement (both qubits) of a ToyK2 block. | ||
| decode_block_measurement, |
There was a problem hiding this comment.
Do you agree this is the right way to go about this? I couldn't think of anything else.
For now, I'm thinking the measurement_logical_qubit_type is just a glorified bool_t under the hood, similarly for the _block_ one being vec![bool_t; 2]. Basically, the decode primitives will be replaced with identity functions for now, since the primitives for measurement currently do call .read() and do the decoding themselves. This should change in the future, but I want to have a full architecture first.
There was a problem hiding this comment.
I'm not sure why but this doesn't feel right, but I also cannot think of another solution. We cannot use the guppylang.std.Measurement type as it will likely cause errors during type replacement. The block measurement is "just" a collection of two qubit measurements, but cannot be treated independently so should not be a tuple of qubit measurements.
We could only have a block measurement type, and then during implementation it gets replaced by a Guppy struct that wraps Option[Measurement]. Only measurements that have been performed would be some. This is likely too complicated for this example but we could consider in the future. More thought needed I think.
There was a problem hiding this comment.
Follow up thought that I don't know if there is a real-world example of - Is it possible that a measurement of an entire k>1 block could fail for only some logical qubits? If yes, the collection of Option[Measurement] would be useful.
There was a problem hiding this comment.
Note that the decoding for QubitMeasurement and for BlockMeasurement are different, see the decode part of measure_z and measure_z_all in primitives.py. Atm these decode_ functions will be trivial ops, but once we upgrade them to do the physical .read() themselves, they'll need to do what measure_z and measure_z_all do after the read, which are completely different.
I'm fairly convinced this is the way. More so now that I've seen with #326 that they can then both be called with the .decode() syntax on the outcome of a measurement: measure_z(block, idx).decode() and measure_z_all(block).decode(). The difference is only for type checking and being explicit in the primitive definition, both things that we want.
Is it possible that a measurement of an entire k>1 block could fail for only some logical qubits?
I have not seen this, and I doubt that'll come up.
There was a problem hiding this comment.
@hsemenenko I'll make the changes you request on #315 now and rebase this branch.
EDIT: done
695a078 to
15a7b52
Compare
c46be8e to
661347a
Compare
hsemenenko
left a comment
There was a problem hiding this comment.
Looks good Pablo. I'm satisfied with the justification to have both measurement types. Just a couple of small edits to fix.
| cx_transversal, | ||
| /// Swap the two logical qubits of a ToyK2 block. | ||
| swap_intra, | ||
| /// Prepare a ToyK2 block with both logical qubits on the |0> state. |
There was a problem hiding this comment.
| /// Prepare a ToyK2 block with both logical qubits on the |0> state. | |
| /// Prepare a ToyK2 block with both logical qubits on the |0>|0> state. |
| @@ -0,0 +1,4 @@ | |||
| //! HUGR extension for the logical operations and types for | |||
| //! the `[[4,2,2]]` C4 QEC code. | |||
There was a problem hiding this comment.
| //! the `[[4,2,2]]` C4 QEC code. | |
| //! the `[[4,2,2]]` ToyK2 QEC code. |
8fa2888 to
462165d
Compare
b9b0795 to
b0331a1
Compare
Closes #244