Skip to content

Commit 73b2364

Browse files
authored
Allow slicing to work with address analysis (#374)
This allows slicing to work with the address analysis pass. @liupengy19 ran into this problem with some of his work and @david-pl helped me confirm the issue was not specific to my setup (: Note: the way the tests are written for the address analysis are definitely a bit outdated, I believe once #370 goes through I updated the tests there so it will just be a matter of merging in the new updated stuff
1 parent 95fa7ec commit 73b2364

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

src/bloqade/analysis/address/impls.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,35 @@ def new_ilist(
7373
class PyIndexing(interp.MethodTable):
7474
@interp.impl(py.GetItem)
7575
def getitem(self, interp: AddressAnalysis, frame: interp.Frame, stmt: py.GetItem):
76-
# Integer index into the thing being indexed
77-
idx = interp.get_const_value(int, stmt.index)
76+
77+
# determine if the index is an int constant
78+
# or a slice
79+
hint = stmt.index.hints.get("const")
80+
if hint is None:
81+
return (NotQubit(),)
82+
83+
if isinstance(hint, const.Value):
84+
idx = hint.data
85+
elif isinstance(hint, slice):
86+
idx = hint
87+
else:
88+
return (NotQubit(),)
7889

7990
# The object being indexed into
8091
obj = frame.get(stmt.obj)
8192
# The `data` attributes holds onto other Address types
8293
# so we just extract that here
8394
if isinstance(obj, AddressTuple):
8495
return (obj.data[idx],)
85-
# an AddressReg is guaranteed to just have some sequence
86-
# of integers which is directly pluggable to AddressQubit
96+
# If idx is an integer index into an AddressReg,
97+
# then it's safe to assume a single qubit is being accessed.
98+
# On the other hand, if it's a slice, we return
99+
# a new AddressReg to preserve the new sequence.
87100
elif isinstance(obj, AddressReg):
88-
return (AddressQubit(obj.data[idx]),)
101+
if isinstance(idx, slice):
102+
return (AddressReg(data=obj.data[idx]),)
103+
if isinstance(idx, int):
104+
return (AddressQubit(obj.data[idx]),)
89105
else:
90106
return (NotQubit(),)
91107

test/analysis/address/test_analysis.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from kirin.dialects import py, func, ilist
55

66
from bloqade import qasm2, squin
7+
from bloqade.squin import qubit
78
from bloqade.analysis import address
89

910

@@ -203,6 +204,38 @@ def test_multiple_wire_apply():
203204
assert len(address_wire_parent_qubit_1) == 2
204205

205206

207+
def test_slice():
208+
209+
@squin.kernel
210+
def main():
211+
q = qubit.new(4)
212+
# get the middle qubits out and apply to them
213+
sub_q = q[1:3]
214+
qubit.broadcast(squin.op.x(), sub_q)
215+
# get a single qubit out, do some stuff
216+
single_q = sub_q[0]
217+
qubit.apply(squin.op.h(), single_q)
218+
219+
address_analysis = address.AddressAnalysis(main.dialects)
220+
frame, _ = address_analysis.run_analysis(main, no_raise=False)
221+
222+
address_regs = [
223+
address_reg_type
224+
for address_reg_type in frame.entries.values()
225+
if isinstance(address_reg_type, address.AddressReg)
226+
]
227+
address_qubits = [
228+
address_qubit_type
229+
for address_qubit_type in frame.entries.values()
230+
if isinstance(address_qubit_type, address.AddressQubit)
231+
]
232+
233+
assert address_regs[0] == address.AddressReg(data=range(0, 4))
234+
assert address_regs[1] == address.AddressReg(data=range(1, 3))
235+
236+
assert address_qubits[0] == address.AddressQubit(data=1)
237+
238+
206239
def test_for_loop():
207240
@squin.kernel
208241
def main():

0 commit comments

Comments
 (0)