|
17 | 17 |
|
18 | 18 | from pytket import Bit, Circuit, OpType, Qubit |
19 | 19 | from pytket.backends.backendresult import BackendResult |
| 20 | +from pytket.circuit import BitRegister |
20 | 21 | from pytket.utils.outcomearray import OutcomeArray |
21 | 22 |
|
22 | 23 | if TYPE_CHECKING: |
@@ -53,7 +54,7 @@ def get_leakage_gadget_circuit( |
53 | 54 | return c |
54 | 55 |
|
55 | 56 |
|
56 | | -def get_detection_circuit(circuit: Circuit, n_device_qubits: int) -> Circuit: # noqa: PLR0912 |
| 57 | +def get_detection_circuit(circuit: Circuit, n_device_qubits: int) -> Circuit: # noqa: PLR0912 PLR0915 |
57 | 58 | """ |
58 | 59 | For a passed circuit, appends a leakage detection circuit for |
59 | 60 | each end of circuit measurement using spare device qubits. |
@@ -89,22 +90,48 @@ def get_detection_circuit(circuit: Circuit, n_device_qubits: int) -> Circuit: # |
89 | 90 | # end of Circuit Measure gates |
90 | 91 | end_circuit_measures: dict[Qubit, Bit] = {} |
91 | 92 | for com in circuit: |
92 | | - if com.op.type == OpType.Barrier: |
93 | | - detection_circuit.add_barrier(com.args) |
| 93 | + op, args = com.op, com.args |
| 94 | + if op.type == OpType.Barrier: |
| 95 | + detection_circuit.add_barrier(args) |
94 | 96 | continue |
95 | 97 | # first check if a mid circuit measure needs to be readded |
96 | 98 | for q in com.qubits: |
97 | 99 | # this condition only true if this Qubit has previously had a |
98 | 100 | # "mid-circuit" measure operation |
99 | 101 | if q in end_circuit_measures: |
100 | 102 | detection_circuit.Measure(q, end_circuit_measures.pop(q)) |
101 | | - if com.op.type == OpType.Measure: |
| 103 | + if op.type == OpType.Measure: |
102 | 104 | # if this is "mid-circuit" then this will be rewritten later |
103 | 105 | end_circuit_measures[com.qubits[0]] = com.bits[0] |
104 | | - elif com.op.params: |
105 | | - detection_circuit.add_gate(com.op.type, com.op.params, com.args) |
| 106 | + elif op.is_gate(): |
| 107 | + detection_circuit.add_gate(op.type, op.params, args) |
| 108 | + elif op.type == OpType.SetBits: |
| 109 | + detection_circuit.add_c_setbits(op.values, args) # type: ignore |
| 110 | + elif op.type == OpType.CopyBits: |
| 111 | + assert len(args) % 2 == 0 |
| 112 | + n = len(args) // 2 |
| 113 | + detection_circuit.add_c_copybits(args[:n], args[n:]) # type: ignore |
| 114 | + elif op.type == OpType.ClExpr: |
| 115 | + detection_circuit.add_clexpr(op.expr, args) # type: ignore |
| 116 | + elif op.type == OpType.RNGSeed: |
| 117 | + creg = BitRegister(args[0].reg_name, 64) |
| 118 | + detection_circuit.set_rng_seed(creg) |
| 119 | + elif op.type == OpType.RNGBound: |
| 120 | + creg = BitRegister(args[0].reg_name, 32) |
| 121 | + detection_circuit.set_rng_bound(creg) |
| 122 | + elif op.type == OpType.RNGIndex: |
| 123 | + creg = BitRegister(args[0].reg_name, 32) |
| 124 | + detection_circuit.set_rng_index(creg) |
| 125 | + elif op.type == OpType.RNGNum: |
| 126 | + creg = BitRegister(args[0].reg_name, 32) |
| 127 | + detection_circuit.get_rng_num(creg) |
| 128 | + elif op.type == OpType.JobShotNum: |
| 129 | + creg = BitRegister(args[0].reg_name, 32) |
| 130 | + detection_circuit.get_job_shot_num(creg) |
106 | 131 | else: |
107 | | - detection_circuit.add_gate(com.op.type, com.args) |
| 132 | + raise ValueError( |
| 133 | + f"Operation type {op.type} not supported in leakage detection circuit." |
| 134 | + ) |
108 | 135 |
|
109 | 136 | # for each entry in end_circuit_measures, we want to add a leakage_gadget_circuit |
110 | 137 | # we try to use each free architecture qubit as few times as possible |
|
0 commit comments