feat: Add logical API to the toy_k2 architecture - #326
PabloAndresCQ wants to merge 4 commits into
Conversation
hsemenenko
left a comment
There was a problem hiding this comment.
Looks good, few minor suggestions.
| @hugr_op(toy_k2_op("measure_z")) | ||
| @no_type_check | ||
| def measure_z(blk: "Block", idx: int) -> QubitMeasurement: | ||
| """Measure the chosen qubit in the Z basis.""" |
There was a problem hiding this comment.
I'm annoyed that I've only just realised that the equivalent Guppy is project_z and perhaps we should have adopted that for non-destructive measurements. Too late now to change I think.
| """Measure the chosen qubit in the Z basis.""" | |
| """Non-destructively measure the chosen qubit in the Z basis.""" |
| This consists of a syndrome extraction followed by discarding of the | ||
| shot if the syndrome is not trivial. |
There was a problem hiding this comment.
Could the discarding happen in decode?
| This consists of a syndrome extraction followed by discarding of the | ||
| shot if the syndrome is not trivial. |
| @guppy | ||
| @no_type_check | ||
| def cx_inter(ctrl_block: Block, ctrl_idx: int, tgt_block: Block, tgt_idx: int) -> None: | ||
| """Logical CX between two blocks, targeting the specified logical qubits. |
There was a problem hiding this comment.
As this architecture is a demonstration, we could add a note to the docstring to highlight that this is an example of a composite logical operation.
| """Logical CX between two blocks, targeting the specified logical qubits. | |
| """Logical CX between two blocks, targeting the specified logical qubits. | |
| Note: | |
| `cx_inter` is not itself a logical primitive of the code, but is instead composed of `swap` and `cx` logical primitives. Therefore, it is defined here rather than with the primitives. |
| # Prepare an ancilla `|0+>` state, with the `|+>` on the index where we want | ||
| # to apply the Hadamard. | ||
| ancilla = Block() # |00> | ||
| h_all(ancilla) # |++> | ||
| # Project the other ancilla logical qubit to |0> | ||
| if measure_z(ancilla, 1 - idx).decode(): | ||
| x(ancilla, idx) |
There was a problem hiding this comment.
This seems like a good place to use _encode_state_non_ft from primitives.
(This comment makes me think that the module naming is incorrect: why is _encode_state_non_ft in a module called primitives if it is not itself a primitive?)
|
|
||
| def test_op_instantiations() -> None: | ||
| ops_extn = toy_k2_ops() | ||
| # No operations take indices |
There was a problem hiding this comment.
Do you mean there are no parametrised ops?
| Normalize()(h, inplace=True) | ||
| InlineFunctions()(h, inplace=True) |
There was a problem hiding this comment.
Run selene_hugr_qis_compiler.check_hugr to validate?
| entrypoint = h.entrypoint | ||
| children = h.children(entrypoint) | ||
| # When https://github.com/Quantinuum/tket2/issues/1691 is implemented, this | ||
| # test will have to change: all the logical ops including `prep_zero` |
There was a problem hiding this comment.
| # test will have to change: all the logical ops including `prep_zero` | |
| # test will have to change: all the logical ops including `prep_zero_ft` |
| pkg = main.compile() | ||
| h = pkg.modules[0] | ||
| Normalize()(h, inplace=True) | ||
| InlineFunctions()(h, inplace=True) |
There was a problem hiding this comment.
Also add a check_hugr here.
| @@ -0,0 +1,403 @@ | |||
| from collections.abc import Callable | |||
There was a problem hiding this comment.
I suggest adding a docstring to the top to explain that this module contains logical primitives of the ToyK2 architecture (including ops comprising other primitives) but does not contain any references to the physical implementations (i.e. guppylang.std.quantum)
891ef56 to
f2b66ff
Compare
54efabd to
158a64f
Compare
158a64f to
c1f6f7d
Compare
Closes #308
Includes enough non-primitive logicals to allow for 1-to-1 replacement of Clifford+T computational programs.
Caveat: the non-primitive logicals (
cx_inter,s_all,s, etc...) have not been tested (beyond a smoke test), since we can't immediately use the Clifford verifier framework on these. We'd need to be able to runimplement_opson functions (rather than executables) and have a way to wire it up with the framework (which does its own generation of physical programs for automated Bell state prep).I will be able to add some sanity checks once I add
implement_opsin a separate PR. These won't be exhaustive, but should give confidence of correctness.Why are these not in
primitives.py?Multiple reasons:
implement_ops.