Skip to content

Commit a35fb61

Browse files
committed
Properly check for atom loss in apply methods
1 parent d298078 commit a35fb61

File tree

2 files changed

+58
-24
lines changed

2 files changed

+58
-24
lines changed

src/bloqade/pyqrack/squin/qubit.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@ def new(self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: qubit.New):
2727
@interp.impl(qubit.Apply)
2828
def apply(self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: qubit.Apply):
2929
qubits: ilist.IList[PyQrackQubit, Any] = frame.get(stmt.qubits)
30-
31-
for qbit in qubits:
32-
if not qbit.is_active():
33-
return ()
34-
3530
operator: OperatorRuntimeABC = frame.get(stmt.operator)
3631
operator.apply(*qubits)
3732

src/bloqade/pyqrack/squin/runtime.py

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,14 @@ def apply(self, qubit: PyQrackQubit, adjoint: bool = False) -> None:
5555
getattr(qubit.sim_reg, method_name)(qubit.addr)
5656

5757
def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
58-
ctrls = [qbit.addr for qbit in qubits[:-1]]
5958
target = qubits[-1]
59+
if not target.is_active():
60+
return
61+
62+
ctrls = [qbit.addr for qbit in qubits[:-1] if qbit.is_active()]
63+
if len(ctrls) == 0:
64+
return
65+
6066
method_name = self.get_method_name(adjoint=adjoint, control=True)
6167
getattr(target.sim_reg, method_name)(ctrls, target.addr)
6268

@@ -77,13 +83,19 @@ def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
7783
class ProjectorRuntime(OperatorRuntimeABC):
7884
to_state: bool
7985

80-
def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
81-
qubits[-1].sim_reg.force_m(qubits[-1].addr, self.to_state)
86+
def apply(self, qubit: PyQrackQubit, adjoint: bool = False) -> None:
87+
if not qubit.is_active():
88+
return
89+
qubit.sim_reg.force_m(qubit.addr, self.to_state)
8290

8391
def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
84-
m = [not self.to_state, 0, 0, self.to_state]
8592
target = qubits[-1]
93+
if not target.is_active():
94+
return
95+
8696
ctrls = [qbit.addr for qbit in qubits[:-1]]
97+
98+
m = [not self.to_state, 0, 0, self.to_state]
8799
target.sim_reg.mcmtrx(ctrls, m, target.addr)
88100

89101

@@ -155,9 +167,11 @@ def mat(self, adjoint: bool):
155167
return [self.factor, 0, 0, self.factor]
156168

157169
def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
158-
self.op.apply(*qubits, adjoint=adjoint)
159-
160170
target = qubits[-1]
171+
if not target.is_active():
172+
return
173+
174+
self.op.apply(*qubits, adjoint=adjoint)
161175

162176
# NOTE: just factor * eye(2)
163177
m = self.mat(adjoint)
@@ -166,13 +180,16 @@ def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
166180
target.sim_reg.mtrx(m, target.addr)
167181

168182
def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
169-
self.op.control_apply(*qubits, adjoint=adjoint)
170-
171183
target = qubits[-1]
172-
ctrls = [qbit.addr for qbit in qubits[:-1]]
184+
if not target.is_active():
185+
return
173186

174-
m = self.mat(adjoint=adjoint)
187+
ctrls = [qbit.addr for qbit in qubits[:-1] if qbit.is_active()]
188+
if len(ctrls) == 0:
189+
return
175190

191+
self.op.control_apply(*qubits, adjoint=adjoint)
192+
m = self.mat(adjoint=adjoint)
176193
target.sim_reg.mcmtrx(ctrls, m, target.addr)
177194

178195

@@ -183,15 +200,22 @@ def mat(self, adjoint: bool) -> list[complex]:
183200

184201
def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
185202
target = qubits[-1]
203+
if not target.is_active():
204+
return
205+
186206
m = self.mat(adjoint=adjoint)
187207
target.sim_reg.mtrx(m, target.addr)
188208

189209
def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
190210
target = qubits[-1]
191-
ctrls = [qbit.addr for qbit in qubits[:-1]]
211+
if not target.is_active():
212+
return
192213

193-
m = self.mat(adjoint=adjoint)
214+
ctrls = [qbit.addr for qbit in qubits[:-1] if qbit.is_active()]
215+
if len(ctrls) == 0:
216+
return
194217

218+
m = self.mat(adjoint=adjoint)
195219
target.sim_reg.mcmtrx(ctrls, m, target.addr)
196220

197221

@@ -251,19 +275,25 @@ def __post_init__(self):
251275
object.__setattr__(self, "pyqrack_axis", axis)
252276

253277
def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
254-
sign = (-1) ** adjoint
255-
angle = sign * self.angle
256278
target = qubits[-1]
279+
if not target.is_active():
280+
return
257281

282+
sign = (-1) ** adjoint
283+
angle = sign * self.angle
258284
target.sim_reg.r(self.pyqrack_axis, angle, target.addr)
259285

260286
def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
261-
sign = (-1) ** (not adjoint)
262-
angle = sign * self.angle
263-
264-
ctrls = [qbit.addr for qbit in qubits[:-1]]
265287
target = qubits[-1]
288+
if not target.is_active():
289+
return
290+
291+
ctrls = [qbit.addr for qbit in qubits[:-1] if qbit.is_active()]
292+
if len(ctrls) == 0:
293+
return
266294

295+
sign = (-1) ** (not adjoint)
296+
angle = sign * self.angle
267297
target.sim_reg.mcr(self.pyqrack_axis, angle, ctrls, target.addr)
268298

269299

@@ -293,12 +323,21 @@ def angles(self, adjoint: bool) -> tuple[float, float, float]:
293323

294324
def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
295325
target = qubits[-1]
326+
if not target.is_active():
327+
return
328+
296329
angles = self.angles(adjoint=adjoint)
297330
target.sim_reg.u(target.addr, *angles)
298331

299332
def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
300333
target = qubits[-1]
301-
ctrls = [qbit.addr for qbit in qubits[:-1]]
334+
if not target.is_active():
335+
return
336+
337+
ctrls = [qbit.addr for qbit in qubits[:-1] if qbit.is_active()]
338+
if len(ctrls) == 0:
339+
return
340+
302341
angles = self.angles(adjoint=adjoint)
303342
target.sim_reg.mcu(ctrls, target.addr, *angles)
304343

0 commit comments

Comments
 (0)