bloqade-circuit 0.7.3__py3-none-any.whl → 0.7.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bloqade-circuit might be problematic. Click here for more details.

@@ -0,0 +1,24 @@
1
+ from .stdlib import broadcast as broadcast
2
+ from ._prelude import kernel as kernel
3
+ from .stdlib.simple import (
4
+ h as h,
5
+ s as s,
6
+ t as t,
7
+ x as x,
8
+ y as y,
9
+ z as z,
10
+ cx as cx,
11
+ cy as cy,
12
+ cz as cz,
13
+ rx as rx,
14
+ ry as ry,
15
+ rz as rz,
16
+ u3 as u3,
17
+ rot as rot,
18
+ s_dag as s_dag,
19
+ shift as shift,
20
+ sqrt_x as sqrt_x,
21
+ sqrt_y as sqrt_y,
22
+ sqrt_x_adj as sqrt_x_adj,
23
+ sqrt_y_adj as sqrt_y_adj,
24
+ )
@@ -0,0 +1,45 @@
1
+ from typing import Annotated
2
+
3
+ from kirin import ir
4
+ from kirin.passes import Default
5
+ from kirin.prelude import structural_no_opt
6
+ from typing_extensions import Doc
7
+
8
+ from bloqade.squin import qubit
9
+
10
+ from .dialects import gates
11
+
12
+
13
+ @ir.dialect_group(structural_no_opt.union([gates, qubit]))
14
+ def kernel(self):
15
+ """Compile a function to a native kernel."""
16
+
17
+ def run_pass(
18
+ mt,
19
+ *,
20
+ verify: Annotated[
21
+ bool, Doc("run `verify` before running passes, default is `True`")
22
+ ] = True,
23
+ typeinfer: Annotated[
24
+ bool,
25
+ Doc(
26
+ "run type inference and apply the inferred type to IR, default `False`"
27
+ ),
28
+ ] = False,
29
+ fold: Annotated[bool, Doc("run folding passes")] = True,
30
+ aggressive: Annotated[
31
+ bool, Doc("run aggressive folding passes if `fold=True`")
32
+ ] = False,
33
+ no_raise: Annotated[bool, Doc("do not raise exception during analysis")] = True,
34
+ ) -> None:
35
+ default_pass = Default(
36
+ self,
37
+ verify=verify,
38
+ fold=fold,
39
+ aggressive=aggressive,
40
+ typeinfer=typeinfer,
41
+ no_raise=no_raise,
42
+ )
43
+ default_pass.fixpoint(mt)
44
+
45
+ return run_pass
File without changes
@@ -0,0 +1,3 @@
1
+ from .stmts import CZ as CZ, R as R, Rz as Rz
2
+ from ._dialect import dialect as dialect
3
+ from ._interface import r as r, cz as cz, rz as rz
@@ -0,0 +1,3 @@
1
+ from kirin import ir
2
+
3
+ dialect = ir.Dialect("bloqade.native")
@@ -0,0 +1,32 @@
1
+ import typing
2
+
3
+ from kirin import lowering
4
+ from kirin.dialects import ilist
5
+
6
+ from bloqade.squin import qubit
7
+
8
+ from .stmts import CZ, R, Rz
9
+
10
+ Len = typing.TypeVar("Len")
11
+
12
+
13
+ @lowering.wraps(CZ)
14
+ def cz(
15
+ ctrls: ilist.IList[qubit.Qubit, Len],
16
+ qargs: ilist.IList[qubit.Qubit, Len],
17
+ ): ...
18
+
19
+
20
+ @lowering.wraps(R)
21
+ def r(
22
+ inputs: ilist.IList[qubit.Qubit, typing.Any],
23
+ axis_angle: float,
24
+ rotation_angle: float,
25
+ ): ...
26
+
27
+
28
+ @lowering.wraps(Rz)
29
+ def rz(
30
+ inputs: ilist.IList[qubit.Qubit, typing.Any],
31
+ rotation_angle: float,
32
+ ): ...
@@ -0,0 +1,31 @@
1
+ from kirin import ir, types, lowering
2
+ from kirin.decl import info, statement
3
+ from kirin.dialects import ilist
4
+
5
+ from bloqade.squin import qubit
6
+
7
+ from ._dialect import dialect
8
+
9
+ N = types.TypeVar("N")
10
+
11
+
12
+ @statement(dialect=dialect)
13
+ class CZ(ir.Statement):
14
+ traits = frozenset({lowering.FromPythonCall()})
15
+ ctrls: ir.SSAValue = info.argument(ilist.IListType[qubit.QubitType, N])
16
+ qargs: ir.SSAValue = info.argument(ilist.IListType[qubit.QubitType, N])
17
+
18
+
19
+ @statement(dialect=dialect)
20
+ class R(ir.Statement):
21
+ traits = frozenset({lowering.FromPythonCall()})
22
+ inputs: ir.SSAValue = info.argument(ilist.IListType[qubit.QubitType, types.Any])
23
+ axis_angle: ir.SSAValue = info.argument(types.Float)
24
+ rotation_angle: ir.SSAValue = info.argument(types.Float)
25
+
26
+
27
+ @statement(dialect=dialect)
28
+ class Rz(ir.Statement):
29
+ traits = frozenset({lowering.FromPythonCall()})
30
+ inputs: ir.SSAValue = info.argument(ilist.IListType[qubit.QubitType, types.Any])
31
+ rotation_angle: ir.SSAValue = info.argument(types.Float)
File without changes
@@ -0,0 +1,246 @@
1
+ import math
2
+ from typing import Any, TypeVar
3
+
4
+ from kirin.dialects import ilist
5
+
6
+ from bloqade.squin import qubit
7
+ from bloqade.native._prelude import kernel
8
+ from bloqade.native.dialects.gates import _interface as native
9
+
10
+
11
+ @kernel
12
+ def _radian_to_turn(angle: float) -> float:
13
+ """Convert an angle from radians to turns.
14
+
15
+ Args:
16
+ angle (float): Angle in radians.
17
+
18
+ Returns:
19
+ float: Equivalent angle in turns.
20
+ """
21
+ return angle / (2 * math.pi)
22
+
23
+
24
+ @kernel
25
+ def rx(angle: float, qubits: ilist.IList[qubit.Qubit, Any]):
26
+ """Apply an RX rotation gate on a group of qubits.
27
+
28
+ Args:
29
+ angle (float): Rotation angle in radians.
30
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
31
+ """
32
+ native.r(qubits, 0.0, _radian_to_turn(angle))
33
+
34
+
35
+ @kernel
36
+ def x(qubits: ilist.IList[qubit.Qubit, Any]):
37
+ """Apply a Pauli-X gate on a group of qubits.
38
+
39
+ Args:
40
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
41
+ """
42
+ rx(math.pi, qubits)
43
+
44
+
45
+ @kernel
46
+ def sqrt_x(qubits: ilist.IList[qubit.Qubit, Any]):
47
+ """Apply a sqrt(X) gate on a group of qubits.
48
+
49
+ Args:
50
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
51
+ """
52
+ rx(math.pi / 2.0, qubits)
53
+
54
+
55
+ @kernel
56
+ def sqrt_x_adj(qubits: ilist.IList[qubit.Qubit, Any]):
57
+ """Apply the adjoint of sqrt(X) on a group of qubits.
58
+
59
+ Args:
60
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
61
+ """
62
+ rx(-math.pi / 2.0, qubits)
63
+
64
+
65
+ @kernel
66
+ def ry(angle: float, qubits: ilist.IList[qubit.Qubit, Any]):
67
+ """Apply an RY rotation gate on a group of qubits.
68
+
69
+ Args:
70
+ angle (float): Rotation angle in radians.
71
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
72
+ """
73
+ native.r(qubits, 0.25, _radian_to_turn(angle))
74
+
75
+
76
+ @kernel
77
+ def y(qubits: ilist.IList[qubit.Qubit, Any]):
78
+ """Apply a Pauli-Y gate on a group of qubits.
79
+
80
+ Args:
81
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
82
+ """
83
+ ry(math.pi, qubits)
84
+
85
+
86
+ @kernel
87
+ def sqrt_y(qubits: ilist.IList[qubit.Qubit, Any]):
88
+ """Apply a sqrt(Y) gate on a group of qubits.
89
+
90
+ Args:
91
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
92
+ """
93
+ ry(-math.pi / 2.0, qubits)
94
+
95
+
96
+ @kernel
97
+ def sqrt_y_adj(qubits: ilist.IList[qubit.Qubit, Any]):
98
+ """Apply the adjoint of sqrt(Y) on a group of qubits.
99
+
100
+ Args:
101
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
102
+ """
103
+ ry(math.pi / 2.0, qubits)
104
+
105
+
106
+ @kernel
107
+ def rz(angle: float, qubits: ilist.IList[qubit.Qubit, Any]):
108
+ """Apply an RZ rotation gate on a group of qubits.
109
+
110
+ Args:
111
+ angle (float): Rotation angle in radians.
112
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
113
+ """
114
+ native.rz(qubits, _radian_to_turn(angle))
115
+
116
+
117
+ @kernel
118
+ def z(qubits: ilist.IList[qubit.Qubit, Any]):
119
+ """Apply a Pauli-Z gate on a group of qubits.
120
+
121
+ Args:
122
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
123
+ """
124
+ rz(math.pi, qubits)
125
+
126
+
127
+ @kernel
128
+ def s(qubits: ilist.IList[qubit.Qubit, Any]):
129
+ """Apply an S gate on a group of qubits.
130
+
131
+ Args:
132
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
133
+ """
134
+ rz(math.pi / 2.0, qubits)
135
+
136
+
137
+ @kernel
138
+ def s_adj(qubits: ilist.IList[qubit.Qubit, Any]):
139
+ """Apply the adjoint of the S gate on a group of qubits.
140
+
141
+ Args:
142
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
143
+ """
144
+ rz(-math.pi / 2.0, qubits)
145
+
146
+
147
+ @kernel
148
+ def h(qubits: ilist.IList[qubit.Qubit, Any]):
149
+ """Apply a Hadamard gate on a group of qubits.
150
+
151
+ Args:
152
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
153
+ """
154
+ s(qubits)
155
+ sqrt_x(qubits)
156
+ s(qubits)
157
+
158
+
159
+ @kernel
160
+ def t(qubits: ilist.IList[qubit.Qubit, Any]):
161
+ """Apply a T gate on a group of qubits.
162
+
163
+ Args:
164
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
165
+ """
166
+ rz(math.pi / 4.0, qubits)
167
+
168
+
169
+ @kernel
170
+ def shift(angle: float, qubits: ilist.IList[qubit.Qubit, Any]):
171
+ """Apply a phase shift to the |1> state on a group of qubits.
172
+
173
+ Args:
174
+ angle (float): Phase shift angle in radians.
175
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
176
+ """
177
+ rz(angle / 2.0, qubits)
178
+
179
+
180
+ @kernel
181
+ def rot(phi: float, theta: float, omega: float, qubits: ilist.IList[qubit.Qubit, Any]):
182
+ """Apply a general single-qubit rotation on a group of qubits.
183
+
184
+ Args:
185
+ phi (float): Z rotation before Y (radians).
186
+ theta (float): Y rotation (radians).
187
+ omega (float): Z rotation after Y (radians).
188
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
189
+ """
190
+ rz(phi, qubits)
191
+ ry(theta, qubits)
192
+ rz(omega, qubits)
193
+
194
+
195
+ @kernel
196
+ def u3(theta: float, phi: float, lam: float, qubits: ilist.IList[qubit.Qubit, Any]):
197
+ """Apply the U3 gate on a group of qubits.
198
+
199
+ Args:
200
+ theta (float): Rotation around Y axis (radians).
201
+ phi (float): Global phase shift component (radians).
202
+ lam (float): Z rotations in decomposition (radians).
203
+ qubits (ilist.IList[qubit.Qubit, Any]): Target qubits.
204
+ """
205
+ rot(lam, theta, -lam, qubits)
206
+ shift(phi + lam, qubits)
207
+
208
+
209
+ N = TypeVar("N")
210
+
211
+
212
+ @kernel
213
+ def cz(controls: ilist.IList[qubit.Qubit, N], qubits: ilist.IList[qubit.Qubit, N]):
214
+ """Apply a controlled-Z gate on a pairs of qubits.
215
+
216
+ Args:
217
+ controls (ilist.IList[qubit.Qubit, N]): Control qubits.
218
+ qubits (ilist.IList[qubit.Qubit, N]): Target qubits.
219
+ """
220
+ native.cz(controls, qubits)
221
+
222
+
223
+ @kernel
224
+ def cx(controls: ilist.IList[qubit.Qubit, N], targets: ilist.IList[qubit.Qubit, N]):
225
+ """Apply a controlled-X gate on a pairs of qubits.
226
+
227
+ Args:
228
+ controls (ilist.IList[qubit.Qubit, N]): Control qubits.
229
+ targets (ilist.IList[qubit.Qubit, N]): Target qubits.
230
+ """
231
+ sqrt_y_adj(targets)
232
+ cz(controls, targets)
233
+ sqrt_y(targets)
234
+
235
+
236
+ @kernel
237
+ def cy(controls: ilist.IList[qubit.Qubit, N], targets: ilist.IList[qubit.Qubit, N]):
238
+ """Apply a controlled-Y gate on a pairs of qubits.
239
+
240
+ Args:
241
+ controls (ilist.IList[qubit.Qubit, N]): Control qubits.
242
+ targets (ilist.IList[qubit.Qubit, N]): Target qubits.
243
+ """
244
+ sqrt_x(targets)
245
+ cz(controls, targets)
246
+ sqrt_x_adj(targets)
@@ -0,0 +1,219 @@
1
+ from kirin.dialects import ilist
2
+
3
+ from bloqade.squin import qubit
4
+
5
+ from . import broadcast
6
+ from .._prelude import kernel
7
+
8
+
9
+ @kernel
10
+ def rx(angle: float, qubit: qubit.Qubit):
11
+ """Apply an RX rotation gate on a single qubit.
12
+
13
+ Args:
14
+ angle (float): Rotation angle in radians.
15
+ qubit (qubit.Qubit): The qubit to apply the rotation to.
16
+ """
17
+ broadcast.rx(angle, ilist.IList([qubit]))
18
+
19
+
20
+ @kernel
21
+ def x(qubit: qubit.Qubit):
22
+ """Apply a Pauli-X gate on a single qubit.
23
+
24
+ Args:
25
+ qubit (qubit.Qubit): The qubit to apply the X gate to.
26
+ """
27
+ broadcast.x(ilist.IList([qubit]))
28
+
29
+
30
+ @kernel
31
+ def sqrt_x(qubit: qubit.Qubit):
32
+ """Apply a sqrt(X) gate on a single qubit.
33
+
34
+ Args:
35
+ qubit (qubit.Qubit): The qubit to apply the sqrt(X) gate to.
36
+ """
37
+ broadcast.sqrt_x(ilist.IList([qubit]))
38
+
39
+
40
+ @kernel
41
+ def sqrt_x_adj(qubit: qubit.Qubit):
42
+ """Apply the adjoint of sqrt(X) on a single qubit.
43
+
44
+ Args:
45
+ qubit (qubit.Qubit): The qubit to apply the adjoint sqrt(X) gate to.
46
+ """
47
+ broadcast.sqrt_x_adj(ilist.IList([qubit]))
48
+
49
+
50
+ @kernel
51
+ def ry(angle: float, qubit: qubit.Qubit):
52
+ """Apply an RY rotation gate on a single qubit.
53
+
54
+ Args:
55
+ angle (float): Rotation angle in radians.
56
+ qubit (qubit.Qubit): The qubit to apply the rotation to.
57
+ """
58
+ broadcast.ry(angle, ilist.IList([qubit]))
59
+
60
+
61
+ @kernel
62
+ def y(qubit: qubit.Qubit):
63
+ """Apply a Pauli-Y gate on a single qubit.
64
+
65
+ Args:
66
+ qubit (qubit.Qubit): The qubit to apply the Y gate to.
67
+ """
68
+ broadcast.y(ilist.IList([qubit]))
69
+
70
+
71
+ @kernel
72
+ def sqrt_y(qubit: qubit.Qubit):
73
+ """Apply a sqrt(Y) gate on a single qubit.
74
+
75
+ Args:
76
+ qubit (qubit.Qubit): The qubit to apply the sqrt(Y) gate to.
77
+ """
78
+ broadcast.sqrt_y(ilist.IList([qubit]))
79
+
80
+
81
+ @kernel
82
+ def sqrt_y_adj(qubit: qubit.Qubit):
83
+ """Apply the adjoint of sqrt(Y) on a single qubit.
84
+
85
+ Args:
86
+ qubit (qubit.Qubit): The qubit to apply the adjoint sqrt(Y) gate to.
87
+ """
88
+ broadcast.sqrt_y_adj(ilist.IList([qubit]))
89
+
90
+
91
+ @kernel
92
+ def rz(angle: float, qubit: qubit.Qubit):
93
+ """Apply an RZ rotation gate on a single qubit.
94
+
95
+ Args:
96
+ angle (float): Rotation angle in radians.
97
+ qubit (qubit.Qubit): The qubit to apply the rotation to.
98
+ """
99
+ broadcast.rz(angle, ilist.IList([qubit]))
100
+
101
+
102
+ @kernel
103
+ def z(qubit: qubit.Qubit):
104
+ """Apply a Pauli-Z gate on a single qubit.
105
+
106
+ Args:
107
+ qubit (qubit.Qubit): The qubit to apply the Z gate to.
108
+ """
109
+ broadcast.z(ilist.IList([qubit]))
110
+
111
+
112
+ @kernel
113
+ def s(qubit: qubit.Qubit):
114
+ """Apply an S gate on a single qubit.
115
+
116
+ Args:
117
+ qubit (qubit.Qubit): The qubit to apply the S gate to.
118
+ """
119
+ broadcast.s(ilist.IList([qubit]))
120
+
121
+
122
+ @kernel
123
+ def s_dag(qubit: qubit.Qubit):
124
+ """Apply the adjoint of the S gate on a single qubit.
125
+
126
+ Args:
127
+ qubit (qubit.Qubit): The qubit to apply the adjoint S gate to.
128
+ """
129
+ broadcast.s_adj(ilist.IList([qubit]))
130
+
131
+
132
+ @kernel
133
+ def h(qubit: qubit.Qubit):
134
+ """Apply a Hadamard gate on a single qubit.
135
+
136
+ Args:
137
+ qubit (qubit.Qubit): The qubit to apply the Hadamard gate to.
138
+ """
139
+ broadcast.h(ilist.IList([qubit]))
140
+
141
+
142
+ @kernel
143
+ def t(qubit: qubit.Qubit):
144
+ """Apply a T gate on a single qubit.
145
+
146
+ Args:
147
+ qubit (qubit.Qubit): The qubit to apply the T gate to.
148
+ """
149
+ broadcast.t(ilist.IList([qubit]))
150
+
151
+
152
+ @kernel
153
+ def shift(angle: float, qubit: qubit.Qubit):
154
+ """Apply a phase shift on the |1> state of a single qubit.
155
+
156
+ Args:
157
+ angle (float): Shift angle in radians.
158
+ qubit (qubit.Qubit): The qubit to apply the shift to.
159
+ """
160
+ broadcast.shift(angle, ilist.IList([qubit]))
161
+
162
+
163
+ @kernel
164
+ def rot(phi: float, theta: float, omega: float, qubit: qubit.Qubit):
165
+ """Apply a general single-qubit rotation on a single qubit.
166
+
167
+ Args:
168
+ phi (float): Z rotation before Y (radians).
169
+ theta (float): Y rotation (radians).
170
+ omega (float): Z rotation after Y (radians).
171
+ qubit (qubit.Qubit): The qubit to apply the rotation to.
172
+ """
173
+ broadcast.rot(phi, theta, omega, ilist.IList([qubit]))
174
+
175
+
176
+ @kernel
177
+ def u3(theta: float, phi: float, lam: float, qubit: qubit.Qubit):
178
+ """Apply the U3 gate on a single qubit.
179
+
180
+ Args:
181
+ theta (float): Rotation angle around the Y axis in radians.
182
+ phi (float): Rotation angle around the Z axis in radians.
183
+ lam (float): Rotation angle around the Z axis in radians.
184
+ qubit (qubit.Qubit): The qubit to apply the U3 gate to.
185
+ """
186
+ broadcast.u3(theta, phi, lam, ilist.IList([qubit]))
187
+
188
+
189
+ @kernel
190
+ def cz(control: qubit.Qubit, target: qubit.Qubit):
191
+ """Apply a controlled-Z gate on two qubits.
192
+
193
+ Args:
194
+ control (qubit.Qubit): The control qubit.
195
+ target (qubit.Qubit): The target qubit.
196
+ """
197
+ broadcast.cz(ilist.IList([control]), ilist.IList([target]))
198
+
199
+
200
+ @kernel
201
+ def cx(control: qubit.Qubit, target: qubit.Qubit):
202
+ """Apply a controlled-X gate on two qubits.
203
+
204
+ Args:
205
+ control (qubit.Qubit): The control qubit.
206
+ target (qubit.Qubit): The target qubit.
207
+ """
208
+ broadcast.cx(ilist.IList([control]), ilist.IList([target]))
209
+
210
+
211
+ @kernel
212
+ def cy(control: qubit.Qubit, targets: qubit.Qubit):
213
+ """Apply a controlled-Y gate on two qubits.
214
+
215
+ Args:
216
+ control (qubit.Qubit): The control qubit.
217
+ targets (qubit.Qubit): The target qubit.
218
+ """
219
+ broadcast.cy(ilist.IList([control]), ilist.IList([targets]))
@@ -21,4 +21,5 @@ from .device import (
21
21
  StackMemorySimulator as StackMemorySimulator,
22
22
  DynamicMemorySimulator as DynamicMemorySimulator,
23
23
  )
