diff --git a/src/bloqade/cirq_utils/emit/base.py b/src/bloqade/cirq_utils/emit/base.py index 51956611..adf18ebd 100644 --- a/src/bloqade/cirq_utils/emit/base.py +++ b/src/bloqade/cirq_utils/emit/base.py @@ -28,7 +28,7 @@ def emit_circuit( Keyword Args: circuit_qubits (Sequence[cirq.Qid] | None): A list of qubits to use as the qubits in the circuit. Defaults to None. - If this is None, then `cirq.LineQubit`s are inserted for every `squin.qubit.new` + If this is None, then `cirq.LineQubit`s are inserted for every `squin.qalloc` statement in the order they appear inside the kernel. **Note**: If a list of qubits is provided, make sure that there is a sufficient number of qubits for the resulting circuit. @@ -48,7 +48,7 @@ def emit_circuit( @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.h(q[0]) squin.cx(q[0], q[1]) @@ -74,8 +74,10 @@ def entangle(q: ilist.IList[squin.qubit.Qubit, Literal[2]]): @squin.kernel def main(): - q = squin.qubit.new(2) - entangle(q) + q = squin.qalloc(2) + q2 = squin.qalloc(3) + squin.cx(q[1], q2[2]) + # custom list of qubits on grid qubits = [cirq.GridQubit(i, i+1) for i in range(5)] diff --git a/src/bloqade/cirq_utils/emit/qubit.py b/src/bloqade/cirq_utils/emit/qubit.py index 47d736ab..3cbd8f7f 100644 --- a/src/bloqade/cirq_utils/emit/qubit.py +++ b/src/bloqade/cirq_utils/emit/qubit.py @@ -11,19 +11,15 @@ class EmitCirqQubitMethods(MethodTable): @impl(qubit.New) def new(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.New): - n_qubits = frame.get(stmt.n_qubits) if frame.qubits is not None: - cirq_qubits = tuple( - frame.qubits[i + frame.qubit_index] for i in range(n_qubits) - ) + cirq_qubit = frame.qubits[frame.qubit_index] else: - cirq_qubits = tuple( - cirq.LineQubit(i + frame.qubit_index) for i in range(n_qubits) - ) + cirq_qubit = cirq.LineQubit(frame.qubit_index) - frame.qubit_index += n_qubits - return (cirq_qubits,) + frame.has_allocations = True + frame.qubit_index += 1 + return (cirq_qubit,) @impl(qubit.Apply) def apply(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.Apply): diff --git a/src/bloqade/cirq_utils/lowering.py b/src/bloqade/cirq_utils/lowering.py index aa14bd03..dab98b51 100644 --- a/src/bloqade/cirq_utils/lowering.py +++ b/src/bloqade/cirq_utils/lowering.py @@ -6,7 +6,7 @@ from kirin.rewrite import Walk, CFGCompactify from kirin.dialects import py, scf, func, ilist -from bloqade.squin import gate, noise, qubit, kernel +from bloqade.squin import gate, noise, qubit, kernel, qalloc def load_circuit( @@ -92,7 +92,7 @@ def load_circuit( @squin.kernel def main(): qreg = get_entangled_qubits() - qreg2 = squin.qubit.new(1) + qreg2 = squin.qalloc(1) entangle_qubits([qreg[1], qreg2[0]]) return squin.qubit.measure(qreg2) ``` @@ -254,7 +254,9 @@ def run( # NOTE: create a new register of appropriate size n_qubits = len(self.qreg_index) n = frame.push(py.Constant(n_qubits)) - self.qreg = frame.push(qubit.New(n_qubits=n.result)).result + self.qreg = frame.push( + func.Invoke((n.result,), callee=qalloc, kwargs=()) + ).result self.visit(state, stmt) diff --git a/src/bloqade/pyqrack/squin/qubit.py b/src/bloqade/pyqrack/squin/qubit.py index 1e2933b3..d49660c3 100644 --- a/src/bloqade/pyqrack/squin/qubit.py +++ b/src/bloqade/pyqrack/squin/qubit.py @@ -13,15 +13,12 @@ @qubit.dialect.register(key="pyqrack") class PyQrackMethods(interp.MethodTable): @interp.impl(qubit.New) - def new(self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: qubit.New): - n_qubits: int = frame.get(stmt.n_qubits) - qreg = ilist.IList( - [ - PyQrackQubit(i, interp.memory.sim_reg, QubitState.Active) - for i in interp.memory.allocate(n_qubits=n_qubits) - ] - ) - return (qreg,) + def new_qubit( + self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: qubit.New + ): + (addr,) = interp.memory.allocate(1) + qb = PyQrackQubit(addr, interp.memory.sim_reg, QubitState.Active) + return (qb,) @interp.impl(qubit.Apply) def apply(self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: qubit.Apply): diff --git a/src/bloqade/squin/__init__.py b/src/bloqade/squin/__init__.py index c1febe37..5c700efd 100644 --- a/src/bloqade/squin/__init__.py +++ b/src/bloqade/squin/__init__.py @@ -6,9 +6,9 @@ qubit as qubit, analysis as analysis, lowering as lowering, - _typeinfer as _typeinfer, ) from .groups import wired as wired, kernel as kernel +from .stdlib.qubit import qalloc as qalloc from .stdlib.simple import ( h as h, s as s, diff --git a/src/bloqade/squin/_typeinfer.py b/src/bloqade/squin/_typeinfer.py deleted file mode 100644 index b1055ef3..00000000 --- a/src/bloqade/squin/_typeinfer.py +++ /dev/null @@ -1,20 +0,0 @@ -from kirin import types, interp -from kirin.analysis import TypeInference, const -from kirin.dialects import ilist - -from bloqade import squin - - -@squin.qubit.dialect.register(key="typeinfer") -class TypeInfer(interp.MethodTable): - @interp.impl(squin.qubit.New) - def _call(self, interp: TypeInference, frame: interp.Frame, stmt: squin.qubit.New): - # based on Xiu-zhe (Roger) Luo's get_const_value function - - if (hint := stmt.n_qubits.hints.get("const")) is None: - return (ilist.IListType[squin.qubit.QubitType, types.Any],) - - if isinstance(hint, const.Value) and isinstance(hint.data, int): - return (ilist.IListType[squin.qubit.QubitType, types.Literal(hint.data)],) - - return (ilist.IListType[squin.qubit.QubitType, types.Any],) diff --git a/src/bloqade/squin/analysis/address_impl.py b/src/bloqade/squin/analysis/address_impl.py index e54900cb..787914b7 100644 --- a/src/bloqade/squin/analysis/address_impl.py +++ b/src/bloqade/squin/analysis/address_impl.py @@ -3,7 +3,6 @@ from bloqade.analysis.address.lattice import ( Address, - AddressReg, AddressWire, AddressQubit, ) @@ -57,15 +56,13 @@ def apply( @qubit.dialect.register(key="qubit.address") class SquinQubitMethodTable(interp.MethodTable): - # This can be treated like a QRegNew impl @interp.impl(qubit.New) - def new( + def new_qubit( self, interp_: AddressAnalysis, frame: ForwardFrame[Address], stmt: qubit.New, ): - n_qubits = interp_.get_const_value(int, stmt.n_qubits) - addr = AddressReg(range(interp_.next_address, interp_.next_address + n_qubits)) - interp_.next_address += n_qubits + addr = AddressQubit(interp_.next_address) + interp_.next_address += 1 return (addr,) diff --git a/src/bloqade/squin/groups.py b/src/bloqade/squin/groups.py index 971229d9..ee7cb212 100644 --- a/src/bloqade/squin/groups.py +++ b/src/bloqade/squin/groups.py @@ -24,7 +24,7 @@ def run_pass(method: ir.Method, *, fold=True, typeinfer=True): py_mult_to_mult_pass(method) if typeinfer: - typeinfer_pass(method) + typeinfer_pass(method) # infer types before desugaring desugar_pass.rewrite(method.code) ilist_desugar_pass(method) @@ -32,6 +32,7 @@ def run_pass(method: ir.Method, *, fold=True, typeinfer=True): if typeinfer: typeinfer_pass(method) # fix types after desugaring method.verify_type() + # method.print() return run_pass diff --git a/src/bloqade/squin/qubit.py b/src/bloqade/squin/qubit.py index 1faa74fd..7d2917c2 100644 --- a/src/bloqade/squin/qubit.py +++ b/src/bloqade/squin/qubit.py @@ -25,8 +25,7 @@ @statement(dialect=dialect) class New(ir.Statement): traits = frozenset({lowering.FromPythonCall()}) - n_qubits: ir.SSAValue = info.argument(types.Int) - result: ir.ResultValue = info.result(ilist.IListType[QubitType, types.Any]) + result: ir.ResultValue = info.result(QubitType) @statement(dialect=dialect) @@ -94,14 +93,11 @@ class MeasurementId(ir.Statement): # NOTE: no dependent types in Python, so we have to mark it Any... @wraps(New) -def new(n_qubits: int) -> ilist.IList[Qubit, Any]: - """Create a new list of qubits. - - Args: - n_qubits(int): The number of qubits to create. +def new() -> Qubit: + """Create a new qubit. Returns: - (ilist.IList[Qubit, n_qubits]) A list of qubits. + Qubit: A new qubit. """ ... @@ -164,8 +160,8 @@ def broadcast(operator: Op, *qubits: ilist.IList[Qubit, OpSize] | list[Qubit]) - @squin.kernel def ghz(): - controls = squin.qubit.new(4) - targets = squin.qubit.new(4) + controls = squin.qalloc(4) + targets = squin.qalloc(4) h = squin.op.h() squin.qubit.broadcast(h, controls) diff --git a/src/bloqade/squin/stdlib/qubit.py b/src/bloqade/squin/stdlib/qubit.py new file mode 100644 index 00000000..d826b82b --- /dev/null +++ b/src/bloqade/squin/stdlib/qubit.py @@ -0,0 +1,25 @@ +from typing import Any + +from kirin.dialects import ilist + +from .. import qubit, kernel + + +@kernel(typeinfer=True) +def qalloc(n_qubits: int) -> ilist.IList[qubit.Qubit, Any]: + """Allocate a new list of qubits. + + Args: + n_qubits(int): The number of qubits to create. + + Returns: + (ilist.IList[Qubit, n_qubits]) A list of qubits. + """ + + def _new(qid: int) -> qubit.Qubit: + return qubit.new() + + return ilist.map(_new, ilist.range(n_qubits)) + + +qalloc.print() diff --git a/test/analysis/address/test_qubit_analysis.py b/test/analysis/address/test_qubit_analysis.py index b61afc51..e63917b3 100644 --- a/test/analysis/address/test_qubit_analysis.py +++ b/test/analysis/address/test_qubit_analysis.py @@ -1,7 +1,7 @@ import pytest from util import collect_address_types -from bloqade.squin import op, qubit, kernel +from bloqade.squin import op, qubit, kernel, qalloc from bloqade.analysis import address # test tuple and indexing @@ -11,8 +11,8 @@ def test_tuple_address(): @kernel def test(): - q1 = qubit.new(5) - q2 = qubit.new(10) + q1 = qalloc(5) + q2 = qalloc(10) qubit.broadcast(op.y(), q1) qubit.apply(op.x(), q2[2]) # desugar creates a new ilist here # natural to expect two AddressTuple types @@ -37,7 +37,7 @@ def test_get_item(): @kernel def test(): - q = qubit.new(5) + q = qalloc(5) qubit.broadcast(op.y(), q) x = (q[0], q[3]) # -> AddressTuple(AddressQubit, AddressQubit) y = q[2] # getitem on ilist # -> AddressQubit @@ -66,7 +66,7 @@ def extract_qubits(qubits): @kernel def test(): - q = qubit.new(5) + q = qalloc(5) qubit.broadcast(op.y(), q) return extract_qubits(q) @@ -84,7 +84,7 @@ def test_slice(): @kernel def main(): - q = qubit.new(4) + q = qalloc(4) # get the middle qubits out and apply to them sub_q = q[1:3] qubit.broadcast(op.x(), sub_q) @@ -117,7 +117,7 @@ def main(): def test_for_loop_idx(): @kernel def main(): - q = qubit.new(3) + q = qalloc(3) x = op.x() for i in range(3): qubit.apply(x, [q[i]]) @@ -126,3 +126,26 @@ def main(): address_analysis = address.AddressAnalysis(main.dialects) address_analysis.run_analysis(main, no_raise=False) + + +def test_new_qubit(): + @kernel + def main(): + return qalloc() + + address_analysis = address.AddressAnalysis(main.dialects) + _, result = address_analysis.run_analysis(main, no_raise=False) + assert result == address.AddressQubit(0) + + +@pytest.mark.xfail # fails due to ilist.map not being handled correctly +def test_new_stdlib(): + @kernel + def main(): + return qalloc(10) + + address_analysis = address.AddressAnalysis(main.dialects) + _, result = address_analysis.run_analysis(main, no_raise=False) + assert ( + result == address.AnyAddress() + ) # TODO: should be AddressTuple with AddressQubits diff --git a/test/analysis/address/test_wire_analysis.py b/test/analysis/address/test_wire_analysis.py deleted file mode 100644 index 8b492a85..00000000 --- a/test/analysis/address/test_wire_analysis.py +++ /dev/null @@ -1,253 +0,0 @@ -from util import collect_address_types -from kirin import ir, types -from kirin.passes import Fold -from kirin.dialects import py, func, ilist - -from bloqade import squin -from bloqade.analysis import address - - -def as_int(value: int): - return py.constant.Constant(value=value) - - -squin_qubit_with_wire = squin.groups.wired.add(squin.qubit) - - -def build_method(stmts, dialects, output_type): - block = ir.Block(stmts) - block.args.append_from(types.MethodType[[], types.NoneType], "main_self") - func_wrapper = func.Function( - sym_name="main", - signature=func.Signature(inputs=(), output=output_type), - body=ir.Region(blocks=block), - ) - return ir.Method( - mod=None, - py_func=None, - sym_name="main", - dialects=dialects, - code=func_wrapper, - arg_names=[], - ) - - -def run_fold_and_address_analysis(method): - fold_pass = Fold(method.dialects) - fold_pass(method) - frame, _ = address.AddressAnalysis(method.dialects).run_analysis( - method, no_raise=False - ) - return frame - - -def test_unwrap(): - - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(2)), - (qreg := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - ( - q1 := py.GetItem( - index=idx0.result, - obj=qreg.result, - ) - ), - (idx1 := as_int(1)), - ( - q2 := py.GetItem( - index=idx1.result, - obj=qreg.result, - ) - ), - # Unwrap to get wires - (w1 := squin.wire.Unwrap(qubit=q1.result)), - (w2 := squin.wire.Unwrap(qubit=q2.result)), - # Put them in an ilist and return to prevent elimination - (wire_list := ilist.New([w1.result, w2.result])), - (func.Return(wire_list)), - ] - - method = build_method(stmts, squin_qubit_with_wire, ilist.IListType) - frame = run_fold_and_address_analysis(method) - address_wires = collect_address_types(frame, address.AddressWire) - - # 2 AddressWires should be produced from the Analysis - assert len(address_wires) == 2 - # The AddressWires should have qubits 0 and 1 as their parents - for qubit_idx, address_wire in enumerate(address_wires): - assert qubit_idx == address_wire.origin_qubit.data - - -## test unwrap + pass through single statements -def test_multiple_unwrap(): - - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(2)), - (qreg := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.GetItem(index=idx0.result, obj=qreg.result)), - (idx1 := as_int(1)), - (q1 := py.GetItem(index=idx1.result, obj=qreg.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - # pass the wires through some 1 Qubit operators - (op1 := squin.op.stmts.T()), - (op2 := squin.op.stmts.H()), - (op3 := squin.op.stmts.X()), - (v0 := squin.wire.Apply(op1.result, w0.result)), - (v1 := squin.wire.Apply(op2.result, v0.results[0])), - (v2 := squin.wire.Apply(op3.result, w1.result)), - (wire_list := ilist.New([v1.results[0], v2.results[0]])), - (func.Return(wire_list)), - ] - - method = build_method(stmts, squin_qubit_with_wire, ilist.IListType) - frame = run_fold_and_address_analysis(method) - - address_wire_parent_qubit_0 = [] - address_wire_parent_qubit_1 = [] - for address_type in collect_address_types(frame, address.AddressWire): - if address_type.origin_qubit.data == 0: - address_wire_parent_qubit_0.append(address_type) - elif address_type.origin_qubit.data == 1: - address_wire_parent_qubit_1.append(address_type) - - # there should be 3 AddressWire instances with parent qubit 0 - # and 2 AddressWire instances with parent qubit 1 - assert len(address_wire_parent_qubit_0) == 3 - assert len(address_wire_parent_qubit_1) == 2 - - -def test_multiple_wire_apply(): - - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(2)), - (qreg := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.GetItem(index=idx0.result, obj=qreg.result)), - (idx1 := as_int(1)), - (q1 := py.GetItem(index=idx1.result, obj=qreg.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - # Put the wires through a 2Q operator - (op1 := squin.op.stmts.X()), - (op2 := squin.op.stmts.Control(op1.result, n_controls=1)), - (apply_stmt := squin.wire.Apply(op2.result, w0.result, w1.result)), - # Inside constant prop, in eval_statement in the forward data analysis, - # Apply is marked as pure so frame.get_values(SSAValues) -> ValueType (where) - (wire_list := ilist.New([apply_stmt.results[0], apply_stmt.results[1]])), - (func.Return(wire_list.result)), - ] - - method = build_method(stmts, squin_qubit_with_wire, ilist.IListType) - frame = run_fold_and_address_analysis(method) - - address_wire_parent_qubit_0 = [] - address_wire_parent_qubit_1 = [] - for address_type in collect_address_types(frame, address.AddressWire): - if address_type.origin_qubit.data == 0: - address_wire_parent_qubit_0.append(address_type) - elif address_type.origin_qubit.data == 1: - address_wire_parent_qubit_1.append(address_type) - - # Should be 2 AddressWire instances with origin qubit 0 - # and another 2 with origin qubit 1 - assert len(address_wire_parent_qubit_0) == 2 - assert len(address_wire_parent_qubit_1) == 2 - - -def test_tuple(): - - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(2)), - (qreg := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.GetItem(index=idx0.result, obj=qreg.result)), - (idx1 := as_int(1)), - (q1 := py.GetItem(index=idx1.result, obj=qreg.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - # Put them in an tuple and return to prevent elimination - (wire_tuple := py.tuple.New((w0.result, w1.result))), - (func.Return(wire_tuple.result)), - ] - - method = build_method( - stmts, - squin_qubit_with_wire, - types.Generic(tuple, squin.wire.WireType, squin.wire.WireType), - ) - frame = run_fold_and_address_analysis(method) - - method.print(analysis=frame.entries) - - address_wires = collect_address_types(frame, address.AddressTuple) - assert address_wires[0] == address.AddressTuple( - data=( - address.AddressWire(origin_qubit=address.AddressQubit(0)), - address.AddressWire(origin_qubit=address.AddressQubit(1)), - ) - ) - - -def test_get_item(): - - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(2)), - (qreg := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.GetItem(index=idx0.result, obj=qreg.result)), - (idx1 := as_int(1)), - (q1 := py.GetItem(index=idx1.result, obj=qreg.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - # Put them in a list - (wire_list := ilist.New([w0.result, w1.result])), - # create another list just to store the results of the getitems, - # then return to prevent elimination - (get_item_idx := as_int(0)), - ( - get_item_0 := py.GetItem(index=get_item_idx.result, obj=wire_list.result) - ), # -> AddressWire - (func.Return(get_item_0.result)), - ] - - method = build_method(stmts, squin_qubit_with_wire, squin.wire.WireType) - frame = run_fold_and_address_analysis(method) - - address_wires = collect_address_types(frame, address.AddressWire) - - assert address_wires[-1] == address.AddressWire( - origin_qubit=address.AddressQubit(0) - ) - - -def test_address_wire_is_subset_eq(): - - origin_qubit_0 = address.AddressQubit(data=0) - address_wire_0 = address.AddressWire(origin_qubit=origin_qubit_0) - - origin_qubit_1 = address.AddressQubit(data=1) - address_wire_1 = address.AddressWire(origin_qubit=origin_qubit_1) - - assert address_wire_0.is_subseteq(address_wire_0) - assert not address_wire_0.is_subseteq(address_wire_1) - - # fully exercise logic with lattice type that is not address wire - address_reg = address.AddressReg(data=[0, 1, 2, 3]) - assert not address_wire_0.is_subseteq(address_reg) diff --git a/test/analysis/measure_id/test_measure_id.py b/test/analysis/measure_id/test_measure_id.py index 5d9d1775..b5dc559e 100644 --- a/test/analysis/measure_id/test_measure_id.py +++ b/test/analysis/measure_id/test_measure_id.py @@ -1,7 +1,7 @@ from kirin.passes import HintConst from kirin.dialects import scf -from bloqade.squin import op, qubit, kernel +from bloqade.squin import op, qubit, kernel, qalloc from bloqade.analysis.measure_id import MeasurementIDAnalysis from bloqade.analysis.measure_id.lattice import ( MeasureIdBool, @@ -18,8 +18,8 @@ def test_add(): @kernel def test(): - ql1 = qubit.new(5) - ql2 = qubit.new(5) + ql1 = qalloc(5) + ql2 = qalloc(5) qubit.broadcast(op.x(), ql1) qubit.broadcast(op.x(), ql2) ml1 = qubit.measure(ql1) @@ -43,7 +43,7 @@ def test_measure_alias(): @kernel def test(): - ql = qubit.new(5) + ql = qalloc(5) ml = qubit.measure(ql) ml_alias = ml @@ -74,7 +74,7 @@ def test_measure_count_at_if_else(): @kernel def test(): - q = qubit.new(5) + q = qalloc(5) qubit.apply(op.x(), q[2]) ms = qubit.measure(q) @@ -95,7 +95,7 @@ def test(): def test_scf_cond_true(): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) qubit.apply(op.x(), q[2]) ms = None @@ -125,7 +125,7 @@ def test_scf_cond_false(): @kernel def test(): - q = qubit.new(5) + q = qalloc(5) qubit.apply(op.x(), q[2]) ms = None @@ -152,7 +152,7 @@ def test(): def test_slice(): @kernel def test(): - q = qubit.new(6) + q = qalloc(6) qubit.apply(op.x(), q[2]) ms = qubit.measure(q) @@ -180,7 +180,7 @@ def test(): def test_getitem_no_hint(): @kernel def test(idx): - q = qubit.new(6) + q = qalloc(6) ms = qubit.measure(q) return ms[idx] @@ -195,7 +195,7 @@ def test(idx): def test_getitem_invalid_hint(): @kernel def test(): - q = qubit.new(6) + q = qalloc(6) ms = qubit.measure(q) return ms["x"] @@ -211,7 +211,7 @@ def test_getitem_propagate_invalid_measure(): @kernel def test(): - q = qubit.new(6) + q = qalloc(6) ms = qubit.measure(q) # this will return an InvalidMeasureId invalid_ms = ms["x"] diff --git a/test/cirq_utils/test_cirq_to_squin.py b/test/cirq_utils/test_cirq_to_squin.py index c72943b5..3a4a07b4 100644 --- a/test/cirq_utils/test_cirq_to_squin.py +++ b/test/cirq_utils/test_cirq_to_squin.py @@ -250,7 +250,7 @@ def test_nesting_lowered_circuit(): @squin.kernel def main(): qreg = get_entangled_qubits() - qreg2 = squin.qubit.new(1) + qreg2 = squin.squin.qalloc(1) entangle_qubits([qreg[1], qreg2[0]]) return squin.qubit.measure(qreg2) @@ -344,7 +344,7 @@ def test_ghz_simulation(): # manually written kernel @squin.kernel def manual(): - q = squin.qubit.new(2) + q = squin.qalloc(2) s = squin.op.s() s_adj = squin.op.adjoint(s) squin.qubit.broadcast(s_adj, q) @@ -380,7 +380,7 @@ def test_kernel_with_args(): @squin.kernel def main(n: int): - q = squin.qubit.new(n) + q = squin.qalloc(n) x = squin.op.x() for i in range(n): squin.qubit.apply(x, q[i]) @@ -400,7 +400,7 @@ def main(n: int): @squin.kernel def multi_arg(n: int, p: float): - q = squin.qubit.new(n) + q = squin.squin.qalloc(n) h = squin.op.h() squin.qubit.apply(h, q[0]) diff --git a/test/cirq_utils/test_clifford_to_cirq.py b/test/cirq_utils/test_clifford_to_cirq.py index 569929f5..baa79fa9 100644 --- a/test/cirq_utils/test_clifford_to_cirq.py +++ b/test/cirq_utils/test_clifford_to_cirq.py @@ -15,14 +15,12 @@ def test_pauli(): @squin.kernel def main(): - q = squin.qubit.new(2) - q2 = squin.qubit.new(4) - x = squin.op.x() - y = squin.op.y() - z = squin.op.z() - squin.qubit.apply(x, q[0]) - squin.qubit.apply(y, q2[0]) - squin.qubit.apply(z, q2[3]) + q = squin.qalloc(2) + q2 = squin.qalloc(4) + + squin.x(q[0]) + squin.y(q2[0]) + squin.z(q2[3]) circuit = emit_circuit(main) @@ -38,7 +36,7 @@ def main(): def test_basic_op(op_name: str): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) getattr(squin, op_name)(q) emit_circuit(main) @@ -47,7 +45,7 @@ def main(): def test_control(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.h(q[0]) squin.cx(q[0], q[1]) @@ -62,7 +60,7 @@ def main(): def test_custom_qubits(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.h(q[0]) squin.cx(q[0], q[1]) @@ -83,7 +81,7 @@ def sub_kernel(q_: ilist.IList[squin.qubit.Qubit, typing.Any]): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) sub_kernel(q) circuit = emit_circuit(main) @@ -107,7 +105,7 @@ def sub_kernel(q_: ilist.IList[squin.qubit.Qubit, typing.Any]): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) sub_kernel(q) circuit = emit_circuit(main) @@ -118,7 +116,7 @@ def main(): def test_return_value(): @squin.kernel def sub_kernel(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.h(q[0]) squin.cx(q[0], q[1]) return q @@ -151,13 +149,13 @@ def test_return_qubits(): @squin.kernel def sub_kernel(q: ilist.IList[squin.qubit.Qubit, typing.Any]): squin.h(q[0]) - q2 = squin.qubit.new(3) + q2 = squin.qalloc(3) squin.cx(q[0], q2[2]) return q2 @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) q2_ = sub_kernel(q) squin.x(q2_[0]) @@ -169,7 +167,7 @@ def main(): def test_measurement(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.broadcast.y(q) squin.qubit.measure(q) @@ -181,7 +179,7 @@ def main(): def test_adjoint(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) squin.s(q[0]) squin.s_adj(q[0]) @@ -192,7 +190,7 @@ def main(): def test_u3(run_sim: bool = False): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) squin.u3(0.323, 1.123, math.pi / 7, q[0]) circuit = emit_circuit(main) @@ -207,7 +205,7 @@ def main(): def test_shift(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) squin.shift(math.pi / 7, q[0]) circuit = emit_circuit(main) @@ -222,7 +220,7 @@ def sub_kernel(q_: squin.qubit.Qubit): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) q0 = q[0] sub_kernel(q0) sub_kernel(q[1]) @@ -241,7 +239,7 @@ def main(): def test_rot(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) squin.rx(math.pi / 2, q[0]) circuit = emit_circuit(main) @@ -254,7 +252,7 @@ def main(): def test_additional_stmts(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) squin.u3(math.pi / 4, math.pi / 3, -math.pi / 4, q[0]) squin.sqrt_x(q[1]) squin.sqrt_y(q[2]) @@ -281,7 +279,7 @@ def test_return_measurement(): @squin.kernel def coinflip(): - qubit = squin.qubit.new(1)[0] + qubit = squin.qalloc(1)[0] squin.h(qubit) return squin.qubit.measure(qubit) diff --git a/test/cirq_utils/test_squin_noise_to_cirq.py b/test/cirq_utils/test_squin_noise_to_cirq.py index eb655d24..7721fb62 100644 --- a/test/cirq_utils/test_squin_noise_to_cirq.py +++ b/test/cirq_utils/test_squin_noise_to_cirq.py @@ -7,7 +7,7 @@ def test_pauli_channel(run_sim: bool = False): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) h = squin.op.h() cx = squin.op.cx() squin.qubit.apply(h, q[0]) diff --git a/test/native/test_stdlib.py b/test/native/test_stdlib.py index 5d8ccd9f..4cfe6760 100644 --- a/test/native/test_stdlib.py +++ b/test/native/test_stdlib.py @@ -5,8 +5,7 @@ from kirin import ir from kirin.dialects import ilist -from bloqade import native -from bloqade.squin import qubit +from bloqade import squin, native from bloqade.pyqrack import DynamicMemorySimulator @@ -14,7 +13,7 @@ def test_ghz(): @native.kernel(typeinfer=True, fold=True) def main(): - qreg = qubit.new(4) + qreg = squin.qalloc(4) native.h(qreg[0]) @@ -57,10 +56,10 @@ def main(): (native.s_dag, [1.0, 0.0]), ], ) -def test_1q_gate(gate_func: ir.Method[[qubit.Qubit], None], expected: Any): +def test_1q_gate(gate_func: ir.Method, expected: Any): @native.kernel def main(): - q = qubit.new(1) + q = squin.qalloc(1) gate_func(q[0]) sv = DynamicMemorySimulator().state_vector(main) diff --git a/test/native/upstream/test_squin2native.py b/test/native/upstream/test_squin2native.py index 7eebf7cd..4a823905 100644 --- a/test/native/upstream/test_squin2native.py +++ b/test/native/upstream/test_squin2native.py @@ -22,7 +22,7 @@ def test_ghz(): @squin.kernel def main(): - q = squin.qubit.new(n) + q = squin.qalloc(n) squin.h(q[0]) for i in range(n - 1): @@ -30,7 +30,7 @@ def main(): squin.broadcast.sqrt_x_adj(q) - new_main = SquinToNative().emit(main, no_raise=False) + new_main = SquinToNative().emit(main, no_raise=True) new_callgraph = callgraph.CallGraph(new_main) # make sure all kernels have been converted to native gates @@ -41,10 +41,10 @@ def main(): # test to make sure the statevectors are the same # before and after conversion to native gates - old_sv = np.asarray(StackMemorySimulator().state_vector(main)) + old_sv = np.asarray(StackMemorySimulator(min_qubits=n).state_vector(main)) old_sv /= old_sv[imax := np.abs(old_sv).argmax()] / np.abs(old_sv[imax]) - new_sv = np.asarray(StackMemorySimulator().state_vector(new_main)) + new_sv = np.asarray(StackMemorySimulator(min_qubits=n).state_vector(new_main)) new_sv /= new_sv[imax := np.abs(new_sv).argmax()] / np.abs(new_sv[imax]) assert np.allclose(old_sv, new_sv) diff --git a/test/pyqrack/runtime/test_qrack.py b/test/pyqrack/runtime/test_qrack.py index 135421bc..9161cabf 100644 --- a/test/pyqrack/runtime/test_qrack.py +++ b/test/pyqrack/runtime/test_qrack.py @@ -174,7 +174,7 @@ def test_rdm1(): @squin.kernel def program(): - q = squin.qubit.new(5) + q = squin.qalloc(5) squin.h(q[1]) return q @@ -203,7 +203,7 @@ def test_rdm1b(): @squin.kernel def program(): - q = squin.qubit.new(5) + q = squin.qalloc(5) squin.h(q[1]) return q @@ -233,7 +233,7 @@ def program(): """ Creates a GHZ state on qubits 0,1,3,4 on a total of 6 qubits. """ - q = squin.qubit.new(6) + q = squin.qalloc(6) squin.h(q[0]) squin.cx(q[0], q[1]) squin.cx(q[0], q[3]) @@ -263,7 +263,7 @@ def program(): """ Random unitaries on 3 qubits. """ - q = squin.qubit.new(3) + q = squin.qalloc(3) squin.rx(0.1, q[0]) squin.ry(0.2, q[1]) squin.rx(0.3, q[2]) @@ -316,7 +316,7 @@ def program(): """ Random unitaries on 3 qubits. """ - q = squin.qubit.new(3) + q = squin.qalloc(3) return q emulator = StackMemorySimulator(min_qubits=6) @@ -329,7 +329,7 @@ def program(): def test_rdm_failures(): @squin.kernel def program(): - q = squin.qubit.new(3) + q = squin.qalloc(3) return q emulator = StackMemorySimulator(min_qubits=6) @@ -357,7 +357,7 @@ def program(): def test_get_qubits(): @squin.kernel def program(): - q = squin.qubit.new(3) + q = squin.qalloc(3) return q emulator = StackMemorySimulator(min_qubits=6) @@ -371,11 +371,11 @@ def program(): def test_batch_run(): @squin.kernel def coinflip(): - qubit = squin.qubit.new(1)[0] + qubit = squin.qalloc(1)[0] squin.h(qubit) return squin.qubit.measure(qubit) - emulator = StackMemorySimulator() + emulator = StackMemorySimulator(min_qubits=1) task = emulator.task(coinflip) results: dict = task.batch_run(1000) assert len(set(results.keys()).symmetric_difference({False, True})) == 0 @@ -387,11 +387,11 @@ def coinflip(): def test_batch_run_IList_converter(): @squin.kernel def coinflip(): - qubit = squin.qubit.new(1)[0] + qubit = squin.qalloc(1)[0] squin.h(qubit) return [squin.qubit.measure(qubit)] - emulator = StackMemorySimulator() + emulator = StackMemorySimulator(min_qubits=1) task = emulator.task(coinflip) results: dict = task.batch_run(1000) assert len(set(results.keys()).symmetric_difference({(False,), (True,)})) == 0 @@ -404,11 +404,13 @@ def test_batch_state1(): @squin.kernel def coinflip(): - qubit = squin.qubit.new(1)[0] + qubit = squin.qalloc(1)[0] squin.h(qubit) return squin.qubit.measure(qubit) - emulator = StackMemorySimulator() + coinflip.print() + + emulator = StackMemorySimulator(min_qubits=1) task = emulator.task(coinflip) results = task.batch_state(1000) assert results.eigenvalues.shape == (2,) @@ -418,6 +420,10 @@ def coinflip(): assert abs(results.eigenvalues[1] - 0.5) < 0.1 +if __name__ == "__main__": + test_batch_state1() + + def test_batch_state2(): """ Averaging with a qubit_map function @@ -425,7 +431,7 @@ def test_batch_state2(): @squin.kernel def coinflip2(): - qubit = squin.qubit.new(2) + qubit = squin.qalloc(2) squin.h(qubit[0]) bit = squin.qubit.measure( qubit[0] diff --git a/test/pyqrack/squin/test_kernel.py b/test/pyqrack/squin/test_kernel.py index aa1594e9..eef7c1a6 100644 --- a/test/pyqrack/squin/test_kernel.py +++ b/test/pyqrack/squin/test_kernel.py @@ -11,7 +11,7 @@ def test_qubit(): @squin.kernel def new(): - return squin.qubit.new(3) + return squin.qalloc(3) new.print() @@ -35,7 +35,7 @@ def new(): @squin.kernel def m(): - q = squin.qubit.new(3) + q = squin.qalloc(3) m = squin.qubit.measure(q) squin.qubit.apply(squin.op.reset(), q) return m @@ -49,7 +49,7 @@ def m(): def test_x(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) x = squin.op.x() squin.qubit.apply(x, q) return squin.qubit.measure(q[0]) @@ -76,7 +76,7 @@ def main(): def test_basic_ops(op_name: str): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) op = getattr(squin.op, op_name)() squin.qubit.apply(op, q[0]) return q @@ -94,7 +94,7 @@ def main(): def test_cx(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) x = squin.op.x() cx = squin.op.control(x, n_controls=1) squin.qubit.apply(cx, q) @@ -106,7 +106,7 @@ def main(): @squin.kernel def main2(): - q = squin.qubit.new(2) + q = squin.qalloc(2) x = squin.op.x() id = squin.op.identity(sites=1) cx = squin.op.control(x, n_controls=1) @@ -120,7 +120,7 @@ def main2(): @squin.kernel def main3(): - q = squin.qubit.new(2) + q = squin.qalloc(2) x = squin.op.adjoint(squin.op.x()) id = squin.op.identity(sites=1) cx = squin.op.control(x, n_controls=1) @@ -136,7 +136,7 @@ def main3(): def test_cxx(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) x = squin.op.x() cxx = squin.op.control(squin.op.kron(x, x), n_controls=1) squin.qubit.apply(x, [q[0]]) @@ -151,7 +151,7 @@ def main(): def test_mult(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) x = squin.op.x() id = squin.op.mult(x, x) squin.qubit.apply(id, q) @@ -168,7 +168,7 @@ def main(): def test_kron(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) x = squin.op.x() k = squin.op.kron(x, x) squin.qubit.apply(k, q) @@ -183,7 +183,7 @@ def main(): def test_scale(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) x = squin.op.x() # TODO: replace by 2 * x once we have the rewrite @@ -200,7 +200,7 @@ def main(): def test_phase(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) h = squin.op.h() squin.qubit.apply(h, q) @@ -218,7 +218,7 @@ def main(): def test_sp(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) sp = squin.op.spin_p() squin.qubit.apply(sp, q) return q @@ -232,7 +232,7 @@ def main(): @squin.kernel def main2(): - q = squin.qubit.new(1) + q = squin.qalloc(1) sn = squin.op.spin_n() sp = squin.op.spin_p() squin.qubit.apply(sn, q) @@ -247,7 +247,7 @@ def main2(): def test_adjoint(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) x = squin.op.x() xadj = squin.op.adjoint(x) squin.qubit.apply(xadj, q) @@ -259,7 +259,7 @@ def main(): @squin.kernel def adj_that_does_something(): - q = squin.qubit.new(1) + q = squin.qalloc(1) s = squin.op.s() sadj = squin.op.adjoint(s) h = squin.op.h() @@ -276,7 +276,7 @@ def adj_that_does_something(): @squin.kernel def adj_of_adj(): - q = squin.qubit.new(1) + q = squin.qalloc(1) s = squin.op.s() sadj = squin.op.adjoint(s) sadj_adj = squin.op.adjoint(sadj) @@ -294,7 +294,7 @@ def adj_of_adj(): @squin.kernel def nested_adj(): - q = squin.qubit.new(1) + q = squin.qalloc(1) s = squin.op.s() sadj = squin.op.adjoint(s) s_nested_adj = squin.op.adjoint(squin.op.adjoint(squin.op.adjoint(sadj))) @@ -315,7 +315,7 @@ def nested_adj(): def test_rot(): @squin.kernel def main_x(): - q = squin.qubit.new(1) + q = squin.qalloc(1) x = squin.op.x() r = squin.op.rot(x, math.pi) squin.qubit.apply(r, q) @@ -327,7 +327,7 @@ def main_x(): @squin.kernel def main_y(): - q = squin.qubit.new(1) + q = squin.qalloc(1) y = squin.op.y() r = squin.op.rot(y, math.pi) squin.qubit.apply(r, q) @@ -339,7 +339,7 @@ def main_y(): @squin.kernel def main_z(): - q = squin.qubit.new(1) + q = squin.qalloc(1) z = squin.op.z() r = squin.op.rot(z, math.pi) squin.qubit.apply(r, q) @@ -353,7 +353,7 @@ def main_z(): def test_broadcast(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) x = squin.op.x() squin.qubit.broadcast(x, q) return squin.qubit.measure(q) @@ -364,7 +364,7 @@ def main(): @squin.kernel def multi_site_bc(): - q = squin.qubit.new(6) + q = squin.qalloc(6) x = squin.op.x() # invert controls @@ -381,7 +381,7 @@ def multi_site_bc(): @squin.kernel def bc_size_mismatch(): - q = squin.qubit.new(5) + q = squin.qalloc(5) x = squin.op.x() # invert controls @@ -401,7 +401,7 @@ def bc_size_mismatch(): def test_u3(): @squin.kernel def broadcast_h(): - q = squin.qubit.new(3) + q = squin.qalloc(3) # rotate around Y by pi/2, i.e. perform a hadamard u = squin.op.u(math.pi / 2.0, 0, 0) @@ -427,7 +427,7 @@ def broadcast_h(): @squin.kernel def broadcast_adjoint(): - q = squin.qubit.new(3) + q = squin.qalloc(3) # rotate around Y by pi/2, i.e. perform a hadamard squin.u3(math.pi / 2.0, 0, 0, q[0]) @@ -446,7 +446,7 @@ def broadcast_adjoint(): def test_projectors(): @squin.kernel def main_p0(): - q = squin.qubit.new(1) + q = squin.qalloc(1) h = squin.op.h() p0 = squin.op.p0() squin.qubit.apply(h, q) @@ -459,7 +459,7 @@ def main_p0(): @squin.kernel def main_p1(): - q = squin.qubit.new(1) + q = squin.qalloc(1) h = squin.op.h() p1 = squin.op.p1() squin.qubit.apply(h, q) @@ -474,7 +474,7 @@ def main_p1(): def test_pauli_str(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) cstr = squin.op.pauli_string(string="XXX") squin.qubit.apply(cstr, q) return squin.qubit.measure(q) @@ -488,7 +488,7 @@ def test_identity(): @squin.kernel def main(): x = squin.op.x() - q = squin.qubit.new(3) + q = squin.qalloc(3) id = squin.op.identity(sites=2) squin.qubit.apply(squin.op.kron(x, id), q) return squin.qubit.measure(q) @@ -502,7 +502,7 @@ def main(): def test_wire(): @squin.wired def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) w = squin.wire.unwrap(q[0]) x = squin.op.x() squin.wire.apply(x, w) @@ -517,7 +517,7 @@ def main(): def test_reset(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.qubit.broadcast(squin.op.h(), q) squin.qubit.broadcast(squin.op.reset(), q) squin.qubit.broadcast(squin.op.reset_to_one(), q) @@ -532,7 +532,7 @@ def main(): def test_feed_forward(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) h = squin.op.h() squin.qubit.apply(h, q[0]) squin.qubit.apply(h, q[1]) diff --git a/test/pyqrack/squin/test_noise.py b/test/pyqrack/squin/test_noise.py index 12020069..14103612 100644 --- a/test/pyqrack/squin/test_noise.py +++ b/test/pyqrack/squin/test_noise.py @@ -5,9 +5,8 @@ def test_qubit_loss(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) squin.qubit_loss(1.0, q[0]) - return q target = PyQrack(1) result = target.run(main) @@ -19,7 +18,7 @@ def main(): def test_pauli_channel(): @squin.kernel def single_qubit(): - q = squin.qubit.new(1) + q = squin.qalloc(1) squin.single_qubit_pauli_channel(px=0.1, py=0.2, pz=0.3, qubit=q[0]) return q @@ -30,7 +29,7 @@ def single_qubit(): @squin.kernel def two_qubits(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.two_qubit_pauli_channel( [ 0.01, @@ -63,7 +62,7 @@ def two_qubits(): def test_depolarize(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) h = squin.op.h() squin.qubit.apply(h, q[0]) @@ -79,7 +78,7 @@ def main(): def test_depolarize2(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) squin.depolarize2(0.1, q[0], q[1]) main.print() diff --git a/test/squin/clifford/test_stdlib_clifford.py b/test/squin/clifford/test_stdlib_clifford.py index b588c185..9ba9fb8d 100644 --- a/test/squin/clifford/test_stdlib_clifford.py +++ b/test/squin/clifford/test_stdlib_clifford.py @@ -16,7 +16,7 @@ def test_ghz(control_gate: ir.Method[[Qubit, Qubit], Any]): @squin.kernel def main(): - q = squin.qubit.new(n) + q = squin.qalloc(n) squin.h(q[0]) for i in range(n - 1): @@ -53,7 +53,7 @@ def main(): def test_1q_gate(gate_func: ir.Method[[Qubit], None], expected: Any): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) gate_func(q[0]) sv = DynamicMemorySimulator().state_vector(main) @@ -77,7 +77,7 @@ def test_1q_rots(rotation: ir.Method[[float, Qubit], None], expected: list): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) rotation(angle, q[0]) sv = DynamicMemorySimulator().state_vector(main) @@ -97,7 +97,7 @@ def test_ghz_with_cz(): @squin.kernel def main(): - q = squin.qubit.new(n) + q = squin.qalloc(n) squin.h(q[0]) for i in range(n - 1): @@ -119,7 +119,7 @@ def main(): def test_broadcast(): @squin.kernel def h_broadcast(): - q = squin.qubit.new(4) + q = squin.qalloc(4) squin.broadcast.h(q) sim = StackMemorySimulator(min_qubits=4) @@ -132,7 +132,7 @@ def h_broadcast(): def test_rotations(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) squin.u3(-math.pi, math.pi, math.pi / 2.0, q[0]) squin.u3(math.pi, -math.pi / 4.0, -math.pi, q[0]) diff --git a/test/squin/noise/test_stdlib_noise.py b/test/squin/noise/test_stdlib_noise.py index 2dd90345..ed196237 100644 --- a/test/squin/noise/test_stdlib_noise.py +++ b/test/squin/noise/test_stdlib_noise.py @@ -6,7 +6,7 @@ def test_loss(): @squin.kernel def main(): - q = squin.qubit.new(1) + q =squin.qalloc(1) squin.qubit_loss(1.0, q[0]) return q[0] @@ -23,7 +23,7 @@ def test_bit_flip(): @squin.kernel def main(): - q = squin.qubit.new(1) + q =squin.qalloc(1) squin.bit_flip(1.0, q[0]) squin.single_qubit_pauli_channel(0.0, 1.0, 0.0, q[0]) return squin.qubit.measure(q) diff --git a/test/squin/rewrite/test_U3_to_clifford.py b/test/squin/rewrite/test_U3_to_clifford.py index 6076c1cf..ba761879 100644 --- a/test/squin/rewrite/test_U3_to_clifford.py +++ b/test/squin/rewrite/test_U3_to_clifford.py @@ -5,7 +5,7 @@ from kirin.passes.abc import Pass from kirin.rewrite.dce import DeadCodeElimination -from bloqade.squin import op, qubit, kernel +from bloqade.squin import op, qubit, kernel, qalloc from bloqade.squin.rewrite.U3_to_clifford import SquinU3ToClifford @@ -34,7 +34,7 @@ def test_identity(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0 * math.tau, phi=0.0 * math.tau, lam=0.0 * math.tau) qubit.apply(oper, q[0]) @@ -47,7 +47,7 @@ def test_s(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0 * math.tau, phi=0.0 * math.tau, lam=0.25 * math.tau) qubit.apply(oper, q[0]) @@ -58,7 +58,7 @@ def test(): ## assumes it's already in units of half pi and normalized to [0, 1) @kernel def test_equiv(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=math.tau, phi=0.5 * math.tau, lam=0.75 * math.tau) qubit.apply(oper, q[0]) @@ -71,7 +71,7 @@ def test_s_alternative(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0, phi=0.25 * math.tau, lam=0.0) qubit.apply(oper, q[0]) @@ -83,7 +83,7 @@ def test_z(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # nice positive representation op0 = op.u(theta=0.0 * math.tau, phi=0.0 * math.tau, lam=0.5 * math.tau) # wrap around @@ -105,7 +105,7 @@ def test_z_alternative(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0, phi=0.5 * math.tau, lam=0.0) qubit.apply(oper, q[0]) @@ -117,7 +117,7 @@ def test_sdag(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0 * math.tau, phi=0.0 * math.tau, lam=-0.25 * math.tau) qubit.apply(oper, q[0]) @@ -127,7 +127,7 @@ def test(): @kernel def test_equiv(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0 * math.tau, phi=0.5 * math.tau, lam=0.25 * math.tau) qubit.apply(oper, q[0]) @@ -140,7 +140,7 @@ def test_sdag_alternative_negative(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0, phi=-0.25 * math.tau, lam=0.0) qubit.apply(oper, q[0]) @@ -153,7 +153,7 @@ def test_sdag_alternative(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.0, phi=0.75 * math.tau, lam=0.0) qubit.apply(oper, q[0]) @@ -166,7 +166,7 @@ def test_sdag_weird_case(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=2 * math.tau, phi=0.7 * math.tau, lam=0.05 * math.tau) qubit.apply(oper, q[0]) @@ -179,7 +179,7 @@ def test_sdag_weirder_case(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) oper = op.u(theta=0.5 * math.tau, phi=0.05 * math.tau, lam=0.8 * math.tau) qubit.apply(oper, q[0]) @@ -192,7 +192,7 @@ def test_sqrt_y(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) op0 = op.u(theta=0.25 * math.tau, phi=0.0 * math.tau, lam=0.0 * math.tau) # equivalent to sqrt(y) gate op1 = op.u(theta=1.25 * math.tau, phi=0.0 * math.tau, lam=0.0 * math.tau) @@ -211,7 +211,7 @@ def test_s_sqrt_y(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) op0 = op.u(theta=0.25 * math.tau, phi=0.0 * math.tau, lam=0.25 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=1.0 * math.tau, lam=1.25 * math.tau) @@ -229,7 +229,7 @@ def test_h(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 0, 1) op0 = op.u(theta=0.25 * math.tau, phi=0.0 * math.tau, lam=0.5 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=0.0 * math.tau, lam=1.5 * math.tau) @@ -245,7 +245,7 @@ def test_sdg_sqrt_y(): @kernel() def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 0, 3) op0 = op.u(theta=0.25 * math.tau, phi=0.0 * math.tau, lam=0.75 * math.tau) op1 = op.u(theta=-1.75 * math.tau, phi=0.0 * math.tau, lam=-1.25 * math.tau) @@ -266,7 +266,7 @@ def test_sqrt_y_s(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 1, 0) op0 = op.u(theta=0.25 * math.tau, phi=0.25 * math.tau, lam=0.0 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=-1.75 * math.tau, lam=0.0 * math.tau) @@ -281,7 +281,7 @@ def test_s_sqrt_y_s(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 1, 1) op0 = op.u(theta=0.25 * math.tau, phi=0.25 * math.tau, lam=0.25 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=1.25 * math.tau, lam=1.25 * math.tau) @@ -306,7 +306,7 @@ def test_z_sqrt_y_s(): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) # (1, 1, 2) op0 = op.u(theta=0.25 * math.tau, phi=0.25 * math.tau, lam=0.5 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=1.25 * math.tau, lam=1.5 * math.tau) @@ -332,7 +332,7 @@ def test_sdg_sqrt_y_s(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 1, 3) op0 = op.u(theta=0.25 * math.tau, phi=0.25 * math.tau, lam=0.75 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=1.25 * math.tau, lam=1.75 * math.tau) @@ -362,7 +362,7 @@ def test_sqrt_y_z(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 2, 0) op0 = op.u(theta=0.25 * math.tau, phi=0.5 * math.tau, lam=0.0 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=-1.5 * math.tau, lam=0.0 * math.tau) @@ -382,7 +382,7 @@ def test_s_sqrt_y_z(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 2, 1) op0 = op.u(theta=0.25 * math.tau, phi=0.5 * math.tau, lam=0.25 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=1.5 * math.tau, lam=-1.75 * math.tau) @@ -410,7 +410,7 @@ def test_z_sqrt_y_z(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 2, 2) op0 = op.u(theta=0.25 * math.tau, phi=0.5 * math.tau, lam=0.5 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=-0.5 * math.tau, lam=-1.5 * math.tau) @@ -436,7 +436,7 @@ def test_sdg_sqrt_y_z(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 2, 3) op0 = op.u(theta=0.25 * math.tau, phi=0.5 * math.tau, lam=0.75 * math.tau) op1 = op.u(theta=1.25 * math.tau, phi=1.5 * math.tau, lam=-1.25 * math.tau) @@ -465,7 +465,7 @@ def test_sqrt_y_sdg(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 3, 0) op0 = op.u(theta=0.25 * math.tau, phi=0.75 * math.tau, lam=0.0 * math.tau) qubit.apply(op0, q[0]) @@ -486,7 +486,7 @@ def test_s_sqrt_y_sdg(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 3, 1) op0 = op.u(theta=0.25 * math.tau, phi=0.75 * math.tau, lam=0.25 * math.tau) qubit.apply(op0, q[0]) @@ -508,7 +508,7 @@ def test_z_sqrt_y_sdg(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 3, 2) op0 = op.u(theta=0.25 * math.tau, phi=0.75 * math.tau, lam=0.5 * math.tau) qubit.apply(op0, q[0]) @@ -530,7 +530,7 @@ def test_sdg_sqrt_y_sdg(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (1, 3, 3) op0 = op.u(theta=0.25 * math.tau, phi=0.75 * math.tau, lam=0.75 * math.tau) qubit.apply(op0, q[0]) @@ -553,7 +553,7 @@ def test_y(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (2, 0, 0) op0 = op.u(theta=0.5 * math.tau, phi=0.0 * math.tau, lam=0.0 * math.tau) qubit.apply(op0, q[0]) @@ -566,7 +566,7 @@ def test_s_y(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (2, 0, 1) op0 = op.u(theta=0.5 * math.tau, phi=0.0 * math.tau, lam=0.25 * math.tau) qubit.apply(op0, q[0]) @@ -580,7 +580,7 @@ def test_z_y(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (2, 0, 2) op0 = op.u(theta=0.5 * math.tau, phi=0.0 * math.tau, lam=0.5 * math.tau) qubit.apply(op0, q[0]) @@ -594,7 +594,7 @@ def test_sdg_y(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) # (2, 0, 3) op0 = op.u(theta=0.5 * math.tau, phi=0.0 * math.tau, lam=0.75 * math.tau) qubit.apply(op0, q[0]) diff --git a/test/squin/rewrite/test_mult_rewrite.py b/test/squin/rewrite/test_mult_rewrite.py index 8a0bbaea..eb9ac44a 100644 --- a/test/squin/rewrite/test_mult_rewrite.py +++ b/test/squin/rewrite/test_mult_rewrite.py @@ -12,7 +12,7 @@ def helper(x: squin.op.types.Op, y: squin.op.types.Op): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) x = squin.op.x() y = squin.op.y() z = x * y diff --git a/test/squin/test_qubit.py b/test/squin/test_qubit.py index c2b085de..82f5723f 100644 --- a/test/squin/test_qubit.py +++ b/test/squin/test_qubit.py @@ -8,7 +8,7 @@ def test_get_ids(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) m = squin.qubit.measure(q) @@ -21,7 +21,7 @@ def main(): @squin.kernel def main2(): - q = squin.qubit.new(2) + q = squin.qalloc(2) qid = squin.qubit.get_qubit_id(q[0]) m1 = squin.qubit.measure(q[qid]) diff --git a/test/squin/test_stdlib_shorthands.py b/test/squin/test_stdlib_shorthands.py index e31112ec..7e713fe7 100644 --- a/test/squin/test_stdlib_shorthands.py +++ b/test/squin/test_stdlib_shorthands.py @@ -27,7 +27,7 @@ def test_single_qubit_apply(op_name: str): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) getattr(squin, op_name)(q[0]) main.print() @@ -48,7 +48,7 @@ def main(): def test_control_apply(op_name: str): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) getattr(squin, op_name)(q[0], q[1]) main.print() @@ -78,7 +78,7 @@ def main(): def test_single_qubit_broadcast(op_name: str): @squin.kernel def main(): - q = squin.qubit.new(4) + q = squin.qalloc(4) getattr(squin.broadcast, op_name)(q) main.print() @@ -99,8 +99,8 @@ def main(): def test_control_broadcast(op_name: str): @squin.kernel def main(): - controls = squin.qubit.new(3) - targets = squin.qubit.new(3) + controls = squin.qalloc(3) + targets = squin.qalloc(3) getattr(squin.broadcast, op_name)(controls, targets) main.print() @@ -115,7 +115,7 @@ def subkernel(q: Qubit): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) subkernel(q[0]) main.print() @@ -134,7 +134,7 @@ def main(): def test_parameter_gates(op_name: str): @squin.kernel def main(): - q = squin.qubit.new(4) + q = squin.qalloc(4) theta = 0.123 getattr(squin, op_name)(theta, q[0]) @@ -156,7 +156,7 @@ def main(): def test_single_qubit_noise(op_name: str): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) p = 0.1 getattr(squin, op_name)(p, q[0]) @@ -169,7 +169,7 @@ def main(): def test_single_qubit_pauli_channel(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) px = 0.1 py = 0.1 pz = 0.05 @@ -184,7 +184,7 @@ def main(): def test_depolarize2(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) p = 0.1 squin.depolarize2(p, q[0], q[1]) @@ -197,7 +197,7 @@ def main(): def test_two_qubit_pauli_channel(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) # NOTE: this API is not great ps = [ diff --git a/test/squin/test_sugar.py b/test/squin/test_sugar.py index 39b517cd..f1fb6eca 100644 --- a/test/squin/test_sugar.py +++ b/test/squin/test_sugar.py @@ -17,7 +17,7 @@ def get_return_value_stmt(kernel: ir.Method): def test_measure_register(): @squin.kernel def test_measure_sugar(): - q = squin.qubit.new(2) + q = squin.qalloc(2) return squin.qubit.measure(q) @@ -29,7 +29,7 @@ def test_measure_sugar(): def test_measure_qubit(): @squin.kernel def test_measure_sugar(): - q = squin.qubit.new(2) + q = squin.qalloc(2) return squin.qubit.measure(q[0]) @@ -42,7 +42,7 @@ def test_measure_sugar(): def test_apply_sugar(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) h = squin.op.h() x = squin.op.x() @@ -76,7 +76,7 @@ def test_apply_in_for_loop(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) x = squin.op.x() for i in range(2): squin.qubit.apply(x, q[i]) @@ -95,7 +95,7 @@ def test_apply_in_for_loop_index_multiple_index(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) squin.qubit.apply(squin.op.h(), q[0]) cx = squin.op.cx() for i in range(2): @@ -109,7 +109,7 @@ def main(): def test_apply_with_named_args(): @squin.kernel def main(): - q = squin.qubit.new(2) + q = squin.qalloc(2) h = squin.op.h() squin.qubit.apply(h, qubits=[q[0]]) cx = squin.op.cx() @@ -122,7 +122,7 @@ def test_new_apply_syntax(): @squin.kernel def main(): - q = squin.qubit.new(1) + q = squin.qalloc(1) x = squin.op.x() squin.qubit.apply(x, q[0]) @@ -130,8 +130,8 @@ def main(): @squin.kernel def ghz(): - controls = squin.qubit.new(4) - targets = squin.qubit.new(4) + controls = squin.qalloc(4) + targets = squin.qalloc(4) h = squin.op.h() for i in range(4): @@ -149,8 +149,8 @@ def ghz(): def test_new_broadcast_syntax(): @squin.kernel def main(): - controls = squin.qubit.new(4) - targets = squin.qubit.new(4) + controls = squin.qalloc(4) + targets = squin.qalloc(4) h = squin.op.h() squin.qubit.broadcast(h, controls) diff --git a/test/squin/test_typeinfer.py b/test/squin/test_typeinfer.py index 4d968807..c879f981 100644 --- a/test/squin/test_typeinfer.py +++ b/test/squin/test_typeinfer.py @@ -21,13 +21,13 @@ def results_at(kernel: ir.Method, block_id: int, stmt_id: int): # following tests ensure that type inferece for squin.qubit.New can figure # out the IList length when the data is immediately available. If not, just # safely fall back to Any. Historically, without an addition to the -# type inference method table, the result type of squin's qubit.new +# type inference method table, the result type of squin's qalloc # would always be IListType[QubitType, Any]. def test_typeinfer_new_qubit_len_concrete(): @squin.kernel def test(): - q = squin.qubit.new(4) + q = squin.qalloc(4) return q type_infer_analysis = TypeInference(dialects=test.dialects) @@ -42,7 +42,7 @@ def test_typeinfer_new_qubit_len_ambiguous(): # Now let's try with non-concrete length @squin.kernel def test(n: int): - q = squin.qubit.new(n) + q = squin.qalloc(n) return q type_infer_analysis = TypeInference(dialects=test.dialects) @@ -60,7 +60,7 @@ def test(n: int): def test_typeinfer_new_qubit_getitem(): @squin.kernel def test(): - q = squin.qubit.new(4) + q = squin.qalloc(4) q0 = q[0] q1 = q[1] return [q0, q1] diff --git a/test/stim/passes/squin_meas_to_stim.py b/test/stim/passes/squin_meas_to_stim.py index dff954e0..cf62ad21 100644 --- a/test/stim/passes/squin_meas_to_stim.py +++ b/test/stim/passes/squin_meas_to_stim.py @@ -4,7 +4,7 @@ from kirin.dialects.ilist import IList from bloqade import squin -from bloqade.squin import op, qubit +from bloqade.squin import op, qubit, qalloc from bloqade.stim.emit import EmitStimMain from bloqade.squin.qubit import MeasurementResult from bloqade.stim.passes import SquinToStimPass @@ -32,7 +32,7 @@ def test_cond_on_measurement(): @squin.kernel def main(): n_qubits = 4 - q = qubit.new(n_qubits) + q = qalloc(n_qubits) ms = qubit.measure(q) @@ -59,7 +59,7 @@ def test_alias_with_measure_list(): @squin.kernel def main(): - q = qubit.new(4) + q = qalloc(4) ms = qubit.measure(q) new_ms = ms @@ -78,7 +78,7 @@ def test_record_index_order(): @squin.kernel def main(): n_qubits = 4 - q = qubit.new(n_qubits) + q = qalloc(n_qubits) ms0 = qubit.measure(q) @@ -112,7 +112,7 @@ def test_complex_intermediate_storage_of_measurements(): @squin.kernel def main(): n_qubits = 4 - q = qubit.new(n_qubits) + q = qalloc(n_qubits) ms0 = qubit.measure(q) @@ -148,7 +148,7 @@ def test_addition_assignment_on_measures_in_list(): @squin.kernel(fold=False) def main(): - q = qubit.new(2) + q = qalloc(2) results = [] result: MeasurementResult = qubit.measure(q[0]) @@ -169,7 +169,7 @@ def test_measure_desugar(): @squin.kernel def main(): - q = qubit.new(10) + q = qalloc(10) qubit.measure(q[pairs[0]]) for i in range(1): qubit.measure(q[0]) diff --git a/test/stim/passes/squin_noise_to_stim.py b/test/stim/passes/squin_noise_to_stim.py index 057b10d6..38d81b30 100644 --- a/test/stim/passes/squin_noise_to_stim.py +++ b/test/stim/passes/squin_noise_to_stim.py @@ -7,7 +7,7 @@ from kirin.dialects import py, func, ilist import bloqade.types as bloqade_types -from bloqade.squin import op, wire, noise, qubit, kernel +from bloqade.squin import op, wire, noise, qubit, kernel, qalloc from bloqade.stim.emit import EmitStimMain from bloqade.stim.passes import SquinToStimPass from bloqade.stim.rewrite import SquinNoiseToStim @@ -68,7 +68,7 @@ def test_apply_pauli_channel_1(): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) channel = noise.single_qubit_pauli_channel(params=[0.01, 0.02, 0.03]) qubit.apply(channel, q[0]) return @@ -82,7 +82,7 @@ def test_broadcast_pauli_channel_1(): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) channel = noise.single_qubit_pauli_channel(params=[0.01, 0.02, 0.03]) qubit.broadcast(channel, q) return @@ -96,7 +96,7 @@ def test_broadcast_pauli_channel_1_many_qubits(): @kernel def test(): - q = qubit.new(2) + q = qalloc(2) channel = noise.single_qubit_pauli_channel(params=[0.01, 0.02, 0.03]) qubit.broadcast(channel, q) return @@ -112,7 +112,7 @@ def test_broadcast_pauli_channel_1_reuse(): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) channel = noise.single_qubit_pauli_channel(params=[0.01, 0.02, 0.03]) qubit.broadcast(channel, q) qubit.broadcast(channel, q) @@ -130,7 +130,7 @@ def test_broadcast_pauli_channel_2(): @kernel def test(): - q = qubit.new(2) + q = qalloc(2) channel = noise.two_qubit_pauli_channel( params=[ 0.001, @@ -162,7 +162,7 @@ def test_broadcast_pauli_channel_2_reuse_on_4_qubits(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) channel = noise.two_qubit_pauli_channel( params=[ 0.001, @@ -197,7 +197,7 @@ def test_broadcast_depolarize2(): @kernel def test(): - q = qubit.new(2) + q = qalloc(2) channel = noise.depolarize2(p=0.015) qubit.broadcast(channel, q) return @@ -211,7 +211,7 @@ def test_apply_depolarize1(): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) channel = noise.depolarize(p=0.01) qubit.apply(channel, q[0]) return @@ -225,7 +225,7 @@ def test_broadcast_depolarize1(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) channel = noise.depolarize(p=0.01) qubit.broadcast(channel, q) return @@ -239,7 +239,7 @@ def test_broadcast_iid_bit_flip_channel(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) x = op.x() channel = noise.pauli_error(x, 0.01) qubit.broadcast(channel, q) @@ -256,7 +256,7 @@ def test_broadcast_iid_phase_flip_channel(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) z = op.z() channel = noise.pauli_error(z, 0.01) qubit.broadcast(channel, q) @@ -273,7 +273,7 @@ def test_broadcast_iid_y_flip_channel(): @kernel def test(): - q = qubit.new(4) + q = qalloc(4) y = op.y() channel = noise.pauli_error(y, 0.01) qubit.broadcast(channel, q) @@ -288,7 +288,7 @@ def test_apply_loss(): @kernel def test(): - q = qubit.new(3) + q = qalloc(3) loss = noise.qubit_loss(0.1) qubit.apply(loss, q[0]) qubit.apply(loss, q[1]) @@ -371,7 +371,7 @@ class NonExistentNoiseChannel(noise.stmts.NoiseChannel): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) channel = NonExistentNoiseChannel() qubit.apply(channel, q[0]) return @@ -395,7 +395,7 @@ def test_standard_op_no_rewrite(): @kernel def test(): - q = qubit.new(1) + q = qalloc(1) qubit.apply(op.x(), q[0]) return diff --git a/test/stim/passes/squin_qubit_to_stim.py b/test/stim/passes/squin_qubit_to_stim.py index 6385d2c9..1eb9b544 100644 --- a/test/stim/passes/squin_qubit_to_stim.py +++ b/test/stim/passes/squin_qubit_to_stim.py @@ -5,7 +5,7 @@ from kirin.dialects import py from bloqade import squin -from bloqade.squin import op, noise, qubit, kernel +from bloqade.squin import op, noise, qubit, kernel, qalloc from bloqade.stim.emit import EmitStimMain from bloqade.stim.passes import SquinToStimPass @@ -39,7 +39,7 @@ def test_qubit(): @kernel def test(): n_qubits = 2 - ql = qubit.new(n_qubits) + ql = qalloc(n_qubits) qubit.broadcast(op.h(), ql) qubit.apply(op.x(), ql[0]) ctrl = op.control(op.x(), n_controls=1) @@ -60,7 +60,7 @@ def test_qubit_reset(): @kernel def test(): n_qubits = 1 - q = qubit.new(n_qubits) + q = qalloc(n_qubits) # reset the qubit squin.qubit.apply(op.reset(), q[0]) # measure out @@ -77,7 +77,7 @@ def test_qubit_broadcast(): @kernel def test(): n_qubits = 4 - ql = qubit.new(n_qubits) + ql = qalloc(n_qubits) # apply Hadamard to all qubits squin.qubit.broadcast(op.h(), ql) # measure out @@ -94,7 +94,7 @@ def test_qubit_loss(): @kernel def test(): n_qubits = 5 - ql = qubit.new(n_qubits) + ql = qalloc(n_qubits) # apply Hadamard to all qubits squin.qubit.broadcast(op.h(), ql) # apply and broadcast qubit loss @@ -115,7 +115,7 @@ def test_u3_to_clifford(): @kernel def test(): n_qubits = 1 - q = qubit.new(n_qubits) + q = qalloc(n_qubits) # apply U3 rotation that can be translated to a Clifford gate squin.qubit.apply(op.u(0.25 * math.tau, 0.0 * math.tau, 0.5 * math.tau), q[0]) # measure out @@ -133,7 +133,7 @@ def test_sqrt_x_rewrite(): @squin.kernel def test(): - q = qubit.new(1) + q = qalloc(1) qubit.broadcast(op.sqrt_x(), q) return @@ -146,7 +146,7 @@ def test_sqrt_y_rewrite(): @squin.kernel def test(): - q = qubit.new(1) + q = qalloc(1) qubit.broadcast(op.sqrt_y(), q) return @@ -159,7 +159,7 @@ def test_for_loop_nontrivial_index_rewrite(): @squin.kernel def main(): - q = squin.qubit.new(3) + q = squin.qalloc(3) squin.qubit.apply(squin.op.h(), q[0]) cx = squin.op.cx() for i in range(2): @@ -175,7 +175,7 @@ def test_nested_for_loop_rewrite(): @squin.kernel def main(): - q = squin.qubit.new(5) + q = squin.qalloc(5) squin.qubit.apply(squin.op.h(), q[0]) cx = squin.op.cx() for i in range(2): @@ -201,7 +201,7 @@ def test_nested_list(): @squin.kernel def main(): - q = qubit.new(10) + q = qalloc(10) h = squin.op.h() for i in range(2): squin.qubit.apply(h, q[pairs[i][0]]) @@ -217,7 +217,7 @@ def test_pick_if_else(): @squin.kernel def main(): - q = qubit.new(10) + q = qalloc(10) if False: qubit.apply(squin.op.h(), q[0]) @@ -234,7 +234,7 @@ def main(): def test_non_pure_loop_iterator(): @kernel def test_squin_kernel(): - q = qubit.new(5) + q = qalloc(5) result = qubit.measure(q) outputs = [] for rnd in range(len(result)): # Non-pure loop iterator diff --git a/test/stim/passes/squin_wire_to_stim.py b/test/stim/passes/squin_wire_to_stim.py deleted file mode 100644 index 89d32ea8..00000000 --- a/test/stim/passes/squin_wire_to_stim.py +++ /dev/null @@ -1,394 +0,0 @@ -import os - -import pytest -from kirin import ir, types -from kirin.passes import TypeInfer -from kirin.rewrite import Walk -from kirin.dialects import py, func - -from bloqade import squin -from bloqade.squin import wire, kernel -from bloqade.stim.emit import EmitStimMain -from bloqade.stim.passes import SquinToStimPass -from bloqade.squin.rewrite import WrapAddressAnalysis -from bloqade.analysis.address import AddressAnalysis - - -def gen_func_from_stmts(stmts, output_type=types.NoneType): - - extended_dialect = kernel.add(wire) - - block = ir.Block(stmts) - block.args.append_from(types.MethodType[[], types.NoneType], "main") - func_wrapper = func.Function( - sym_name="main", - signature=func.Signature(inputs=(), output=output_type), - body=ir.Region(blocks=block), - ) - - constructed_method = ir.Method( - mod=None, - py_func=None, - sym_name="main", - dialects=extended_dialect, - code=func_wrapper, - arg_names=[], - ) - - return constructed_method - - -def codegen(mt: ir.Method): - # method should not have any arguments! - emit = EmitStimMain() - emit.initialize() - emit.run(mt=mt, args=()) - return emit.get_output() - - -def as_int(value: int): - return py.constant.Constant(value=value) - - -def as_float(value: float): - return py.constant.Constant(value=value) - - -def get_stim_reference_file(filename: str) -> str: - path = os.path.join( - os.path.dirname(__file__), - "stim_reference_programs", - "wire", - filename, - ) - with open(path, "r") as f: - return f.read() - - -def run_passes(test_method): - TypeInfer(test_method.dialects)(test_method) - addr_frame, _ = AddressAnalysis(test_method.dialects).run_analysis(test_method) - Walk(WrapAddressAnalysis(address_analysis=addr_frame.entries)).rewrite( - test_method.code - ) - SquinToStimPass(test_method.dialects)(test_method) - - -@pytest.mark.xfail -def test_wire(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(4)), - # returns an ilist - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - (idx1 := as_int(1)), - (q1 := py.indexing.GetItem(q.result, idx1.result)), - (idx2 := as_int(2)), - (q2 := py.indexing.GetItem(q.result, idx2.result)), - (idx3 := as_int(3)), - (q3 := py.indexing.GetItem(q.result, idx3.result)), - # get wires from qubits - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - (w2 := squin.wire.Unwrap(qubit=q2.result)), - (w3 := squin.wire.Unwrap(qubit=q3.result)), - # try Apply - (op0 := squin.op.stmts.S()), - (app0 := squin.wire.Apply(op0.result, w0.result)), - # try Broadcast - (op1 := squin.op.stmts.H()), - ( - broad0 := squin.wire.Broadcast( - op1.result, app0.results[0], w1.result, w2.result, w3.result - ) - ), - # wrap everything back - (squin.wire.Wrap(broad0.results[0], q0.result)), - (squin.wire.Wrap(broad0.results[1], q1.result)), - (squin.wire.Wrap(broad0.results[2], q2.result)), - (squin.wire.Wrap(broad0.results[3], q3.result)), - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_apply(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(1)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubit out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - # pass the wires through some 1 Qubit operators - (op1 := squin.op.stmts.S()), - (v0 := squin.wire.Apply(op1.result, w0.result)), - ( - squin.wire.Wrap(v0.results[0], q0.result) - ), # for wrap, just free a use for the result SSAval - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_apply.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_multiple_apply(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(1)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubit out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - # pass the wires through some 1 Qubit operators - (op1 := squin.op.stmts.S()), - (op2 := squin.op.stmts.H()), - (op3 := squin.op.stmts.Identity(sites=1)), - (op4 := squin.op.stmts.Identity(sites=1)), - (v0 := squin.wire.Apply(op1.result, w0.result)), - (v1 := squin.wire.Apply(op2.result, v0.results[0])), - (v2 := squin.wire.Apply(op3.result, v1.results[0])), - (v3 := squin.wire.Apply(op4.result, v2.results[0])), - ( - squin.wire.Wrap(v3.results[0], q0.result) - ), # for wrap, just free a use for the result SSAval - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_multiple_apply.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_broadcast(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(4)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - (idx1 := as_int(1)), - (q1 := py.indexing.GetItem(q.result, idx1.result)), - (idx2 := as_int(2)), - (q2 := py.indexing.GetItem(q.result, idx2.result)), - (idx3 := as_int(3)), - (q3 := py.indexing.GetItem(q.result, idx3.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - (w2 := squin.wire.Unwrap(qubit=q2.result)), - (w3 := squin.wire.Unwrap(qubit=q3.result)), - # Apply with stim semantics - (h_op := squin.op.stmts.H()), - ( - app_res := squin.wire.Broadcast( - h_op.result, w0.result, w1.result, w2.result, w3.result - ) - ), - # Wrap everything back - (squin.wire.Wrap(app_res.results[0], q0.result)), - (squin.wire.Wrap(app_res.results[1], q1.result)), - (squin.wire.Wrap(app_res.results[2], q2.result)), - (squin.wire.Wrap(app_res.results[3], q3.result)), - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_broadcast.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_broadcast_control(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(4)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - (idx1 := as_int(1)), - (q1 := py.indexing.GetItem(q.result, idx1.result)), - (idx2 := as_int(2)), - (q2 := py.indexing.GetItem(q.result, idx2.result)), - (idx3 := as_int(3)), - (q3 := py.indexing.GetItem(q.result, idx3.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - (w2 := squin.wire.Unwrap(qubit=q2.result)), - (w3 := squin.wire.Unwrap(qubit=q3.result)), - # Create and apply CX gate - (x_op := squin.op.stmts.X()), - (ctrl_x_op := squin.op.stmts.Control(x_op.result, n_controls=1)), - ( - app_res := squin.wire.Broadcast( - ctrl_x_op.result, w0.result, w1.result, w2.result, w3.result - ) - ), - # measure it all out - (squin.wire.Measure(wire=app_res.results[0], qubit=q0.result)), - (squin.wire.Measure(wire=app_res.results[1], qubit=q1.result)), - (squin.wire.Measure(wire=app_res.results[2], qubit=q2.result)), - (squin.wire.Measure(wire=app_res.results[3], qubit=q3.result)), - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_broadcast_control.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_apply_control(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(2)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubis out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - (idx1 := as_int(1)), - (q1 := py.indexing.GetItem(q.result, idx1.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - # set up control gate - (op1 := squin.op.stmts.X()), - (cx := squin.op.stmts.Control(op1.result, n_controls=1)), - (app := squin.wire.Apply(cx.result, w0.result, w1.result)), - # wrap things back - (squin.wire.Wrap(wire=app.results[0], qubit=q0.result)), - (squin.wire.Wrap(wire=app.results[1], qubit=q1.result)), - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_apply_control.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_measure(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(2)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubis out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - # Unwrap to get wires - (w0 := squin.wire.Unwrap(qubit=q0.result)), - # measure the wires out - (squin.wire.Measure(wire=w0.result, qubit=q0.result)), - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_measure.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_reset(): - stmts: list[ir.Statement] = [ - # Create qubit register - (n_qubits := as_int(1)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - # get wire - (w0 := squin.wire.Unwrap(q0.result)), - (res_op := squin.op.stmts.Reset()), - (app := squin.wire.Apply(res_op.result, w0.result)), - # wrap it back - (squin.wire.Measure(wire=app.results[0], qubit=q0.result)), - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_reset.stim") - assert codegen(test_method) == base_stim_prog.rstrip() - - -@pytest.mark.xfail -def test_wire_qubit_loss(): - - stmts: list[ir.Statement] = [ - (n_qubits := as_int(5)), - (q := squin.qubit.New(n_qubits=n_qubits.result)), - # Get qubits out - (idx0 := as_int(0)), - (q0 := py.indexing.GetItem(q.result, idx0.result)), - (idx1 := as_int(1)), - (q1 := py.indexing.GetItem(q.result, idx1.result)), - (idx2 := as_int(2)), - (q2 := py.indexing.GetItem(q.result, idx2.result)), - (idx3 := as_int(3)), - (q3 := py.indexing.GetItem(q.result, idx3.result)), - (idx4 := as_int(4)), - (q4 := py.indexing.GetItem(q.result, idx4.result)), - # get wires from qubits - (w0 := squin.wire.Unwrap(qubit=q0.result)), - (w1 := squin.wire.Unwrap(qubit=q1.result)), - (w2 := squin.wire.Unwrap(qubit=q2.result)), - (w3 := squin.wire.Unwrap(qubit=q3.result)), - (w4 := squin.wire.Unwrap(qubit=q4.result)), - (p_loss_0 := as_float(0.1)), - # apply and broadcast qubit loss - (ql_loss_0 := squin.noise.stmts.QubitLoss(p=p_loss_0.result)), - ( - app_0 := squin.wire.Broadcast( - ql_loss_0.result, w0.result, w1.result, w2.result, w3.result, w4.result - ) - ), - (p_loss_1 := as_float(0.9)), - (ql_loss_1 := squin.noise.stmts.QubitLoss(p=p_loss_1.result)), - (app_1 := squin.wire.Apply(ql_loss_1.result, app_0.results[0])), - # wrap everything back - (squin.wire.Measure(wire=app_1.results[0], qubit=q0.result)), - (squin.wire.Measure(wire=app_0.results[1], qubit=q1.result)), - (squin.wire.Measure(wire=app_0.results[2], qubit=q2.result)), - (squin.wire.Measure(wire=app_0.results[3], qubit=q3.result)), - (squin.wire.Measure(wire=app_0.results[4], qubit=q4.result)), - (ret_none := func.ConstantNone()), - (func.Return(ret_none)), - ] - - test_method = gen_func_from_stmts(stmts) - run_passes(test_method) - base_stim_prog = get_stim_reference_file("wire_qubit_loss.stim") - assert codegen(test_method) == base_stim_prog.rstrip() diff --git a/test/stim/passes/test_squin_qubit_to_stim.py b/test/stim/passes/test_squin_qubit_to_stim.py new file mode 100644 index 00000000..be3c403e --- /dev/null +++ b/test/stim/passes/test_squin_qubit_to_stim.py @@ -0,0 +1,248 @@ +import os +import math + +from kirin import ir +from kirin.dialects import py + +from bloqade import squin +from bloqade.squin import op, noise, qubit, kernel +from bloqade.stim.emit import EmitStimMain +from bloqade.stim.passes import SquinToStimPass + + +# Taken gratuitously from Kai's unit test +def codegen(mt: ir.Method): + # method should not have any arguments! + emit = EmitStimMain() + emit.initialize() + emit.run(mt=mt, args=()) + return emit.get_output() + + +def as_int(value: int): + return py.constant.Constant(value=value) + + +def as_float(value: float): + return py.constant.Constant(value=value) + + +def load_reference_program(filename): + path = os.path.join( + os.path.dirname(__file__), "stim_reference_programs", "qubit", filename + ) + with open(path, "r") as f: + return f.read() + + +def test_qubit(): + @kernel + def test(): + n_qubits = 2 + ql = qubit.new(n_qubits) + qubit.broadcast(op.h(), ql) + qubit.apply(op.x(), ql[0]) + ctrl = op.control(op.x(), n_controls=1) + qubit.apply(ctrl, ql[1], ql[0]) + # measure out + squin.qubit.measure(ql) + return + + test.print() + + SquinToStimPass(test.dialects)(test) + base_stim_prog = load_reference_program("qubit.stim") + + assert codegen(test) == base_stim_prog.rstrip() + + +def test_qubit_reset(): + @kernel + def test(): + n_qubits = 1 + q = qubit.new(n_qubits) + # reset the qubit + squin.qubit.apply(op.reset(), q[0]) + # measure out + squin.qubit.measure(q[0]) + return + + SquinToStimPass(test.dialects)(test) + base_stim_prog = load_reference_program("qubit_reset.stim") + + assert codegen(test) == base_stim_prog.rstrip() + + +def test_qubit_broadcast(): + @kernel + def test(): + n_qubits = 4 + ql = qubit.new(n_qubits) + # apply Hadamard to all qubits + squin.qubit.broadcast(op.h(), ql) + # measure out + squin.qubit.measure(ql) + return + + SquinToStimPass(test.dialects)(test) + base_stim_prog = load_reference_program("qubit_broadcast.stim") + + assert codegen(test) == base_stim_prog.rstrip() + + +def test_qubit_loss(): + @kernel + def test(): + n_qubits = 5 + ql = qubit.new(n_qubits) + # apply Hadamard to all qubits + squin.qubit.broadcast(op.h(), ql) + # apply and broadcast qubit loss + squin.qubit.apply(noise.qubit_loss(0.1), ql[3]) + squin.qubit.broadcast(noise.qubit_loss(0.05), ql) + # measure out + squin.qubit.measure(ql) + return + + SquinToStimPass(test.dialects)(test) + base_stim_prog = load_reference_program("qubit_loss.stim") + + assert codegen(test) == base_stim_prog.rstrip() + + +def test_u3_to_clifford(): + + @kernel + def test(): + n_qubits = 1 + q = qubit.new(n_qubits) + # apply U3 rotation that can be translated to a Clifford gate + squin.qubit.apply(op.u(0.25 * math.tau, 0.0 * math.tau, 0.5 * math.tau), q[0]) + # measure out + squin.qubit.measure(q) + return + + SquinToStimPass(test.dialects)(test) + + base_stim_prog = load_reference_program("u3_to_clifford.stim") + + assert codegen(test) == base_stim_prog.rstrip() + + +def test_sqrt_x_rewrite(): + + @squin.kernel + def test(): + q = qubit.new(1) + qubit.broadcast(op.sqrt_x(), q) + return + + SquinToStimPass(test.dialects)(test) + + assert codegen(test).strip() == "SQRT_X 0" + + +def test_sqrt_y_rewrite(): + + @squin.kernel + def test(): + q = qubit.new(1) + qubit.broadcast(op.sqrt_y(), q) + return + + SquinToStimPass(test.dialects)(test) + + assert codegen(test).strip() == "SQRT_Y 0" + + +def test_for_loop_nontrivial_index_rewrite(): + + @squin.kernel + def main(): + q =squin.qalloc(3) + squin.qubit.apply(squin.op.h(), q[0]) + cx = squin.op.cx() + for i in range(2): + squin.qubit.apply(cx, q[i], q[i + 1]) + + SquinToStimPass(main.dialects)(main) + base_stim_prog = load_reference_program("for_loop_nontrivial_index.stim") + + assert codegen(main) == base_stim_prog.rstrip() + + +def test_nested_for_loop_rewrite(): + + @squin.kernel + def main(): + q =squin.qalloc(5) + squin.qubit.apply(squin.op.h(), q[0]) + cx = squin.op.cx() + for i in range(2): + for j in range(2, 3): + squin.qubit.apply(cx, q[i], q[j]) + + SquinToStimPass(main.dialects)(main) + base_stim_prog = load_reference_program("nested_for_loop.stim") + + assert codegen(main) == base_stim_prog.rstrip() + + +def test_nested_list(): + + # NOTE: While SquinToStim now has the ability to handle + # the nested list outside of the kernel in this test, + # in general it will be necessary to explicitly + # annotate it as an IList so type inference can work + # properly. Otherwise its global, mutable nature means + # we cannot assume a static type. + + pairs = [[0, 1], [2, 3]] + + @squin.kernel + def main(): + q = qubit.new(10) + h = squin.op.h() + for i in range(2): + squin.qubit.apply(h, q[pairs[i][0]]) + + SquinToStimPass(main.dialects)(main) + + base_stim_prog = load_reference_program("nested_list.stim") + + assert codegen(main) == base_stim_prog.rstrip() + + +def test_pick_if_else(): + + @squin.kernel + def main(): + q = qubit.new(10) + if False: + qubit.apply(squin.op.h(), q[0]) + + if True: + qubit.apply(squin.op.h(), q[1]) + + SquinToStimPass(main.dialects)(main) + + base_stim_prog = load_reference_program("pick_if_else.stim") + + assert codegen(main) == base_stim_prog.rstrip() + + +def test_non_pure_loop_iterator(): + @kernel + def test_squin_kernel(): + q = qubit.new(5) + result = qubit.measure(q) + outputs = [] + for rnd in range(len(result)): # Non-pure loop iterator + outputs += [] + qubit.apply(op.x(), q[rnd]) # make sure body does something + return + + main = test_squin_kernel.similar() + SquinToStimPass(main.dialects)(main) + base_stim_prog = load_reference_program("non_pure_loop_iterator.stim") + assert codegen(main) == base_stim_prog.rstrip() diff --git a/test/stim/test_measure_id_analysis.py b/test/stim/test_measure_id_analysis.py index 81b00e60..8281356b 100644 --- a/test/stim/test_measure_id_analysis.py +++ b/test/stim/test_measure_id_analysis.py @@ -1,4 +1,4 @@ -from bloqade.squin import qubit, kernel +from bloqade.squin import qubit, kernel, qalloc from bloqade.analysis.measure_id import MeasurementIDAnalysis @@ -8,7 +8,7 @@ def test_linear_measure_analysis(): @kernel def main(): n_qubits = 4 - q = qubit.new(n_qubits) + q = qalloc(n_qubits) meas_res = qubit.measure(q) # very contrived tuple just to make sure impl for tuple @@ -26,7 +26,7 @@ def test_scf_measure_analysis(): @kernel def main(): n_qubits = 4 - q = qubit.new(n_qubits) + q = qalloc(n_qubits) meas_res = qubit.measure(q) if meas_res[0]: