Skip to content

Commit 12a0591

Browse files
committed
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 2709b00 commit 12a0591

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
@@ -70,19 +70,35 @@ def new_ilist(
7070
class PyIndexing(interp.MethodTable):
7171
@interp.impl(py.GetItem)
7272
def getitem(self, interp: AddressAnalysis, frame: interp.Frame, stmt: py.GetItem):
73-
# Integer index into the thing being indexed
74-
idx = interp.get_const_value(int, stmt.index)
73+
74+
# determine if the index is an int constant
75+
# or a slice
76+
hint = stmt.index.hints.get("const")
77+
if hint is None:
78+
return (NotQubit(),)
79+
80+
if isinstance(hint, const.Value):
81+
idx = hint.data
82+
elif isinstance(hint, slice):
83+
idx = hint
84+
else:
85+
return (NotQubit(),)
7586

7687
# The object being indexed into
7788
obj = frame.get(stmt.obj)
7889
# The `data` attributes holds onto other Address types
7990
# so we just extract that here
8091
if isinstance(obj, AddressTuple):
8192
return (obj.data[idx],)
82-
# an AddressReg is guaranteed to just have some sequence
83-
# of integers which is directly pluggable to AddressQubit
93+
# If idx is an integer index into an AddressReg,
94+
# then it's safe to assume a single qubit is being accessed.
95+
# On the other hand, if it's a slice, we return
96+
# a new AddressReg to preserve the new sequence.
8497
elif isinstance(obj, AddressReg):
85-
return (AddressQubit(obj.data[idx]),)
98+
if isinstance(idx, slice):
99+
return (AddressReg(data=obj.data[idx]),)
100+
if isinstance(idx, int):
101+
return (AddressQubit(obj.data[idx]),)
86102
else:
87103
return (NotQubit(),)
88104

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)