24
+ from .native import NativeMethods as NativeMethods
24
25
  from .target import PyQrack as PyQrack
@@ -0,0 +1,49 @@
1
+ import math
2
+ from typing import Any
3
+
4
+ from kirin import interp
5
+ from kirin.dialects import ilist
6
+
7
+ from pyqrack import Pauli
8
+ from bloqade.pyqrack import PyQrackQubit
9
+ from bloqade.pyqrack.base import PyQrackInterpreter
10
+ from bloqade.native.dialects import gates
11
+
12
+
13
+ @gates.dialect.register(key="pyqrack")
14
+ class NativeMethods(interp.MethodTable):
15
+
16
+ @interp.impl(gates.CZ)
17
+ def cz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.CZ):
18
+ ctrls = frame.get_casted(stmt.ctrls, ilist.IList[PyQrackQubit, Any])
19
+ qargs = frame.get_casted(stmt.qargs, ilist.IList[PyQrackQubit, Any])
20
+
21
+ for ctrl, qarg in zip(ctrls, qargs):
22
+ if ctrl.is_active() and qarg.is_active():
23
+ ctrl.sim_reg.mcz([ctrl.addr], qarg.addr)
24
+
25
+ return ()
26
+
27
+ @interp.impl(gates.R)
28
+ def r(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.R):
29
+ inputs = frame.get_casted(stmt.inputs, ilist.IList[PyQrackQubit, Any])
30
+ rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float)
31
+ axis_angle = 2 * math.pi * frame.get_casted(stmt.axis_angle, float)
32
+ for qubit in inputs:
33
+ if qubit.is_active():
34
+ qubit.sim_reg.r(Pauli.PauliZ, axis_angle, qubit.addr)
35
+ qubit.sim_reg.r(Pauli.PauliX, rotation_angle, qubit.addr)
36
+ qubit.sim_reg.r(Pauli.PauliZ, -axis_angle, qubit.addr)
37
+
38
+ return ()
39
+
40
+ @interp.impl(gates.Rz)
41
+ def rz(self, _interp: PyQrackInterpreter, frame: interp.Frame, stmt: gates.Rz):
42
+ inputs = frame.get_casted(stmt.inputs, ilist.IList[PyQrackQubit, Any])
43
+ rotation_angle = 2 * math.pi * frame.get_casted(stmt.rotation_angle, float)
44
+
45
+ for qubit in inputs:
46
+ if qubit.is_active():
47
+ qubit.sim_reg.r(Pauli.PauliZ, rotation_angle, qubit.addr)
48
+
49
+ return ()
@@ -36,11 +36,9 @@ class EmitCirqQubitMethods(MethodTable):
36
36
  op = frame.get(stmt.operator)
