From f09029fcfa73d418bfacc29f6d388e9d11e87b6e Mon Sep 17 00:00:00 2001 From: Phillip Weinberg Date: Tue, 28 Oct 2025 14:06:12 -0400 Subject: [PATCH 1/7] renaming dialect and folders for dialect --- src/bloqade/native/dialects/{gates => gate}/__init__.py | 0 src/bloqade/native/dialects/gate/_dialect.py | 3 +++ src/bloqade/native/dialects/{gates => gate}/_interface.py | 0 src/bloqade/native/dialects/{gates => gate}/stmts.py | 0 src/bloqade/native/dialects/gates/_dialect.py | 3 --- 5 files changed, 3 insertions(+), 3 deletions(-) rename src/bloqade/native/dialects/{gates => gate}/__init__.py (100%) create mode 100644 src/bloqade/native/dialects/gate/_dialect.py rename src/bloqade/native/dialects/{gates => gate}/_interface.py (100%) rename src/bloqade/native/dialects/{gates => gate}/stmts.py (100%) delete mode 100644 src/bloqade/native/dialects/gates/_dialect.py diff --git a/src/bloqade/native/dialects/gates/__init__.py b/src/bloqade/native/dialects/gate/__init__.py similarity index 100% rename from src/bloqade/native/dialects/gates/__init__.py rename to src/bloqade/native/dialects/gate/__init__.py diff --git a/src/bloqade/native/dialects/gate/_dialect.py b/src/bloqade/native/dialects/gate/_dialect.py new file mode 100644 index 00000000..873f9911 --- /dev/null +++ b/src/bloqade/native/dialects/gate/_dialect.py @@ -0,0 +1,3 @@ +from kirin import ir + +dialect = ir.Dialect("native.gate") diff --git a/src/bloqade/native/dialects/gates/_interface.py b/src/bloqade/native/dialects/gate/_interface.py similarity index 100% rename from src/bloqade/native/dialects/gates/_interface.py rename to src/bloqade/native/dialects/gate/_interface.py diff --git a/src/bloqade/native/dialects/gates/stmts.py b/src/bloqade/native/dialects/gate/stmts.py similarity index 100% rename from src/bloqade/native/dialects/gates/stmts.py rename to src/bloqade/native/dialects/gate/stmts.py diff --git a/src/bloqade/native/dialects/gates/_dialect.py b/src/bloqade/native/dialects/gates/_dialect.py deleted file mode 100644 index 7679809b..00000000 --- a/src/bloqade/native/dialects/gates/_dialect.py +++ /dev/null @@ -1,3 +0,0 @@ -from kirin import ir - -dialect = ir.Dialect("bloqade.native") From 27d7e2fcca45fb1a2ba3e4c583bfacad61f175ed Mon Sep 17 00:00:00 2001 From: Phillip Weinberg Date: Tue, 28 Oct 2025 14:09:56 -0400 Subject: [PATCH 2/7] updating the names of statement fields to match squin --- src/bloqade/native/dialects/gate/stmts.py | 8 ++++---- src/bloqade/pyqrack/native.py | 24 +++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/bloqade/native/dialects/gate/stmts.py b/src/bloqade/native/dialects/gate/stmts.py index 458af507..fee43d75 100644 --- a/src/bloqade/native/dialects/gate/stmts.py +++ b/src/bloqade/native/dialects/gate/stmts.py @@ -12,14 +12,14 @@ @statement(dialect=dialect) class CZ(ir.Statement): traits = frozenset({lowering.FromPythonCall()}) - ctrls: ir.SSAValue = info.argument(ilist.IListType[QubitType, N]) - qargs: ir.SSAValue = info.argument(ilist.IListType[QubitType, N]) + controls: ir.SSAValue = info.argument(ilist.IListType[QubitType, N]) + targets: ir.SSAValue = info.argument(ilist.IListType[QubitType, N]) @statement(dialect=dialect) class R(ir.Statement): traits = frozenset({lowering.FromPythonCall()}) - inputs: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) + qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) axis_angle: ir.SSAValue = info.argument(types.Float) rotation_angle: ir.SSAValue = info.argument(types.Float) @@ -27,5 +27,5 @@ class R(ir.Statement): @statement(dialect=dialect) class Rz(ir.Statement): traits = frozenset({lowering.FromPythonCall()}) - inputs: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) + qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) rotation_angle: ir.SSAValue = info.argument(types.Float) diff --git a/src/bloqade/pyqrack/native.py b/src/bloqade/pyqrack/native.py index c68ef8ac..e2a15de4 100644 --- a/src/bloqade/pyqrack/native.py +++ b/src/bloqade/pyqrack/native.py @@ -7,16 +7,16 @@ from pyqrack import Pauli from bloqade.pyqrack import PyQrackQubit from bloqade.pyqrack.base import PyQrackInterpreter -from bloqade.native.dialects import gates +from bloqade.native.dialects import gate -@gates.dialect.register(key="pyqrack") +@gate.dialect.register(key="pyqrack") class NativeMethods(interp.MethodTable): - @interp.impl(gates.CZ) - def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.CZ): - ctrls = frame.get_casted(stmt.ctrls, ilist.IList[PyQrackQubit, Any]) - qargs = frame.get_casted(stmt.qargs, ilist.IList[PyQrackQubit, Any]) + @interp.impl(gate.CZ) + def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.CZ): + ctrls = frame.get_casted(stmt.controls, ilist.IList[PyQrackQubit, Any]) + qargs = frame.get_casted(stmt.targets, ilist.IList[PyQrackQubit, Any]) for ctrl, qarg in zip(ctrls, qargs): if ctrl.is_active() and qarg.is_active(): @@ -24,9 +24,9 @@ def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.CZ): return () - @interp.impl(gates.R) - def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.R): - inputs = frame.get_casted(stmt.inputs, ilist.IList[PyQrackQubit, Any]) + @interp.impl(gate.R) + def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.R): + inputs = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float) axis_angle = 2 * math.pi * frame.get_casted(stmt.axis_angle, float) for qubit in inputs: @@ -37,9 +37,9 @@ def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.R): return () - @interp.impl(gates.Rz) - def rz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.Rz): - inputs = frame.get_casted(stmt.inputs, ilist.IList[PyQrackQubit, Any]) + @interp.impl(gate.Rz) + def rz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.Rz): + inputs = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float) for qubit in inputs: From 9dfcb34717f2624e69a06c847630474a441f2f19 Mon Sep 17 00:00:00 2001 From: Phillip Weinberg Date: Tue, 28 Oct 2025 14:13:40 -0400 Subject: [PATCH 3/7] making arguments order and names consistent with squin statements --- src/bloqade/native/dialects/gate/_interface.py | 8 ++++---- src/bloqade/native/dialects/gate/stmts.py | 4 ++-- src/bloqade/native/stdlib/broadcast.py | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/bloqade/native/dialects/gate/_interface.py b/src/bloqade/native/dialects/gate/_interface.py index 6d68a589..a36e2e9a 100644 --- a/src/bloqade/native/dialects/gate/_interface.py +++ b/src/bloqade/native/dialects/gate/_interface.py @@ -12,21 +12,21 @@ @lowering.wraps(CZ) def cz( - ctrls: ilist.IList[qubit.Qubit, Len], - qargs: ilist.IList[qubit.Qubit, Len], + controls: ilist.IList[qubit.Qubit, Len], + targets: ilist.IList[qubit.Qubit, Len], ): ... @lowering.wraps(R) def r( - inputs: ilist.IList[qubit.Qubit, typing.Any], axis_angle: float, rotation_angle: float, + qubits: ilist.IList[qubit.Qubit, typing.Any], ): ... @lowering.wraps(Rz) def rz( - inputs: ilist.IList[qubit.Qubit, typing.Any], rotation_angle: float, + qubits: ilist.IList[qubit.Qubit, typing.Any], ): ... diff --git a/src/bloqade/native/dialects/gate/stmts.py b/src/bloqade/native/dialects/gate/stmts.py index fee43d75..c73462e5 100644 --- a/src/bloqade/native/dialects/gate/stmts.py +++ b/src/bloqade/native/dialects/gate/stmts.py @@ -19,13 +19,13 @@ class CZ(ir.Statement): @statement(dialect=dialect) class R(ir.Statement): traits = frozenset({lowering.FromPythonCall()}) - qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) axis_angle: ir.SSAValue = info.argument(types.Float) rotation_angle: ir.SSAValue = info.argument(types.Float) + qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) @statement(dialect=dialect) class Rz(ir.Statement): traits = frozenset({lowering.FromPythonCall()}) - qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) rotation_angle: ir.SSAValue = info.argument(types.Float) + qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType, types.Any]) diff --git a/src/bloqade/native/stdlib/broadcast.py b/src/bloqade/native/stdlib/broadcast.py index e5a10ccc..e8942a9a 100644 --- a/src/bloqade/native/stdlib/broadcast.py +++ b/src/bloqade/native/stdlib/broadcast.py @@ -5,7 +5,7 @@ from bloqade import qubit from bloqade.native._prelude import kernel -from bloqade.native.dialects.gates import _interface as native +from bloqade.native.dialects.gate import _interface as native @kernel @@ -29,7 +29,7 @@ def rx(angle: float, qubits: ilist.IList[qubit.Qubit, Any]): angle (float): Rotation angle in radians. qubits (ilist.IList[qubit.Qubit, Any]): Target qubits. """ - native.r(qubits, 0.0, _radian_to_turn(angle)) + native.r(0.0, _radian_to_turn(angle), qubits) @kernel @@ -70,7 +70,7 @@ def ry(angle: float, qubits: ilist.IList[qubit.Qubit, Any]): angle (float): Rotation angle in radians. qubits (ilist.IList[qubit.Qubit, Any]): Target qubits. """ - native.r(qubits, 0.25, _radian_to_turn(angle)) + native.r(0.25, _radian_to_turn(angle), qubits) @kernel @@ -111,7 +111,7 @@ def rz(angle: float, qubits: ilist.IList[qubit.Qubit, Any]): angle (float): Rotation angle in radians. qubits (ilist.IList[qubit.Qubit, Any]): Target qubits. """ - native.rz(qubits, _radian_to_turn(angle)) + native.rz(_radian_to_turn(angle), qubits) @kernel From 78f5d2b842bd44d23108b188dc8acac0a00f84f9 Mon Sep 17 00:00:00 2001 From: Phillip Weinberg Date: Tue, 28 Oct 2025 14:17:58 -0400 Subject: [PATCH 4/7] renaming variables in method table --- src/bloqade/pyqrack/native.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/bloqade/pyqrack/native.py b/src/bloqade/pyqrack/native.py index e2a15de4..1e652411 100644 --- a/src/bloqade/pyqrack/native.py +++ b/src/bloqade/pyqrack/native.py @@ -15,21 +15,21 @@ class NativeMethods(interp.MethodTable): @interp.impl(gate.CZ) def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.CZ): - ctrls = frame.get_casted(stmt.controls, ilist.IList[PyQrackQubit, Any]) - qargs = frame.get_casted(stmt.targets, ilist.IList[PyQrackQubit, Any]) + controls = frame.get_casted(stmt.controls, ilist.IList[PyQrackQubit, Any]) + targets = frame.get_casted(stmt.targets, ilist.IList[PyQrackQubit, Any]) - for ctrl, qarg in zip(ctrls, qargs): - if ctrl.is_active() and qarg.is_active(): - ctrl.sim_reg.mcz([ctrl.addr], qarg.addr) + for ctrl, trgt in zip(controls, targets): + if ctrl.is_active() and trgt.is_active(): + ctrl.sim_reg.mcz([ctrl.addr], trgt.addr) return () @interp.impl(gate.R) def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.R): - inputs = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) + qubits = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float) axis_angle = 2 * math.pi * frame.get_casted(stmt.axis_angle, float) - for qubit in inputs: + for qubit in qubits: if qubit.is_active(): qubit.sim_reg.r(Pauli.PauliZ, axis_angle, qubit.addr) qubit.sim_reg.r(Pauli.PauliX, rotation_angle, qubit.addr) @@ -39,10 +39,10 @@ def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.R): @interp.impl(gate.Rz) def rz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.Rz): - inputs = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) + qubits = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float) - for qubit in inputs: + for qubit in qubits: if qubit.is_active(): qubit.sim_reg.r(Pauli.PauliZ, rotation_angle, qubit.addr) From 4b35f8aa62d7103107114d9e61907921bebc76df Mon Sep 17 00:00:00 2001 From: Phillip Weinberg Date: Wed, 29 Oct 2025 16:01:03 -0400 Subject: [PATCH 5/7] fixing tests --- src/bloqade/native/_prelude.py | 4 ++-- test/native/upstream/test_squin2native.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bloqade/native/_prelude.py b/src/bloqade/native/_prelude.py index 0776de0c..e9f42b99 100644 --- a/src/bloqade/native/_prelude.py +++ b/src/bloqade/native/_prelude.py @@ -7,10 +7,10 @@ from bloqade import qubit -from .dialects import gates +from .dialects import gate -@ir.dialect_group(structural_no_opt.union([gates, qubit])) +@ir.dialect_group(structural_no_opt.union([gate, qubit])) def kernel(self): """Compile a function to a native kernel.""" diff --git a/test/native/upstream/test_squin2native.py b/test/native/upstream/test_squin2native.py index 4a823905..7d250e67 100644 --- a/test/native/upstream/test_squin2native.py +++ b/test/native/upstream/test_squin2native.py @@ -5,7 +5,7 @@ from bloqade import squin from bloqade.squin import gate from bloqade.pyqrack import StackMemorySimulator -from bloqade.native.dialects import gates +from bloqade.native.dialects import gate as native_gate from bloqade.native.upstream import GateRule, SquinToNative @@ -33,14 +33,14 @@ def main(): new_main = SquinToNative().emit(main, no_raise=True) new_callgraph = callgraph.CallGraph(new_main) - # make sure all kernels have been converted to native gates + # make sure all kernels have been converted to native gate all_kernels = (ker for kers in new_callgraph.defs.values() for ker in kers) for ker in all_kernels: assert gate.dialect not in ker.dialects - assert gates.dialect in ker.dialects + assert native_gate.dialect in ker.dialects # test to make sure the statevectors are the same - # before and after conversion to native gates + # before and after conversion to native gate 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]) From 1ef747bb8fea406353df80fdee10243b589eaa3e Mon Sep 17 00:00:00 2001 From: Phillip Weinberg Date: Thu, 30 Oct 2025 08:17:34 -0400 Subject: [PATCH 6/7] removing export of statements --- src/bloqade/native/dialects/gate/__init__.py | 1 - src/bloqade/pyqrack/native.py | 16 ++++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/bloqade/native/dialects/gate/__init__.py b/src/bloqade/native/dialects/gate/__init__.py index 34d5f8df..210cc4ee 100644 --- a/src/bloqade/native/dialects/gate/__init__.py +++ b/src/bloqade/native/dialects/gate/__init__.py @@ -1,3 +1,2 @@ -from .stmts import CZ as CZ, R as R, Rz as Rz from ._dialect import dialect as dialect from ._interface import r as r, cz as cz, rz as rz diff --git a/src/bloqade/pyqrack/native.py b/src/bloqade/pyqrack/native.py index 1e652411..88b26119 100644 --- a/src/bloqade/pyqrack/native.py +++ b/src/bloqade/pyqrack/native.py @@ -7,14 +7,14 @@ from pyqrack import Pauli from bloqade.pyqrack import PyQrackQubit from bloqade.pyqrack.base import PyQrackInterpreter -from bloqade.native.dialects import gate +from bloqade.native.dialects.gate import stmts -@gate.dialect.register(key="pyqrack") +@stmts.dialect.register(key="pyqrack") class NativeMethods(interp.MethodTable): - @interp.impl(gate.CZ) - def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.CZ): + @interp.impl(stmts.CZ) + def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: stmts.CZ): controls = frame.get_casted(stmt.controls, ilist.IList[PyQrackQubit, Any]) targets = frame.get_casted(stmt.targets, ilist.IList[PyQrackQubit, Any]) @@ -24,8 +24,8 @@ def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.CZ): return () - @interp.impl(gate.R) - def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.R): + @interp.impl(stmts.R) + def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: stmts.R): qubits = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float) axis_angle = 2 * math.pi * frame.get_casted(stmt.axis_angle, float) @@ -37,8 +37,8 @@ def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.R): return () - @interp.impl(gate.Rz) - def rz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gate.Rz): + @interp.impl(stmts.Rz) + def rz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: stmts.Rz): qubits = frame.get_casted(stmt.qubits, ilist.IList[PyQrackQubit, Any]) rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float) From 6a6cd1c57ca805ba7d08e39ca6afd40264f2a1c4 Mon Sep 17 00:00:00 2001 From: Phillip Weinberg Date: Thu, 30 Oct 2025 08:21:21 -0400 Subject: [PATCH 7/7] fixing imports --- src/bloqade/native/dialects/gate/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bloqade/native/dialects/gate/__init__.py b/src/bloqade/native/dialects/gate/__init__.py index 210cc4ee..79898df3 100644 --- a/src/bloqade/native/dialects/gate/__init__.py +++ b/src/bloqade/native/dialects/gate/__init__.py @@ -1,2 +1,2 @@ +from . import stmts as stmts from ._dialect import dialect as dialect -from ._interface import r as r, cz as cz, rz as rz