bloqade-circuit 0.4.3__py3-none-any.whl → 0.4.4__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.
- bloqade/squin/analysis/nsites/impls.py +7 -0
- bloqade/squin/op/__init__.py +3 -0
- bloqade/squin/op/_wrapper.py +12 -0
- bloqade/squin/op/stmts.py +19 -1
- bloqade/squin/rewrite/U3_to_clifford.py +149 -0
- bloqade/squin/rewrite/__init__.py +3 -7
- bloqade/squin/rewrite/remove_dangling_qubits.py +19 -0
- bloqade/squin/rewrite/wrap_analysis.py +34 -19
- bloqade/stim/__init__.py +1 -1
- bloqade/stim/dialects/auxiliary/stmts/const.py +1 -1
- bloqade/stim/dialects/gate/stmts/__init__.py +6 -0
- bloqade/stim/passes/__init__.py +1 -0
- bloqade/stim/passes/squin_to_stim.py +86 -0
- bloqade/stim/rewrite/__init__.py +7 -0
- bloqade/stim/rewrite/py_constant_to_stim.py +42 -0
- bloqade/{squin → stim}/rewrite/qubit_to_stim.py +18 -3
- bloqade/{squin → stim}/rewrite/squin_measure.py +2 -2
- bloqade/{squin/rewrite/stim_rewrite_util.py → stim/rewrite/util.py} +36 -17
- bloqade/{squin → stim}/rewrite/wire_to_stim.py +1 -1
- {bloqade_circuit-0.4.3.dist-info → bloqade_circuit-0.4.4.dist-info}/METADATA +1 -1
- {bloqade_circuit-0.4.3.dist-info → bloqade_circuit-0.4.4.dist-info}/RECORD +24 -20
- bloqade/squin/passes/__init__.py +0 -1
- bloqade/squin/passes/stim.py +0 -68
- /bloqade/{squin → stim}/rewrite/wire_identity_elimination.py +0 -0
- {bloqade_circuit-0.4.3.dist-info → bloqade_circuit-0.4.4.dist-info}/WHEEL +0 -0
- {bloqade_circuit-0.4.3.dist-info → bloqade_circuit-0.4.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
from kirin import interp
|
|
2
|
+
from kirin.dialects import scf
|
|
3
|
+
from kirin.dialects.scf.typeinfer import TypeInfer as ScfTypeInfer
|
|
2
4
|
|
|
3
5
|
from bloqade.squin import op, wire
|
|
4
6
|
|
|
@@ -78,3 +80,8 @@ class SquinOp(interp.MethodTable):
|
|
|
78
80
|
def scale(self, interp: NSitesAnalysis, frame: interp.Frame, stmt: op.stmts.Scale):
|
|
79
81
|
op_sites = frame.get(stmt.op)
|
|
80
82
|
return (op_sites,)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@scf.dialect.register(key="op.nsites")
|
|
86
|
+
class ScfSquinOp(ScfTypeInfer):
|
|
87
|
+
pass
|
bloqade/squin/op/__init__.py
CHANGED
bloqade/squin/op/_wrapper.py
CHANGED
|
@@ -69,6 +69,18 @@ def y() -> types.Op: ...
|
|
|
69
69
|
def z() -> types.Op: ...
|
|
70
70
|
|
|
71
71
|
|
|
72
|
+
@wraps(stmts.SqrtX)
|
|
73
|
+
def sqrt_x() -> types.Op: ...
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@wraps(stmts.SqrtY)
|
|
77
|
+
def sqrt_y() -> types.Op: ...
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@wraps(stmts.S)
|
|
81
|
+
def sqrt_z() -> types.Op: ...
|
|
82
|
+
|
|
83
|
+
|
|
72
84
|
@wraps(stmts.H)
|
|
73
85
|
def h() -> types.Op: ...
|
|
74
86
|
|
bloqade/squin/op/stmts.py
CHANGED
|
@@ -142,7 +142,12 @@ class Reset(PrimitiveOp):
|
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
@statement
|
|
145
|
-
class
|
|
145
|
+
class CliffordOp(ConstantUnitary):
|
|
146
|
+
pass
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@statement
|
|
150
|
+
class PauliOp(CliffordOp):
|
|
146
151
|
pass
|
|
147
152
|
|
|
148
153
|
|
|
@@ -173,6 +178,19 @@ class Z(PauliOp):
|
|
|
173
178
|
pass
|
|
174
179
|
|
|
175
180
|
|
|
181
|
+
@statement(dialect=dialect)
|
|
182
|
+
class SqrtX(ConstantUnitary):
|
|
183
|
+
pass
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@statement(dialect=dialect)
|
|
187
|
+
class SqrtY(ConstantUnitary):
|
|
188
|
+
pass
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# NOTE no SqrtZ since its equal to S
|
|
192
|
+
|
|
193
|
+
|
|
176
194
|
@statement(dialect=dialect)
|
|
177
195
|
class H(ConstantUnitary):
|
|
178
196
|
pass
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# create rewrite rule name SquinMeasureToStim using kirin
|
|
2
|
+
import math
|
|
3
|
+
from typing import List, Tuple, Callable
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from kirin import ir
|
|
7
|
+
from kirin.dialects import py
|
|
8
|
+
from kirin.rewrite.abc import RewriteRule, RewriteResult
|
|
9
|
+
|
|
10
|
+
from bloqade.squin import op, qubit
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def sdag() -> list[ir.Statement]:
|
|
14
|
+
return [_op := op.stmts.S(), op.stmts.Adjoint(op=_op.result, is_unitary=True)]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# (theta, phi, lam)
|
|
18
|
+
U3_HALF_PI_ANGLE_TO_GATES: dict[
|
|
19
|
+
tuple[int, int, int], Callable[[], Tuple[List[ir.Statement], ...]]
|
|
20
|
+
] = {
|
|
21
|
+
(0, 0, 0): lambda: ([op.stmts.Identity(sites=1)],),
|
|
22
|
+
(0, 0, 1): lambda: ([op.stmts.S()],),
|
|
23
|
+
(0, 0, 2): lambda: ([op.stmts.Z()],),
|
|
24
|
+
(0, 0, 3): lambda: (sdag(),),
|
|
25
|
+
(1, 0, 0): lambda: ([op.stmts.SqrtY()],),
|
|
26
|
+
(1, 0, 1): lambda: ([op.stmts.S()], [op.stmts.SqrtY()]),
|
|
27
|
+
(1, 0, 2): lambda: ([op.stmts.H()],),
|
|
28
|
+
(1, 0, 3): lambda: (sdag(), [op.stmts.SqrtY()]),
|
|
29
|
+
(1, 1, 0): lambda: ([op.stmts.SqrtY()], [op.stmts.S()]),
|
|
30
|
+
(1, 1, 1): lambda: ([op.stmts.S()], [op.stmts.SqrtY()], [op.stmts.S()]),
|
|
31
|
+
(1, 1, 2): lambda: ([op.stmts.Z()], [op.stmts.SqrtY()], [op.stmts.S()]),
|
|
32
|
+
(1, 1, 3): lambda: (sdag(), [op.stmts.SqrtY()], [op.stmts.S()]),
|
|
33
|
+
(1, 2, 0): lambda: ([op.stmts.SqrtY()], [op.stmts.Z()]),
|
|
34
|
+
(1, 2, 1): lambda: ([op.stmts.S()], [op.stmts.SqrtY()], [op.stmts.Z()]),
|
|
35
|
+
(1, 2, 2): lambda: ([op.stmts.Z()], [op.stmts.SqrtY()], [op.stmts.Z()]),
|
|
36
|
+
(1, 2, 3): lambda: (sdag(), [op.stmts.SqrtY()], [op.stmts.Z()]),
|
|
37
|
+
(1, 3, 0): lambda: ([op.stmts.SqrtY()], sdag()),
|
|
38
|
+
(1, 3, 1): lambda: ([op.stmts.S()], [op.stmts.SqrtY()], sdag()),
|
|
39
|
+
(1, 3, 2): lambda: ([op.stmts.Z()], [op.stmts.SqrtY()], sdag()),
|
|
40
|
+
(1, 3, 3): lambda: (sdag(), [op.stmts.SqrtY()], sdag()),
|
|
41
|
+
(2, 0, 0): lambda: ([op.stmts.Y()],),
|
|
42
|
+
(2, 0, 1): lambda: ([op.stmts.S()], [op.stmts.Y()]),
|
|
43
|
+
(2, 0, 2): lambda: ([op.stmts.Z()], [op.stmts.Y()]),
|
|
44
|
+
(2, 0, 3): lambda: (sdag(), [op.stmts.Y()]),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def equivalent_u3_para(
|
|
49
|
+
theta_half_pi: int, phi_half_pi: int, lam_half_pi: int
|
|
50
|
+
) -> tuple[int, int, int]:
|
|
51
|
+
"""
|
|
52
|
+
1. Assume all three angles are in the range [0, 4].
|
|
53
|
+
2. U3(theta, phi, lam) = -U3(2pi-theta, phi+pi, lam+pi).
|
|
54
|
+
"""
|
|
55
|
+
return ((4 - theta_half_pi) % 4, (phi_half_pi + 2) % 4, (lam_half_pi + 2) % 4)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class SquinU3ToClifford(RewriteRule):
|
|
59
|
+
"""
|
|
60
|
+
Rewrite squin U3 statements to clifford when possible.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
|
|
64
|
+
if isinstance(node, (qubit.Apply, qubit.Broadcast)):
|
|
65
|
+
return self.rewrite_ApplyOrBroadcast_onU3(node)
|
|
66
|
+
else:
|
|
67
|
+
return RewriteResult()
|
|
68
|
+
|
|
69
|
+
def get_constant(self, node: ir.SSAValue) -> float | None:
|
|
70
|
+
if isinstance(node.owner, py.Constant):
|
|
71
|
+
# node.value is a PyAttr, need to get the wrapped value out
|
|
72
|
+
return node.owner.value.unwrap()
|
|
73
|
+
else:
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
def resolve_angle(self, angle: float) -> int | None:
|
|
77
|
+
"""
|
|
78
|
+
Normalize the angle to be in the range [0, 2π).
|
|
79
|
+
"""
|
|
80
|
+
# convert to 0.0~1.0, in unit of pi/2
|
|
81
|
+
angle_half_pi = angle / math.pi * 2.0
|
|
82
|
+
|
|
83
|
+
mod = angle_half_pi % 1.0
|
|
84
|
+
if not (np.isclose(mod, 0.0) or np.isclose(mod, 1.0)):
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
else:
|
|
88
|
+
return round((angle / math.tau) % 1 * 4) % 4
|
|
89
|
+
|
|
90
|
+
def rewrite_ApplyOrBroadcast_onU3(
|
|
91
|
+
self, node: qubit.Apply | qubit.Broadcast
|
|
92
|
+
) -> RewriteResult:
|
|
93
|
+
"""
|
|
94
|
+
Rewrite Apply and Broadcast nodes to their clifford equivalent statements.
|
|
95
|
+
"""
|
|
96
|
+
if not isinstance(node.operator.owner, op.stmts.U3):
|
|
97
|
+
return RewriteResult()
|
|
98
|
+
|
|
99
|
+
gates = self.decompose_U3_gates(node.operator.owner)
|
|
100
|
+
|
|
101
|
+
if len(gates) == 0:
|
|
102
|
+
return RewriteResult()
|
|
103
|
+
|
|
104
|
+
for stmt_list in gates:
|
|
105
|
+
for gate_stmt in stmt_list[:-1]:
|
|
106
|
+
gate_stmt.insert_before(node)
|
|
107
|
+
|
|
108
|
+
oper = stmt_list[-1]
|
|
109
|
+
oper.insert_before(node)
|
|
110
|
+
new_node = node.__class__(operator=oper.result, qubits=node.qubits)
|
|
111
|
+
new_node.insert_before(node)
|
|
112
|
+
|
|
113
|
+
node.delete()
|
|
114
|
+
|
|
115
|
+
# rewrite U3 to clifford gates
|
|
116
|
+
return RewriteResult(has_done_something=True)
|
|
117
|
+
|
|
118
|
+
def decompose_U3_gates(self, node: op.stmts.U3) -> Tuple[List[ir.Statement], ...]:
|
|
119
|
+
"""
|
|
120
|
+
Rewrite U3 statements to clifford gates if possible.
|
|
121
|
+
"""
|
|
122
|
+
theta = self.get_constant(node.theta)
|
|
123
|
+
phi = self.get_constant(node.phi)
|
|
124
|
+
lam = self.get_constant(node.lam)
|
|
125
|
+
|
|
126
|
+
if theta is None or phi is None or lam is None:
|
|
127
|
+
return ()
|
|
128
|
+
|
|
129
|
+
theta_half_pi: int | None = self.resolve_angle(theta)
|
|
130
|
+
phi_half_pi: int | None = self.resolve_angle(phi)
|
|
131
|
+
lam_half_pi: int | None = self.resolve_angle(lam)
|
|
132
|
+
|
|
133
|
+
if theta_half_pi is None or phi_half_pi is None or lam_half_pi is None:
|
|
134
|
+
return ()
|
|
135
|
+
|
|
136
|
+
angles_key = (theta_half_pi, phi_half_pi, lam_half_pi)
|
|
137
|
+
if angles_key not in U3_HALF_PI_ANGLE_TO_GATES:
|
|
138
|
+
angles_key = equivalent_u3_para(*angles_key)
|
|
139
|
+
if angles_key not in U3_HALF_PI_ANGLE_TO_GATES:
|
|
140
|
+
return ()
|
|
141
|
+
|
|
142
|
+
gates_stmts = U3_HALF_PI_ANGLE_TO_GATES.get(angles_key)
|
|
143
|
+
|
|
144
|
+
# no consistent gates, then:
|
|
145
|
+
assert (
|
|
146
|
+
gates_stmts is not None
|
|
147
|
+
), "internal error, U3 gates not found for angles: {}".format(angles_key)
|
|
148
|
+
|
|
149
|
+
return gates_stmts()
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
from .wire_to_stim import SquinWireToStim as SquinWireToStim
|
|
2
|
-
from .qubit_to_stim import SquinQubitToStim as SquinQubitToStim
|
|
3
|
-
from .squin_measure import SquinMeasureToStim as SquinMeasureToStim
|
|
4
1
|
from .wrap_analysis import (
|
|
5
2
|
SitesAttribute as SitesAttribute,
|
|
6
3
|
AddressAttribute as AddressAttribute,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from .wire_identity_elimination import (
|
|
10
|
-
SquinWireIdentityElimination as SquinWireIdentityElimination,
|
|
4
|
+
WrapOpSiteAnalysis as WrapOpSiteAnalysis,
|
|
5
|
+
WrapAddressAnalysis as WrapAddressAnalysis,
|
|
11
6
|
)
|
|
7
|
+
from .remove_dangling_qubits import RemoveDeadRegister as RemoveDeadRegister
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from kirin import ir
|
|
2
|
+
from kirin.rewrite.abc import RewriteRule, RewriteResult
|
|
3
|
+
|
|
4
|
+
from bloqade.squin import qubit
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RemoveDeadRegister(RewriteRule):
|
|
8
|
+
|
|
9
|
+
def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
|
|
10
|
+
|
|
11
|
+
if not isinstance(node, qubit.New):
|
|
12
|
+
return RewriteResult()
|
|
13
|
+
|
|
14
|
+
if bool(node.result.uses):
|
|
15
|
+
return RewriteResult()
|
|
16
|
+
else:
|
|
17
|
+
node.delete()
|
|
18
|
+
|
|
19
|
+
return RewriteResult(has_done_something=True)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
1
2
|
from dataclasses import dataclass
|
|
2
3
|
|
|
3
4
|
from kirin import ir
|
|
@@ -40,33 +41,47 @@ class SitesAttribute(ir.Attribute):
|
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
@dataclass
|
|
43
|
-
class
|
|
44
|
+
class WrapAnalysis(RewriteRule):
|
|
44
45
|
|
|
46
|
+
@abstractmethod
|
|
47
|
+
def wrap(self, value: ir.SSAValue) -> bool:
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
def rewrite_Block(self, node: ir.Block) -> RewriteResult:
|
|
51
|
+
has_done_something = any(self.wrap(arg) for arg in node.args)
|
|
52
|
+
return RewriteResult(has_done_something=has_done_something)
|
|
53
|
+
|
|
54
|
+
def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
|
|
55
|
+
has_done_something = any(self.wrap(result) for result in node.results)
|
|
56
|
+
return RewriteResult(has_done_something=has_done_something)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass
|
|
60
|
+
class WrapAddressAnalysis(WrapAnalysis):
|
|
45
61
|
address_analysis: dict[ir.SSAValue, Address]
|
|
46
|
-
op_site_analysis: dict[ir.SSAValue, Sites]
|
|
47
62
|
|
|
48
63
|
def wrap(self, value: ir.SSAValue) -> bool:
|
|
49
64
|
address_analysis_result = self.address_analysis[value]
|
|
50
|
-
op_site_analysis_result = self.op_site_analysis[value]
|
|
51
65
|
|
|
52
|
-
if value.hints.get("address")
|
|
66
|
+
if value.hints.get("address") is not None:
|
|
53
67
|
return False
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
value.hints["sites"] = SitesAttribute(op_site_analysis_result)
|
|
68
|
+
|
|
69
|
+
value.hints["address"] = AddressAttribute(address_analysis_result)
|
|
57
70
|
|
|
58
71
|
return True
|
|
59
72
|
|
|
60
|
-
def rewrite_Block(self, node: ir.Block) -> RewriteResult:
|
|
61
|
-
has_done_something = False
|
|
62
|
-
for arg in node.args:
|
|
63
|
-
if self.wrap(arg):
|
|
64
|
-
has_done_something = True
|
|
65
|
-
return RewriteResult(has_done_something=has_done_something)
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
@dataclass
|
|
75
|
+
class WrapOpSiteAnalysis(WrapAnalysis):
|
|
76
|
+
|
|
77
|
+
op_site_analysis: dict[ir.SSAValue, Sites]
|
|
78
|
+
|
|
79
|
+
def wrap(self, value: ir.SSAValue) -> bool:
|
|
80
|
+
op_site_analysis_result = self.op_site_analysis[value]
|
|
81
|
+
|
|
82
|
+
if value.hints.get("sites") is not None:
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
value.hints["sites"] = SitesAttribute(op_site_analysis_result)
|
|
86
|
+
|
|
87
|
+
return True
|
bloqade/stim/__init__.py
CHANGED
|
@@ -47,7 +47,7 @@ class ConstFloat(ir.Statement):
|
|
|
47
47
|
|
|
48
48
|
@statement(dialect=dialect)
|
|
49
49
|
class ConstBool(ir.Statement):
|
|
50
|
-
"""IR Statement representing a constant
|
|
50
|
+
"""IR Statement representing a constant boolean value."""
|
|
51
51
|
|
|
52
52
|
name = "constant.bool"
|
|
53
53
|
traits = frozenset({ir.Pure(), ir.ConstantLike(), lowering.FromPythonCall()})
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
from .pp import SPP as SPP
|
|
2
|
+
from .base import (
|
|
3
|
+
Gate as Gate,
|
|
4
|
+
TwoQubitGate as TwoQubitGate,
|
|
5
|
+
SingleQubitGate as SingleQubitGate,
|
|
6
|
+
ControlledTwoQubitGate as ControlledTwoQubitGate,
|
|
7
|
+
)
|
|
2
8
|
from .control_2q import CX as CX, CY as CY, CZ as CZ
|
|
3
9
|
from .clifford_1q import (
|
|
4
10
|
H as H,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .squin_to_stim import SquinToStim as SquinToStim
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from kirin.passes import Fold
|
|
4
|
+
from kirin.rewrite import (
|
|
5
|
+
Walk,
|
|
6
|
+
Chain,
|
|
7
|
+
Fixpoint,
|
|
8
|
+
DeadCodeElimination,
|
|
9
|
+
CommonSubexpressionElimination,
|
|
10
|
+
)
|
|
11
|
+
from kirin.ir.method import Method
|
|
12
|
+
from kirin.passes.abc import Pass
|
|
13
|
+
from kirin.rewrite.abc import RewriteResult
|
|
14
|
+
|
|
15
|
+
from bloqade.stim.groups import main as stim_main_group
|
|
16
|
+
from bloqade.stim.rewrite import (
|
|
17
|
+
SquinWireToStim,
|
|
18
|
+
PyConstantToStim,
|
|
19
|
+
SquinQubitToStim,
|
|
20
|
+
SquinMeasureToStim,
|
|
21
|
+
SquinWireIdentityElimination,
|
|
22
|
+
)
|
|
23
|
+
from bloqade.squin.rewrite import RemoveDeadRegister
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class SquinToStim(Pass):
|
|
28
|
+
|
|
29
|
+
def unsafe_run(self, mt: Method) -> RewriteResult:
|
|
30
|
+
fold_pass = Fold(mt.dialects)
|
|
31
|
+
# propagate constants
|
|
32
|
+
rewrite_result = fold_pass(mt)
|
|
33
|
+
|
|
34
|
+
# Assume that address analysis and
|
|
35
|
+
# wrapping has been done before this pass!
|
|
36
|
+
|
|
37
|
+
# Wrap Rewrite + SquinToStim can happen w/ standard walk
|
|
38
|
+
rewrite_result = (
|
|
39
|
+
Walk(
|
|
40
|
+
Chain(
|
|
41
|
+
SquinQubitToStim(),
|
|
42
|
+
SquinWireToStim(),
|
|
43
|
+
SquinMeasureToStim(), # reduce duplicated logic, can split out even more rules later
|
|
44
|
+
SquinWireIdentityElimination(),
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
.rewrite(mt.code)
|
|
48
|
+
.join(rewrite_result)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Convert all PyConsts to Stim Constants
|
|
52
|
+
rewrite_result = (
|
|
53
|
+
Walk(Chain(PyConstantToStim())).rewrite(mt.code).join(rewrite_result)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# remove any squin.qubit.new that's left around
|
|
57
|
+
## Not considered pure so DCE won't touch it but
|
|
58
|
+
## it isn't being used anymore considering everything is a
|
|
59
|
+
## stim dialect statement
|
|
60
|
+
rewrite_result = (
|
|
61
|
+
Fixpoint(
|
|
62
|
+
Walk(
|
|
63
|
+
Chain(
|
|
64
|
+
DeadCodeElimination(),
|
|
65
|
+
CommonSubexpressionElimination(),
|
|
66
|
+
RemoveDeadRegister(),
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
.rewrite(mt.code)
|
|
71
|
+
.join(rewrite_result)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# do program verification here,
|
|
75
|
+
# ideally use built-in .verify() to catch any
|
|
76
|
+
# incompatible statements as the full rewrite process should not
|
|
77
|
+
# leave statements from any other dialects (other than the stim main group)
|
|
78
|
+
mt_verification_clone = mt.similar(stim_main_group)
|
|
79
|
+
|
|
80
|
+
# suggested by Kai, will work for now
|
|
81
|
+
for stmt in mt_verification_clone.code.walk():
|
|
82
|
+
assert (
|
|
83
|
+
stmt.dialect in stim_main_group
|
|
84
|
+
), "Statements detected that are not part of the stim dialect, please verify the original code is valid for rewrite!"
|
|
85
|
+
|
|
86
|
+
return rewrite_result
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .wire_to_stim import SquinWireToStim as SquinWireToStim
|
|
2
|
+
from .qubit_to_stim import SquinQubitToStim as SquinQubitToStim
|
|
3
|
+
from .squin_measure import SquinMeasureToStim as SquinMeasureToStim
|
|
4
|
+
from .py_constant_to_stim import PyConstantToStim as PyConstantToStim
|
|
5
|
+
from .wire_identity_elimination import (
|
|
6
|
+
SquinWireIdentityElimination as SquinWireIdentityElimination,
|
|
7
|
+
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from kirin import ir
|
|
2
|
+
from kirin.dialects import py
|
|
3
|
+
from kirin.rewrite.abc import RewriteRule, RewriteResult
|
|
4
|
+
|
|
5
|
+
from bloqade.stim.dialects import auxiliary
|
|
6
|
+
|
|
7
|
+
# py.constant.int -> stim.const.ConstInt
|
|
8
|
+
# py.constant.float -> stimt.const.ConstFloat
|
|
9
|
+
# py.constant -> stim.const.ConstBool
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PyConstantToStim(RewriteRule):
|
|
14
|
+
|
|
15
|
+
def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
|
|
16
|
+
|
|
17
|
+
match node:
|
|
18
|
+
case py.constant.Constant():
|
|
19
|
+
return self.rewrite_PyConstant(node)
|
|
20
|
+
case _:
|
|
21
|
+
return RewriteResult()
|
|
22
|
+
|
|
23
|
+
def rewrite_PyConstant(self, node: py.constant.Constant) -> RewriteResult:
|
|
24
|
+
|
|
25
|
+
# node.value is a PyAttr, need to get the
|
|
26
|
+
# wrapped value out
|
|
27
|
+
wrapped_value = node.value.unwrap()
|
|
28
|
+
|
|
29
|
+
if isinstance(wrapped_value, int):
|
|
30
|
+
stim_const = auxiliary.ConstInt(value=wrapped_value)
|
|
31
|
+
elif isinstance(wrapped_value, float):
|
|
32
|
+
stim_const = auxiliary.ConstFloat(value=wrapped_value)
|
|
33
|
+
elif isinstance(wrapped_value, bool):
|
|
34
|
+
stim_const = auxiliary.ConstBool(value=wrapped_value)
|
|
35
|
+
elif isinstance(wrapped_value, str):
|
|
36
|
+
stim_const = auxiliary.ConstStr(value=wrapped_value)
|
|
37
|
+
else:
|
|
38
|
+
return RewriteResult()
|
|
39
|
+
|
|
40
|
+
node.replace_by(stim_const)
|
|
41
|
+
|
|
42
|
+
return RewriteResult(has_done_something=True)
|
|
@@ -2,8 +2,9 @@ from kirin import ir
|
|
|
2
2
|
from kirin.rewrite.abc import RewriteRule, RewriteResult
|
|
3
3
|
|
|
4
4
|
from bloqade.squin import op, qubit
|
|
5
|
-
from bloqade.squin.rewrite
|
|
6
|
-
from bloqade.
|
|
5
|
+
from bloqade.squin.rewrite import AddressAttribute
|
|
6
|
+
from bloqade.stim.dialects import gate
|
|
7
|
+
from bloqade.stim.rewrite.util import (
|
|
7
8
|
SQUIN_STIM_GATE_MAPPING,
|
|
8
9
|
rewrite_Control,
|
|
9
10
|
insert_qubit_idx_from_address,
|
|
@@ -34,6 +35,15 @@ class SquinQubitToStim(RewriteRule):
|
|
|
34
35
|
if isinstance(applied_op, op.stmts.Control):
|
|
35
36
|
return rewrite_Control(stmt)
|
|
36
37
|
|
|
38
|
+
# check if its adjoint, assume its canonicalized so no nested adjoints.
|
|
39
|
+
is_conj = False
|
|
40
|
+
if isinstance(applied_op, op.stmts.Adjoint):
|
|
41
|
+
if not applied_op.is_unitary:
|
|
42
|
+
return RewriteResult()
|
|
43
|
+
|
|
44
|
+
is_conj = True
|
|
45
|
+
applied_op = applied_op.op.owner
|
|
46
|
+
|
|
37
47
|
# need to handle Control through separate means
|
|
38
48
|
# but we can handle X, Y, Z, H, and S here just fine
|
|
39
49
|
stim_1q_op = SQUIN_STIM_GATE_MAPPING.get(type(applied_op))
|
|
@@ -41,9 +51,11 @@ class SquinQubitToStim(RewriteRule):
|
|
|
41
51
|
return RewriteResult()
|
|
42
52
|
|
|
43
53
|
address_attr = stmt.qubits.hints.get("address")
|
|
54
|
+
|
|
44
55
|
if address_attr is None:
|
|
45
56
|
return RewriteResult()
|
|
46
57
|
|
|
58
|
+
# sometimes you can get a whole AddressReg...
|
|
47
59
|
assert isinstance(address_attr, AddressAttribute)
|
|
48
60
|
qubit_idx_ssas = insert_qubit_idx_from_address(
|
|
49
61
|
address=address_attr, stmt_to_insert_before=stmt
|
|
@@ -52,7 +64,10 @@ class SquinQubitToStim(RewriteRule):
|
|
|
52
64
|
if qubit_idx_ssas is None:
|
|
53
65
|
return RewriteResult()
|
|
54
66
|
|
|
55
|
-
|
|
67
|
+
if isinstance(stim_1q_op, gate.stmts.Gate):
|
|
68
|
+
stim_1q_stmt = stim_1q_op(targets=tuple(qubit_idx_ssas), dagger=is_conj)
|
|
69
|
+
else:
|
|
70
|
+
stim_1q_stmt = stim_1q_op(targets=tuple(qubit_idx_ssas))
|
|
56
71
|
stmt.replace_by(stim_1q_stmt)
|
|
57
72
|
|
|
58
73
|
return RewriteResult(has_done_something=True)
|
|
@@ -4,9 +4,9 @@ from kirin.dialects import py
|
|
|
4
4
|
from kirin.rewrite.abc import RewriteRule, RewriteResult
|
|
5
5
|
|
|
6
6
|
from bloqade.squin import wire, qubit
|
|
7
|
+
from bloqade.squin.rewrite import AddressAttribute
|
|
7
8
|
from bloqade.stim.dialects import collapse
|
|
8
|
-
from bloqade.
|
|
9
|
-
from bloqade.squin.rewrite.stim_rewrite_util import (
|
|
9
|
+
from bloqade.stim.rewrite.util import (
|
|
10
10
|
is_measure_result_used,
|
|
11
11
|
insert_qubit_idx_from_address,
|
|
12
12
|
)
|
|
@@ -3,9 +3,9 @@ from kirin.dialects import py
|
|
|
3
3
|
from kirin.rewrite.abc import RewriteResult
|
|
4
4
|
|
|
5
5
|
from bloqade.squin import op, wire, qubit
|
|
6
|
+
from bloqade.squin.rewrite import AddressAttribute
|
|
6
7
|
from bloqade.stim.dialects import gate, collapse
|
|
7
|
-
from bloqade.analysis.address import AddressWire, AddressQubit, AddressTuple
|
|
8
|
-
from bloqade.squin.rewrite.wrap_analysis import AddressAttribute
|
|
8
|
+
from bloqade.analysis.address import AddressReg, AddressWire, AddressQubit, AddressTuple
|
|
9
9
|
|
|
10
10
|
SQUIN_STIM_GATE_MAPPING = {
|
|
11
11
|
op.stmts.X: gate.X,
|
|
@@ -13,10 +13,28 @@ SQUIN_STIM_GATE_MAPPING = {
|
|
|
13
13
|
op.stmts.Z: gate.Z,
|
|
14
14
|
op.stmts.H: gate.H,
|
|
15
15
|
op.stmts.S: gate.S,
|
|
16
|
+
op.stmts.SqrtX: gate.SqrtX,
|
|
17
|
+
op.stmts.SqrtY: gate.SqrtY,
|
|
16
18
|
op.stmts.Identity: gate.Identity,
|
|
17
19
|
op.stmts.Reset: collapse.RZ,
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
# Squin allows creation of control gates where the gate can be any operator,
|
|
23
|
+
# but Stim only supports CX, CY, and CZ as control gates.
|
|
24
|
+
SQUIN_STIM_CONTROL_GATE_MAPPING = {
|
|
25
|
+
op.stmts.X: gate.CX,
|
|
26
|
+
op.stmts.Y: gate.CY,
|
|
27
|
+
op.stmts.Z: gate.CZ,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def create_and_insert_qubit_idx_stmt(
|
|
32
|
+
qubit_idx, stmt_to_insert_before: ir.Statement, qubit_idx_ssas: list
|
|
33
|
+
):
|
|
34
|
+
qubit_idx_stmt = py.Constant(qubit_idx)
|
|
35
|
+
qubit_idx_stmt.insert_before(stmt_to_insert_before)
|
|
36
|
+
qubit_idx_ssas.append(qubit_idx_stmt.result)
|
|
37
|
+
|
|
20
38
|
|
|
21
39
|
def insert_qubit_idx_from_address(
|
|
22
40
|
address: AddressAttribute, stmt_to_insert_before: ir.Statement
|
|
@@ -31,16 +49,23 @@ def insert_qubit_idx_from_address(
|
|
|
31
49
|
for address_qubit in address_data.data:
|
|
32
50
|
if not isinstance(address_qubit, AddressQubit):
|
|
33
51
|
return
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
create_and_insert_qubit_idx_stmt(
|
|
53
|
+
address_qubit.data, stmt_to_insert_before, qubit_idx_ssas
|
|
54
|
+
)
|
|
55
|
+
elif isinstance(address_data, AddressReg):
|
|
56
|
+
for qubit_idx in address_data.data:
|
|
57
|
+
create_and_insert_qubit_idx_stmt(
|
|
58
|
+
qubit_idx, stmt_to_insert_before, qubit_idx_ssas
|
|
59
|
+
)
|
|
60
|
+
elif isinstance(address_data, AddressQubit):
|
|
61
|
+
create_and_insert_qubit_idx_stmt(
|
|
62
|
+
address_data.data, stmt_to_insert_before, qubit_idx_ssas
|
|
63
|
+
)
|
|
38
64
|
elif isinstance(address_data, AddressWire):
|
|
39
65
|
address_qubit = address_data.origin_qubit
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
qubit_idx_ssas.append(qubit_idx_stmt.result)
|
|
66
|
+
create_and_insert_qubit_idx_stmt(
|
|
67
|
+
address_qubit.data, stmt_to_insert_before, qubit_idx_ssas
|
|
68
|
+
)
|
|
44
69
|
else:
|
|
45
70
|
return
|
|
46
71
|
|
|
@@ -119,13 +144,7 @@ def rewrite_Control(
|
|
|
119
144
|
target_qubits = tuple(target_qubits)
|
|
120
145
|
ctrl_qubits = tuple(ctrl_qubits)
|
|
121
146
|
|
|
122
|
-
|
|
123
|
-
op.stmts.X: gate.CX,
|
|
124
|
-
op.stmts.Y: gate.CY,
|
|
125
|
-
op.stmts.Z: gate.CZ,
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
stim_gate = supported_gate_mapping.get(type(ctrl_op_target_gate))
|
|
147
|
+
stim_gate = SQUIN_STIM_CONTROL_GATE_MAPPING.get(type(ctrl_op_target_gate))
|
|
129
148
|
if stim_gate is None:
|
|
130
149
|
return RewriteResult()
|
|
131
150
|
|
|
@@ -2,7 +2,7 @@ from kirin import ir
|
|
|
2
2
|
from kirin.rewrite.abc import RewriteRule, RewriteResult
|
|
3
3
|
|
|
4
4
|
from bloqade.squin import op, wire
|
|
5
|
-
from bloqade.
|
|
5
|
+
from bloqade.stim.rewrite.util import (
|
|
6
6
|
SQUIN_STIM_GATE_MAPPING,
|
|
7
7
|
rewrite_Control,
|
|
8
8
|
insert_qubit_idx_from_wire_ssa,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bloqade-circuit
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
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
|
|
@@ -115,7 +115,7 @@ bloqade/squin/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
115
115
|
bloqade/squin/analysis/schedule.py,sha256=buuC4bFuLuaSDK2BZfkRkh8ZdNicz9HkEv3FAnsDViE,7880
|
|
116
116
|
bloqade/squin/analysis/nsites/__init__.py,sha256=RlQg7ivczXCXG5lMeL3ipYKj2oJKC4THu8orYf5PBYs,263
|
|
117
117
|
bloqade/squin/analysis/nsites/analysis.py,sha256=rIe1RU1MZRItcE2aB8DYahLrv73HfD3IHCX3E_EGQ1c,1773
|
|
118
|
-
bloqade/squin/analysis/nsites/impls.py,sha256=
|
|
118
|
+
bloqade/squin/analysis/nsites/impls.py,sha256=Q2buVBmUX1ghj48_SoMO-_0BASGkfnILZZOOFRnwzIQ,2772
|
|
119
119
|
bloqade/squin/analysis/nsites/lattice.py,sha256=ruh0808SHtj3ecuT-C3AZTsLY2j3DRhtezGiTZvcuVs,942
|
|
120
120
|
bloqade/squin/cirq/__init__.py,sha256=AptJlelH-KJoFKLnq6phq68SrV785zWzi2NOfLH62ms,5994
|
|
121
121
|
bloqade/squin/cirq/lowering.py,sha256=4-kZFH_qbBbV-c3-C9KhIB5o_cp_D8oxJrS8KicD_A8,14382
|
|
@@ -128,26 +128,21 @@ bloqade/squin/noise/_dialect.py,sha256=2IR98J-lXm5Y3srP9g-FD4JC-qTq2seureM6mKKq1
|
|
|
128
128
|
bloqade/squin/noise/_wrapper.py,sha256=0jD5va_go9jEW5rC6bZSWU30kjCha2-axFogPON3-V0,580
|
|
129
129
|
bloqade/squin/noise/rewrite.py,sha256=SxIHgMDqYJXepiZDyukHWpe5yaFDSTG-yJ4JONNVr0o,3917
|
|
130
130
|
bloqade/squin/noise/stmts.py,sha256=rktxkIdjdPUYek0MYh9uh83otkl-7UoADCoWHWf57J8,1678
|
|
131
|
-
bloqade/squin/op/__init__.py,sha256=
|
|
131
|
+
bloqade/squin/op/__init__.py,sha256=QLlvZlb2nDq-RTalRp7xe0v82YgXURsvyovvMA6j2mw,807
|
|
132
132
|
bloqade/squin/op/_dialect.py,sha256=66G1IYqmsqUEaCTyUqn2shSHmGYduiTU8GfDXcoMvw4,55
|
|
133
|
-
bloqade/squin/op/_wrapper.py,sha256=
|
|
133
|
+
bloqade/squin/op/_wrapper.py,sha256=rmQHXjRHFEr-bATbKEKL30w1wlDB7vmrQzDDRoLhRVw,1866
|
|
134
134
|
bloqade/squin/op/number.py,sha256=yujWUqLrOAr8i8OBDsiS5M882wV7t08u345NgNA6TUc,95
|
|
135
135
|
bloqade/squin/op/rewrite.py,sha256=Itxz_hTAPNLyLYeLS0PCVk143J1Z558UR7N9-urbnoU,1327
|
|
136
136
|
bloqade/squin/op/stdlib.py,sha256=4UFK3wKImpums2v5a9OFKuVvz2TLYbYwidg3JYYEi2o,1073
|
|
137
|
-
bloqade/squin/op/stmts.py,sha256=
|
|
137
|
+
bloqade/squin/op/stmts.py,sha256=atPrr12Bc7D5xu_xavVgME3FBNqHQXQSAtMuh7xL0Dw,5491
|
|
138
138
|
bloqade/squin/op/traits.py,sha256=jjsnzWtPtmQK7K3H_D2fvc8XiW1Y3EMBcgeyPax2sjc,1065
|
|
139
139
|
bloqade/squin/op/types.py,sha256=ozUT0Bv9NuUxPjB2vAeqJ9cpdvUaBfP9trB5mybYxgc,663
|
|
140
|
-
bloqade/squin/
|
|
141
|
-
bloqade/squin/
|
|
142
|
-
bloqade/squin/rewrite/__init__.py,sha256=0-9m1cbvFRgjZpQ700NEjW1uKvwZPPbrmUwylhgOjUw,457
|
|
140
|
+
bloqade/squin/rewrite/U3_to_clifford.py,sha256=HpkFTqe-J0macb_aNs1QNs8wJDoUsmwf9Mtb0I3ZepI,5377
|
|
141
|
+
bloqade/squin/rewrite/__init__.py,sha256=mxP01A2IeOT5HKHKBRRMCIPN4BPKfpYSlQkSjY78ugQ,282
|
|
143
142
|
bloqade/squin/rewrite/desugar.py,sha256=fnxchVHIbLx96cv-g_jK7NCVV8t8mo52rs00JaPG7FM,1846
|
|
144
|
-
bloqade/squin/rewrite/
|
|
145
|
-
bloqade/squin/rewrite/
|
|
146
|
-
bloqade/
|
|
147
|
-
bloqade/squin/rewrite/wire_identity_elimination.py,sha256=Cscu8yaSslPuW04HvbXx4HJ3JzdUZNUMyFqcvuc4sxY,795
|
|
148
|
-
bloqade/squin/rewrite/wire_to_stim.py,sha256=PbXjwaF-Z2JioXALKx76uGkYr6-xy20zZFotPeDX-lY,1699
|
|
149
|
-
bloqade/squin/rewrite/wrap_analysis.py,sha256=OoKoS0zFLjfCnn4_fK4bgpQ_ueAEiHl1UmfNWhruxMc,2069
|
|
150
|
-
bloqade/stim/__init__.py,sha256=BbMeLjeIW29xuD6JB0cWG_g0qaYIy4xXbloDqvqbT7A,887
|
|
143
|
+
bloqade/squin/rewrite/remove_dangling_qubits.py,sha256=iTuWV-03YW5wtYbSeKMlnnWjNzDj9SmflyqYPgoYGy8,469
|
|
144
|
+
bloqade/squin/rewrite/wrap_analysis.py,sha256=JUPS4OAYbDHOK0VIrdz1pprSizISUfN7osuoP_P-bIo,2256
|
|
145
|
+
bloqade/stim/__init__.py,sha256=-TkpVoISvZ-HERL2LJfIMHs3Y4k-WdrGWM-_Rwe9q0o,905
|
|
151
146
|
bloqade/stim/_wrappers.py,sha256=KBIIOaeYPnhR3SJSNHcEzihLMcph2tL2mRKhEH47Je8,3939
|
|
152
147
|
bloqade/stim/groups.py,sha256=Fx8G698BGO7hR8OwpPXGUEYdW4uCCPwbMp_3fJAqa8M,585
|
|
153
148
|
bloqade/stim/dialects/__init__.py,sha256=A1Sq0jg8wi6MjRkzmuSBnHmO3EraD0pDFWz-dO6c6v8,89
|
|
@@ -159,7 +154,7 @@ bloqade/stim/dialects/auxiliary/lowering.py,sha256=4dxRZHGp_18EMVlYuZQFSzg4MIOBr
|
|
|
159
154
|
bloqade/stim/dialects/auxiliary/types.py,sha256=1l2YdJ-u9y0wpBfxh4OAlvmRAUnrmcDjDagoW2GyVaQ,314
|
|
160
155
|
bloqade/stim/dialects/auxiliary/stmts/__init__.py,sha256=VxLBnqlZngabs5vn3PiRNRXBBDueTCTmJ2wgWEertrA,371
|
|
161
156
|
bloqade/stim/dialects/auxiliary/stmts/annotate.py,sha256=NZT4AAW0lmwyHR31cmZI8aQNRsp5soeE36s9nBrcOmU,1759
|
|
162
|
-
bloqade/stim/dialects/auxiliary/stmts/const.py,sha256=
|
|
157
|
+
bloqade/stim/dialects/auxiliary/stmts/const.py,sha256=nxcpVylgjfKt8pDkcMzVBMGLjON2bQb99WSLv7frvkI,3298
|
|
163
158
|
bloqade/stim/dialects/collapse/__init__.py,sha256=MhlEWJR_mJI3teoip1N8MlHk2C68seJELXwmyjyx_ns,305
|
|
164
159
|
bloqade/stim/dialects/collapse/_dialect.py,sha256=F5uplH7WL9ZQatEp0ZMvgLWX1k9moAWW879LTNwnHH0,60
|
|
165
160
|
bloqade/stim/dialects/collapse/emit_str.py,sha256=4Vlhtq8BKMMuZLQ-ayUGJTuOs4YJ1rGurPZBZxBQJcU,1879
|
|
@@ -170,7 +165,7 @@ bloqade/stim/dialects/collapse/stmts/reset.py,sha256=4fPSdM_ZiivuUn4uiZGiZQ9swol
|
|
|
170
165
|
bloqade/stim/dialects/gate/__init__.py,sha256=5Y0BTlLOuW-Ud4LwAC_CUuMwxa04LKj4CTKgQbiL8yg,347
|
|
171
166
|
bloqade/stim/dialects/gate/_dialect.py,sha256=78_dThliFZG9xSwYhTdibxP3vefHpEDUawtZqb9X3uA,56
|
|
172
167
|
bloqade/stim/dialects/gate/emit.py,sha256=HGnko9_nV6jl0kOI_dBWWNQDjySo14jAFBsg-2lTVOU,2869
|
|
173
|
-
bloqade/stim/dialects/gate/stmts/__init__.py,sha256=
|
|
168
|
+
bloqade/stim/dialects/gate/stmts/__init__.py,sha256=TbXjWYfCbZNuGEehvtF75LELLJJo_GzoXWRnuVZphv8,461
|
|
174
169
|
bloqade/stim/dialects/gate/stmts/base.py,sha256=MK7Zu-Kys_64O0nXAkPzlHEnWYevBGm3FRHhJw33rrE,748
|
|
175
170
|
bloqade/stim/dialects/gate/stmts/clifford_1q.py,sha256=Sj1Nf9AA_WWazGTg5kzFRTaLRIj3Edj657j0B8dybdI,896
|
|
176
171
|
bloqade/stim/dialects/gate/stmts/clifford_2q.py,sha256=cb3BVSkOt5SiRq4D4WkbuUbEouK3MwDxQIhAF0cvZbo,239
|
|
@@ -184,6 +179,15 @@ bloqade/stim/emit/__init__.py,sha256=N2dPQY7OyqPwHAStDeOgYg2yfxqxMOz-N7pD5Z4JwlI
|
|
|
184
179
|
bloqade/stim/emit/stim_str.py,sha256=JyEBoIhLQASogZcUWHI9tMD4JoXYrEqUr2qaZ30gZdc,1491
|
|
185
180
|
bloqade/stim/parse/__init__.py,sha256=l2DjReB2KkgrDjP_4nP6RnoziiOewoSeZfTno1sVYTw,59
|
|
186
181
|
bloqade/stim/parse/lowering.py,sha256=L-IcR_exlxsTVv4SQ0bhzIF4_L82P-GEdK6qRd6B86Y,23723
|
|
182
|
+
bloqade/stim/passes/__init__.py,sha256=KAWJPhZHf0cVDmr9o9LNRfZU8G9aS4adGC4EC7ci_E8,54
|
|
183
|
+
bloqade/stim/passes/squin_to_stim.py,sha256=4CSWAevECGxYgtojzlH92YwRUlz_lDtedWNEylXKd0A,2752
|
|
184
|
+
bloqade/stim/rewrite/__init__.py,sha256=S2sKUKtX4EGofhZRbewvyHN5s-CavPzseYufij3R5SQ,372
|
|
185
|
+
bloqade/stim/rewrite/py_constant_to_stim.py,sha256=PV8bHvn759-d_0JW4akaGSORW_oxigrlUBhAC51PJAU,1354
|
|
186
|
+
bloqade/stim/rewrite/qubit_to_stim.py,sha256=VggIAS6EQ4a01YplDGJUMDpQ_q-UYD8C4g1xMC_zbcY,2509
|
|
187
|
+
bloqade/stim/rewrite/squin_measure.py,sha256=1X3rcfGvVDSEXmvqlw4T0LQu2A8LFeNeqz1_zf_I8vA,2466
|
|
188
|
+
bloqade/stim/rewrite/util.py,sha256=vpBbTv00odpnnyHTMJZRStb1ZQYfcgbOW5PT5Frf4jw,5847
|
|
189
|
+
bloqade/stim/rewrite/wire_identity_elimination.py,sha256=Cscu8yaSslPuW04HvbXx4HJ3JzdUZNUMyFqcvuc4sxY,795
|
|
190
|
+
bloqade/stim/rewrite/wire_to_stim.py,sha256=vHtktd9pfjlEpInwN7pPhsIHCxTtHJJqJJhYpy0kIGg,1685
|
|
187
191
|
bloqade/visual/__init__.py,sha256=Y7d0YgovKhUFzjMeDvt0wGRUZ3re3SY6iO3e8xHXrr4,37
|
|
188
192
|
bloqade/visual/animation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
189
193
|
bloqade/visual/animation/animate.py,sha256=NSKs3YDWgTZH2-Tpx3cP1bBcIEWTEPqK5UFkY_IF_3k,8927
|
|
@@ -195,7 +199,7 @@ bloqade/visual/animation/runtime/atoms.py,sha256=EmjxhujLiHHPS_HtH_B-7TiqeHgvW5u
|
|
|
195
199
|
bloqade/visual/animation/runtime/ppoly.py,sha256=JB9IP53N1w6adBJEue6J5Nmj818Id9JvrlgrmiQTU1I,1385
|
|
196
200
|
bloqade/visual/animation/runtime/qpustate.py,sha256=rlmxQeJSvaohXrTpXQL5y-NJcpvfW33xPaYM1slv7cc,4270
|
|
197
201
|
bloqade/visual/animation/runtime/utils.py,sha256=ju9IzOWX-vKwfpqUjlUKu3Ssr_UFPFFq-tzH_Nqyo_c,1212
|
|
198
|
-
bloqade_circuit-0.4.
|
|
199
|
-
bloqade_circuit-0.4.
|
|
200
|
-
bloqade_circuit-0.4.
|
|
201
|
-
bloqade_circuit-0.4.
|
|
202
|
+
bloqade_circuit-0.4.4.dist-info/METADATA,sha256=WNmsRDnheZ4YMfpb6skDmZ3tTRy_8eh8OwdyYXtCSwY,3683
|
|
203
|
+
bloqade_circuit-0.4.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
204
|
+
bloqade_circuit-0.4.4.dist-info/licenses/LICENSE,sha256=S5GIJwR6QCixPA9wryYb44ZEek0Nz4rt_zLUqP05UbU,13160
|
|
205
|
+
bloqade_circuit-0.4.4.dist-info/RECORD,,
|
bloqade/squin/passes/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .stim import SquinToStim as SquinToStim
|
bloqade/squin/passes/stim.py
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
|
|
3
|
-
from kirin.passes import Fold
|
|
4
|
-
from kirin.rewrite import (
|
|
5
|
-
Walk,
|
|
6
|
-
Chain,
|
|
7
|
-
Fixpoint,
|
|
8
|
-
DeadCodeElimination,
|
|
9
|
-
CommonSubexpressionElimination,
|
|
10
|
-
)
|
|
11
|
-
from kirin.ir.method import Method
|
|
12
|
-
from kirin.passes.abc import Pass
|
|
13
|
-
from kirin.rewrite.abc import RewriteResult
|
|
14
|
-
|
|
15
|
-
from bloqade.squin.rewrite import (
|
|
16
|
-
SquinWireToStim,
|
|
17
|
-
SquinQubitToStim,
|
|
18
|
-
WrapSquinAnalysis,
|
|
19
|
-
SquinMeasureToStim,
|
|
20
|
-
SquinWireIdentityElimination,
|
|
21
|
-
)
|
|
22
|
-
from bloqade.analysis.address import AddressAnalysis
|
|
23
|
-
from bloqade.squin.analysis.nsites import (
|
|
24
|
-
NSitesAnalysis,
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@dataclass
|
|
29
|
-
class SquinToStim(Pass):
|
|
30
|
-
|
|
31
|
-
def unsafe_run(self, mt: Method) -> RewriteResult:
|
|
32
|
-
fold_pass = Fold(mt.dialects)
|
|
33
|
-
# propagate constants
|
|
34
|
-
rewrite_result = fold_pass(mt)
|
|
35
|
-
|
|
36
|
-
# Get necessary analysis results to plug into hints
|
|
37
|
-
address_analysis = AddressAnalysis(mt.dialects)
|
|
38
|
-
address_frame, _ = address_analysis.run_analysis(mt)
|
|
39
|
-
site_analysis = NSitesAnalysis(mt.dialects)
|
|
40
|
-
sites_frame, _ = site_analysis.run_analysis(mt)
|
|
41
|
-
|
|
42
|
-
# Wrap Rewrite + SquinToStim can happen w/ standard walk
|
|
43
|
-
rewrite_result = (
|
|
44
|
-
Walk(
|
|
45
|
-
Chain(
|
|
46
|
-
WrapSquinAnalysis(
|
|
47
|
-
address_analysis=address_frame.entries,
|
|
48
|
-
op_site_analysis=sites_frame.entries,
|
|
49
|
-
),
|
|
50
|
-
SquinQubitToStim(),
|
|
51
|
-
SquinWireToStim(),
|
|
52
|
-
SquinMeasureToStim(), # reduce duplicated logic, can split out even more rules later
|
|
53
|
-
SquinWireIdentityElimination(),
|
|
54
|
-
)
|
|
55
|
-
)
|
|
56
|
-
.rewrite(mt.code)
|
|
57
|
-
.join(rewrite_result)
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
rewrite_result = (
|
|
61
|
-
Fixpoint(
|
|
62
|
-
Walk(Chain(DeadCodeElimination(), CommonSubexpressionElimination()))
|
|
63
|
-
)
|
|
64
|
-
.rewrite(mt.code)
|
|
65
|
-
.join(rewrite_result)
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
return rewrite_result
|
|
File without changes
|
|
File without changes
|
|
File without changes
|