37
37
  qbit_lists = [frame.get(qbit) for qbit in stmt.qubits]
38
38
 
39
- cirq_ops = []
40
39
  for qbits in zip(*qbit_lists):
41
- cirq_ops.extend(op.apply(qbits))
40
+ frame.circuit.append(op.apply(qbits))
42
41
 
43
- frame.circuit.append(cirq.Moment(cirq_ops))
44
42
  return ()
45
43
 
46
44
  @impl(qubit.MeasureQubit)
@@ -1,5 +1,4 @@
1
1
  from .squin_to_stim import (
2
2
  SquinToStimPass as SquinToStimPass,
3
3
  StimSimplifyIfs as StimSimplifyIfs,
4
- AggressiveForLoopUnroll as AggressiveForLoopUnroll,
5
4
  )
@@ -1,23 +1,21 @@
1
1
  from dataclasses import dataclass
2
2
 
3
- from kirin.passes import Fold, HintConst, TypeInfer
3
+ from kirin.passes import Fold, TypeInfer
4
4
  from kirin.rewrite import (
5
5
  Walk,
6
6
  Chain,
7
7
  Fixpoint,
8
8
  CFGCompactify,
9
- InlineGetItem,
10
- InlineGetField,
11
9
  DeadCodeElimination,
12
10
  CommonSubexpressionElimination,
13
11
  )
14
- from kirin.dialects import scf, ilist
12
+ from kirin.dialects import ilist
15
13
  from kirin.ir.method import Method
16
14
  from kirin.passes.abc import Pass
17
15
  from kirin.rewrite.abc import RewriteResult
18
16
  from kirin.passes.inline import InlinePass
19
17
  from kirin.rewrite.alias import InlineAlias
20
- from kirin.dialects.scf.unroll import PickIfElse
18
+ from kirin.passes.aggressive import UnrollScf
21
19
 
22
20
  from bloqade.stim.rewrite import (
23
21
  SquinWireToStim,
@@ -41,37 +39,6 @@ from .simplify_ifs import StimSimplifyIfs
41
39
  from ..rewrite.ifs_to_stim import IfToStim
42
40
 
43
41
 
44
- @dataclass
45
- class AggressiveForLoopUnroll(Pass):
46
- """
47
- Aggressive unrolling of for loops, addresses cases where unroll
48
- does not successfully handle nested loops because of a lack of constprop.
49
-
50
- This should be invoked via fixpoint to let this be repeatedly applied until
51
- no further rewrites are possible.
52
- """
53
-
54
- def unsafe_run(self, mt: Method) -> RewriteResult:
55
- rule = Chain(
56
- InlineGetField(),
57
- InlineGetItem(),
58
- scf.unroll.ForLoop(),
59
- scf.trim.UnusedYield(),
60
- )
61
-
62
- # Intentionally only walk ONCE, let fixpoint happen with the WHOLE pass
63
- # so that HintConst gets run right after, allowing subsequent unrolls to happen
64
- rewrite_result = Walk(rule).rewrite(mt.code)
65
-
66
- rewrite_result = (
67
- HintConst(dialects=mt.dialects, no_raise=self.no_raise)
68
- .unsafe_run(mt)
69
- .join(rewrite_result)
70
- )
71
-
72
- return rewrite_result
73
-
74
-
75
42
  @dataclass
76
43
  class SquinToStimPass(Pass):
77
44
 
@@ -82,8 +49,11 @@ class SquinToStimPass(Pass):
82
49
  dialects=mt.dialects, no_raise=self.no_raise
83
50
  ).unsafe_run(mt)
84
51
 
52
+ rewrite_result = Walk(ilist.rewrite.HintLen()).rewrite(mt.code)
53
+ rewrite_result = Fold(self.dialects).unsafe_run(mt).join(rewrite_result)
54
+
85
55
  rewrite_result = (
86
- AggressiveForLoopUnroll(dialects=mt.dialects, no_raise=self.no_raise)
56
+ UnrollScf(dialects=mt.dialects, no_raise=self.no_raise)
87
57
  .fixpoint(mt)
88
58
  .join(rewrite_result)
89
59
  )
@@ -92,11 +62,7 @@ class SquinToStimPass(Pass):
92
62
  Walk(Fixpoint(CFGCompactify())).rewrite(mt.code).join(rewrite_result)
93
63
  )
94
64
 
95
- rewrite_result = (
96
- Walk(Chain(InlineAlias(), PickIfElse()))
97
- .rewrite(mt.code)
98
- .join(rewrite_result)
99
- )
65
+ rewrite_result = Walk(InlineAlias()).rewrite(mt.code).join(rewrite_result)
100
66
 
101
67
  rewrite_result = (
102
68
  StimSimplifyIfs(mt.dialects, no_raise=self.no_raise)
@@ -111,6 +77,12 @@ class SquinToStimPass(Pass):
111
77
  )
112
78
  rewrite_result = Fold(mt.dialects, no_raise=self.no_raise)(mt)
113
79
 
80
+ rewrite_result = (
81
+ UnrollScf(mt.dialects, no_raise=self.no_raise)
82
+ .fixpoint(mt)
83
+ .join(rewrite_result)
84
+ )
85
+
114
86
  rewrite_result = (
115
87
  CanonicalizeIList(dialects=mt.dialects, no_raise=self.no_raise)
116
88
  .unsafe_run(mt)
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bloqade-circuit
3
- Version: 0.7.3
3
+ Version: 0.7.5
4
4
  Summary: The software development toolkit for neutral atom arrays.
5
5
  Author-email: Roger-luo <rluo@quera.com>, kaihsin <khwu@quera.com>, weinbe58 <pweinberg@quera.com>, johnzl-777 <jlong@quera.com>
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.10
8
- Requires-Dist: kirin-toolchain~=0.17.17
8
+ Requires-Dist: kirin-toolchain~=0.17.23
9
9
  Requires-Dist: numpy>=1.22.0
10
10
  Requires-Dist: pandas>=2.2.3
11
11
  Requires-Dist: pydantic<2.11.0,>=1.3.0
@@ -21,9 +21,20 @@ bloqade/cirq_utils/noise/_two_zone_utils.py,sha256=iq4nwdJQITFlGB61wfrV7vyPA2194
21
21
  bloqade/cirq_utils/noise/conflict_graph.py,sha256=ZUwPWTknrb6SgtZUVPeICn3YA-nUeWQJDuKKX5jL9tE,7179
22
22
  bloqade/cirq_utils/noise/model.py,sha256=8qovvB50oHzDszXkuMAs2I9BQV3eS1IU2D7Wux_dsGE,18459
23
23
  bloqade/cirq_utils/noise/transform.py,sha256=pauFnOKbk2QjxeyXEV_x2zyRGypr5wiQ6ySirU7C2zg,2278
24
- bloqade/pyqrack/__init__.py,sha256=lonTS-luJkTVujCCtgdZRC12V7FQdoFcozAI-byXwN0,810
24
+ bloqade/native/__init__.py,sha256=MtQZmq7KqNGkjxsO_22DpY-13X23Ovw8JKs7lfuv55w,443
25
+ bloqade/native/_prelude.py,sha256=znle4mSTLZtRMCmmiZ-bCPfHqNdgVxsKuY64Fgj2kko,1258
26
+ bloqade/native/dialects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ bloqade/native/dialects/gates/__init__.py,sha256=YX5h-5Agl_x5K0KD-QnuloNV8oeIFXnsGT4ouMpabCU,138
28
+ bloqade/native/dialects/gates/_dialect.py,sha256=D5vU_JAE2ROT5jMMth3f9SPjL9vfvCVjzEfLJzvAImI,61
29
+ bloqade/native/dialects/gates/_interface.py,sha256=2Tie1C-k9GrrSJEsrQ3IIO_3yYJXsyoD6pBZmm0cyp4,537
30
+ bloqade/native/dialects/gates/stmts.py,sha256=qBziqe1b39ltwcFUEpBZ2RdzL4DTiesRs__HIjbA5N4,1016
31
+ bloqade/native/stdlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ bloqade/native/stdlib/broadcast.py,sha256=0DEK6pRcz0IG5BZHt0sV1wZpDvlJgvw4-Qwd1xYLSYM,6141
33
+ bloqade/native/stdlib/simple.py,sha256=mK_p9x_TUr4g-q-Q4LfbVBtXxBS21XPh1meyCC4to_k,5416
34
+ bloqade/pyqrack/__init__.py,sha256=OV8-2fw44gP_JgY8mAUiwISO_qYxS-t0fKsbuUB-r9Y,861
25
35
  bloqade/pyqrack/base.py,sha256=g0GRlEgyJ_P8z-lR8RK2CAuRTj6KPfglKX0iwrgg4DM,4408
26
36
  bloqade/pyqrack/device.py,sha256=-zlr1lSzOvcj5l28nnevy1oMYct79DTOdLYyGaT2Yco,11567
37
+ bloqade/pyqrack/native.py,sha256=ErbVQCatn_JT3Ej-iQzMMfb_q50JF_K1Iv1vRYvu5VA,1857
27
38
  bloqade/pyqrack/reg.py,sha256=uTL07CT1R0xUsInLmwU9YuuNdV6lV0lCs1zhdUz1qIs,1660
28
39
  bloqade/pyqrack/target.py,sha256=c78VtLWAiDNp_0sXwvVzhaEoeFsr1fUVsupxWuo6p3s,3661
29
40
  bloqade/pyqrack/task.py,sha256=hzMueE03C-MR_-ti_5Z0lqFZcHDVCxmQHFaX9tPNm2o,1522
@@ -145,7 +156,7 @@ bloqade/squin/cirq/lowering.py,sha256=trrcBDQQzy2r3JVKb2x6i2BdzBMYkjQNBzH_Va6JOu
145
156
  bloqade/squin/cirq/emit/emit_circuit.py,sha256=JVFXiaSB7A9kamRwCjLqs03Sel4PVCBT-6kRNRWX-jo,4393
146
157
  bloqade/squin/cirq/emit/noise.py,sha256=rESjGC_66s2Y4FwwYda4rY3mYHYjbqLlKE_vnqpZDYI,1534
147
158
  bloqade/squin/cirq/emit/op.py,sha256=u1FoOlbz7NNXPlU-hMbnX_yRB5suKbsEm2jF3Ts4f68,5764
148
- bloqade/squin/cirq/emit/qubit.py,sha256=FManFeDyi1l4Sd07IeD7Lb4xR-7jy5Nwe-quQHI1yPw,1984
159
+ bloqade/squin/cirq/emit/qubit.py,sha256=9aDM0USxcekzXx9--WJB5r96JQ1iEmeNJ9h8rdZ8QhM,1915
149
160
  bloqade/squin/cirq/emit/runtime.py,sha256=dH7JSMt2mALPhVFjmZETQzvnTUQ3BFY5poe0YZpM5vQ,6819
150
161
  bloqade/squin/noise/__init__.py,sha256=JFJ4kmEeWt6bJ2xx3yA5ek-NEbj8ilYWf6mepgbJLOo,338
151
162
  bloqade/squin/noise/_dialect.py,sha256=2IR98J-lXm5Y3srP9g-FD4JC-qTq2seureM6mKKq1xg,63
@@ -207,9 +218,9 @@ bloqade/stim/emit/__init__.py,sha256=N2dPQY7OyqPwHAStDeOgYg2yfxqxMOz-N7pD5Z4JwlI
207
218
  bloqade/stim/emit/stim_str.py,sha256=JyEBoIhLQASogZcUWHI9tMD4JoXYrEqUr2qaZ30gZdc,1491
208
219
  bloqade/stim/parse/__init__.py,sha256=l2DjReB2KkgrDjP_4nP6RnoziiOewoSeZfTno1sVYTw,59
209
220
  bloqade/stim/parse/lowering.py,sha256=L-IcR_exlxsTVv4SQ0bhzIF4_L82P-GEdK6qRd6B86Y,23723
210
- bloqade/stim/passes/__init__.py,sha256=aysjOZyn0IrJQCQBEqiz8pwZ5u5t2s9TmEzA9Y9KG9w,167
221
+ bloqade/stim/passes/__init__.py,sha256=hemzgyl_pwZi34secp1GqStAW0d09CEeKvLD0fXhbb8,111
211
222
  bloqade/stim/passes/simplify_ifs.py,sha256=zicqggWu_yzfrf2a7uUCt-ZenbYSEnFsyGxDfKw72qQ,1084
212
- bloqade/stim/passes/squin_to_stim.py,sha256=cDn4W9TEsCZQT5YhEMEId87LtLv4iqwaurwgTqtE1qQ,6421
223
+ bloqade/stim/passes/squin_to_stim.py,sha256=mqCspofBJ60YUU5dl7AdxmctmHygk1yeRr4ucgD9TbU,5620
213
224
  bloqade/stim/rewrite/__init__.py,sha256=zL5G73JEsXkehN7gCtUgGnmC2BJ3vKihOd1ohVwM68E,480
214
225
  bloqade/stim/rewrite/ifs_to_stim.py,sha256=A3SndoGinZHLul17zXWyQrK_1Hy5I4qvuOskLIeDRMU,6942
215
226
  bloqade/stim/rewrite/py_constant_to_stim.py,sha256=PV8bHvn759-d_0JW4akaGSORW_oxigrlUBhAC51PJAU,1354
@@ -232,7 +243,7 @@ bloqade/visual/animation/runtime/atoms.py,sha256=EmjxhujLiHHPS_HtH_B-7TiqeHgvW5u
232
243
  bloqade/visual/animation/runtime/ppoly.py,sha256=JB9IP53N1w6adBJEue6J5Nmj818Id9JvrlgrmiQTU1I,1385
233
244
  bloqade/visual/animation/runtime/qpustate.py,sha256=rlmxQeJSvaohXrTpXQL5y-NJcpvfW33xPaYM1slv7cc,4270
234
245
  bloqade/visual/animation/runtime/utils.py,sha256=ju9IzOWX-vKwfpqUjlUKu3Ssr_UFPFFq-tzH_Nqyo_c,1212
235
- bloqade_circuit-0.7.3.dist-info/METADATA,sha256=Bg7Nphnd5xlF_jANV1TK2wzCOlTGT0eHgXQfu8KIdPc,3850
236
- bloqade_circuit-0.7.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
237
- bloqade_circuit-0.7.3.dist-info/licenses/LICENSE,sha256=S5GIJwR6QCixPA9wryYb44ZEek0Nz4rt_zLUqP05UbU,13160
238
- bloqade_circuit-0.7.3.dist-info/RECORD,,
246
+ bloqade_circuit-0.7.5.dist-info/METADATA,sha256=mPPVbTxuk3cA4_obi8jd4Pw09pDDbxa3IIp8Z8vZMn4,3850
247
+ bloqade_circuit-0.7.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
248
+ bloqade_circuit-0.7.5.dist-info/licenses/LICENSE,sha256=S5GIJwR6QCixPA9wryYb44ZEek0Nz4rt_zLUqP05UbU,13160
249
+ bloqade_circuit-0.7.5.dist-info/RECORD,,