bloqade-circuit 0.5.3__py3-none-any.whl → 0.6.1__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/qasm2/_qasm_loading.py +4 -1
- bloqade/qasm2/parse/lowering.py +11 -3
- bloqade/squin/lowering.py +29 -2
- bloqade/squin/noise/__init__.py +1 -0
- bloqade/squin/noise/_wrapper.py +4 -0
- bloqade/squin/noise/stmts.py +10 -1
- bloqade/squin/op/stmts.py +4 -4
- bloqade/squin/rewrite/desugar.py +27 -15
- bloqade/stim/passes/squin_to_stim.py +1 -11
- bloqade/stim/rewrite/squin_noise.py +68 -13
- bloqade/stim/rewrite/util.py +20 -1
- {bloqade_circuit-0.5.3.dist-info → bloqade_circuit-0.6.1.dist-info}/METADATA +1 -1
- {bloqade_circuit-0.5.3.dist-info → bloqade_circuit-0.6.1.dist-info}/RECORD +15 -15
- {bloqade_circuit-0.5.3.dist-info → bloqade_circuit-0.6.1.dist-info}/WHEEL +0 -0
- {bloqade_circuit-0.5.3.dist-info → bloqade_circuit-0.6.1.dist-info}/licenses/LICENSE +0 -0
bloqade/qasm2/_qasm_loading.py
CHANGED
|
@@ -82,7 +82,7 @@ def loads(
|
|
|
82
82
|
body=body,
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
mt = ir.Method(
|
|
86
86
|
mod=None,
|
|
87
87
|
py_func=None,
|
|
88
88
|
sym_name=kernel_name,
|
|
@@ -91,6 +91,9 @@ def loads(
|
|
|
91
91
|
code=code,
|
|
92
92
|
)
|
|
93
93
|
|
|
94
|
+
mt.verify()
|
|
95
|
+
return mt
|
|
96
|
+
|
|
94
97
|
|
|
95
98
|
def loadfile(
|
|
96
99
|
qasm_file: str | pathlib.Path,
|
bloqade/qasm2/parse/lowering.py
CHANGED
|
@@ -202,7 +202,13 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
202
202
|
|
|
203
203
|
then_body = if_frame.curr_region
|
|
204
204
|
|
|
205
|
-
|
|
205
|
+
# NOTE: create empty else body
|
|
206
|
+
else_body = ir.Block(stmts=[scf.Yield()])
|
|
207
|
+
else_body.args.append_from(types.Bool)
|
|
208
|
+
|
|
209
|
+
state.current_frame.push(
|
|
210
|
+
scf.IfElse(cond, then_body=then_body, else_body=else_body)
|
|
211
|
+
)
|
|
206
212
|
|
|
207
213
|
def branch_next_if_not_terminated(self, frame: lowering.Frame):
|
|
208
214
|
"""Branch to the next block if the current block is not terminated.
|
|
@@ -381,6 +387,8 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
381
387
|
QubitType for _ in node.qparams
|
|
382
388
|
]
|
|
383
389
|
|
|
390
|
+
self_name = node.name + "_self"
|
|
391
|
+
|
|
384
392
|
with state.frame(
|
|
385
393
|
stmts=node.body,
|
|
386
394
|
finalize_next=False,
|
|
@@ -390,7 +398,7 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
390
398
|
types.Generic(
|
|
391
399
|
ir.Method, types.Tuple.where(tuple(arg_types)), types.NoneType
|
|
392
400
|
),
|
|
393
|
-
name=
|
|
401
|
+
name=self_name,
|
|
394
402
|
)
|
|
395
403
|
|
|
396
404
|
for arg_type, arg_name in zip(arg_types, arg_names):
|
|
@@ -422,7 +430,7 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
422
430
|
py_func=None,
|
|
423
431
|
sym_name=node.name,
|
|
424
432
|
dialects=self.dialects,
|
|
425
|
-
arg_names=[*node.cparams, *node.qparams],
|
|
433
|
+
arg_names=[self_name, *node.cparams, *node.qparams],
|
|
426
434
|
code=gate_func,
|
|
427
435
|
)
|
|
428
436
|
state.current_frame.globals[node.name] = mt
|
bloqade/squin/lowering.py
CHANGED
|
@@ -15,13 +15,40 @@ class ApplyAnyCallLowering(lowering.FromPythonCall["qubit.ApplyAny"]):
|
|
|
15
15
|
def lower(
|
|
16
16
|
self, stmt: type["qubit.ApplyAny"], state: lowering.State, node: ast.Call
|
|
17
17
|
):
|
|
18
|
-
if len(node.args) < 2:
|
|
18
|
+
if len(node.args) + len(node.keywords) < 2:
|
|
19
19
|
raise lowering.BuildError(
|
|
20
20
|
"Apply requires at least one operator and one qubit as arguments!"
|
|
21
21
|
)
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
op, qubits = self.unpack_arguments(node)
|
|
24
|
+
|
|
23
25
|
op_ssa = state.lower(op).expect_one()
|
|
24
26
|
qubits_lowered = [state.lower(qbit).expect_one() for qbit in qubits]
|
|
25
27
|
|
|
26
28
|
s = stmt(op_ssa, tuple(qubits_lowered))
|
|
27
29
|
return state.current_frame.push(s)
|
|
30
|
+
|
|
31
|
+
def unpack_arguments(self, node: ast.Call) -> tuple[ast.expr, list[ast.expr]]:
|
|
32
|
+
if len(node.keywords) == 0:
|
|
33
|
+
op, *qubits = node.args
|
|
34
|
+
return op, qubits
|
|
35
|
+
|
|
36
|
+
kwargs = {kw.arg: kw.value for kw in node.keywords}
|
|
37
|
+
if len(kwargs) > 2 or "qubits" not in kwargs:
|
|
38
|
+
raise lowering.BuildError(f"Got unsupported keyword argument {kwargs}")
|
|
39
|
+
|
|
40
|
+
qubits = kwargs["qubits"]
|
|
41
|
+
if len(kwargs) == 1:
|
|
42
|
+
if len(node.args) != 1:
|
|
43
|
+
raise lowering.BuildError("Missing operator argument")
|
|
44
|
+
op = node.args[0]
|
|
45
|
+
else:
|
|
46
|
+
try:
|
|
47
|
+
op = kwargs["operator"]
|
|
48
|
+
except KeyError:
|
|
49
|
+
raise lowering.BuildError(f"Got unsupported keyword argument {kwargs}")
|
|
50
|
+
|
|
51
|
+
if isinstance(qubits, ast.List):
|
|
52
|
+
return op, qubits.elts
|
|
53
|
+
|
|
54
|
+
return op, [qubits]
|
bloqade/squin/noise/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ from ._wrapper import (
|
|
|
4
4
|
pp_error as pp_error,
|
|
5
5
|
depolarize as depolarize,
|
|
6
6
|
qubit_loss as qubit_loss,
|
|
7
|
+
depolarize2 as depolarize2,
|
|
7
8
|
pauli_error as pauli_error,
|
|
8
9
|
two_qubit_pauli_channel as two_qubit_pauli_channel,
|
|
9
10
|
single_qubit_pauli_channel as single_qubit_pauli_channel,
|
bloqade/squin/noise/_wrapper.py
CHANGED
|
@@ -20,6 +20,10 @@ def pp_error(op: Op, p: float) -> Op: ...
|
|
|
20
20
|
def depolarize(p: float) -> Op: ...
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
@wraps(stmts.Depolarize2)
|
|
24
|
+
def depolarize2(p: float) -> Op: ...
|
|
25
|
+
|
|
26
|
+
|
|
23
27
|
@wraps(stmts.SingleQubitPauliChannel)
|
|
24
28
|
def single_qubit_pauli_channel(
|
|
25
29
|
params: ilist.IList[float, Literal[3]] | list[float] | tuple[float, float, float],
|
bloqade/squin/noise/stmts.py
CHANGED
|
@@ -33,7 +33,16 @@ class PPError(NoiseChannel):
|
|
|
33
33
|
@statement(dialect=dialect)
|
|
34
34
|
class Depolarize(NoiseChannel):
|
|
35
35
|
"""
|
|
36
|
-
Apply depolarize error to qubit
|
|
36
|
+
Apply depolarize error to single qubit
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
p: ir.SSAValue = info.argument(types.Float)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@statement(dialect=dialect)
|
|
43
|
+
class Depolarize2(NoiseChannel):
|
|
44
|
+
"""
|
|
45
|
+
Apply correlated depolarize error to two qubit
|
|
37
46
|
"""
|
|
38
47
|
|
|
39
48
|
p: ir.SSAValue = info.argument(types.Float)
|
bloqade/squin/op/stmts.py
CHANGED
|
@@ -103,7 +103,7 @@ class U3(PrimitiveOp):
|
|
|
103
103
|
Note that we use the convention from the QASM2 specification, namely
|
|
104
104
|
|
|
105
105
|
$$
|
|
106
|
-
U_3(
|
|
106
|
+
U_3(\\theta, \\phi, \\lambda) = R_z(\\phi) R_y(\\theta) R_z(\\lambda)
|
|
107
107
|
$$
|
|
108
108
|
"""
|
|
109
109
|
|
|
@@ -119,7 +119,7 @@ class PhaseOp(PrimitiveOp):
|
|
|
119
119
|
A phase operator.
|
|
120
120
|
|
|
121
121
|
$$
|
|
122
|
-
PhaseOp(
|
|
122
|
+
\\text{PhaseOp}(\\theta) = e^{i \\theta} I
|
|
123
123
|
$$
|
|
124
124
|
"""
|
|
125
125
|
|
|
@@ -133,7 +133,7 @@ class ShiftOp(PrimitiveOp):
|
|
|
133
133
|
A phase shift operator.
|
|
134
134
|
|
|
135
135
|
$$
|
|
136
|
-
Shift(
|
|
136
|
+
\\text{Shift}(\\theta) = \\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i \\theta} \\end{bmatrix}
|
|
137
137
|
$$
|
|
138
138
|
"""
|
|
139
139
|
|
|
@@ -144,7 +144,7 @@ class ShiftOp(PrimitiveOp):
|
|
|
144
144
|
@statement(dialect=dialect)
|
|
145
145
|
class Reset(PrimitiveOp):
|
|
146
146
|
"""
|
|
147
|
-
Reset operator for qubits
|
|
147
|
+
Reset operator for qubits and wires.
|
|
148
148
|
"""
|
|
149
149
|
|
|
150
150
|
traits = frozenset({ir.Pure(), lowering.FromPythonCall(), FixedSites(1)})
|
bloqade/squin/rewrite/desugar.py
CHANGED
|
@@ -54,7 +54,9 @@ class ApplyDesugarRule(RewriteRule):
|
|
|
54
54
|
qubits = node.qubits
|
|
55
55
|
|
|
56
56
|
if len(qubits) > 1 and all(q.type.is_subseteq(QubitType) for q in qubits):
|
|
57
|
-
(qubits_ilist_stmt := ilist.New(qubits)).insert_before(
|
|
57
|
+
(qubits_ilist_stmt := ilist.New(qubits)).insert_before(
|
|
58
|
+
node
|
|
59
|
+
) # qubits is just a tuple of SSAValues
|
|
58
60
|
qubits_ilist = qubits_ilist_stmt.result
|
|
59
61
|
|
|
60
62
|
elif len(qubits) == 1 and qubits[0].type.is_subseteq(QubitType):
|
|
@@ -76,34 +78,44 @@ class ApplyDesugarRule(RewriteRule):
|
|
|
76
78
|
return RewriteResult()
|
|
77
79
|
|
|
78
80
|
is_ilist = isinstance(qbit_stmt := qubits[0].stmt, ilist.New)
|
|
81
|
+
|
|
79
82
|
if is_ilist:
|
|
80
|
-
if len(qbit_stmt.values) != 1:
|
|
81
|
-
return RewriteResult()
|
|
82
83
|
|
|
83
|
-
if not
|
|
84
|
-
qbit_getindex_result
|
|
84
|
+
if not all(
|
|
85
|
+
isinstance(qbit_getindex_result, ir.ResultValue)
|
|
86
|
+
for qbit_getindex_result in qbit_stmt.values
|
|
85
87
|
):
|
|
86
88
|
return RewriteResult()
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
# Get the parent statement that the qubit came from
|
|
91
|
+
# (should be a GetItem instance, see logic below)
|
|
92
|
+
qbit_getindices = [
|
|
93
|
+
qbit_getindex_result.stmt
|
|
94
|
+
for qbit_getindex_result in qbit_stmt.values
|
|
95
|
+
]
|
|
89
96
|
else:
|
|
90
|
-
|
|
97
|
+
qbit_getindices = [qubit.stmt for qubit in qubits]
|
|
91
98
|
|
|
92
|
-
if
|
|
99
|
+
if any(
|
|
100
|
+
not isinstance(qbit_getindex, py.indexing.GetItem)
|
|
101
|
+
for qbit_getindex in qbit_getindices
|
|
102
|
+
):
|
|
93
103
|
return RewriteResult()
|
|
94
104
|
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
# The GetItem should have been applied on something that returns an IList of Qubits
|
|
106
|
+
if any(
|
|
107
|
+
not qbit_getindex.obj.type.is_subseteq(
|
|
108
|
+
ilist.IListType[QubitType, types.Any]
|
|
109
|
+
)
|
|
110
|
+
for qbit_getindex in qbit_getindices
|
|
97
111
|
):
|
|
98
112
|
return RewriteResult()
|
|
99
113
|
|
|
100
114
|
if is_ilist:
|
|
101
|
-
|
|
115
|
+
qubits_ilist = qbit_stmt.result
|
|
102
116
|
else:
|
|
103
|
-
values
|
|
104
|
-
|
|
105
|
-
(qubits_ilist_stmt := ilist.New(values=values)).insert_before(node)
|
|
106
|
-
qubits_ilist = qubits_ilist_stmt.result
|
|
117
|
+
(qubits_ilist_stmt := ilist.New(values=[qubits[0]])).insert_before(node)
|
|
118
|
+
qubits_ilist = qubits_ilist_stmt.result
|
|
107
119
|
else:
|
|
108
120
|
return RewriteResult()
|
|
109
121
|
|
|
@@ -11,7 +11,6 @@ from kirin.rewrite import (
|
|
|
11
11
|
DeadCodeElimination,
|
|
12
12
|
CommonSubexpressionElimination,
|
|
13
13
|
)
|
|
14
|
-
from kirin.analysis import const
|
|
15
14
|
from kirin.dialects import scf, ilist
|
|
16
15
|
from kirin.ir.method import Method
|
|
17
16
|
from kirin.passes.abc import Pass
|
|
@@ -44,11 +43,6 @@ class SquinToStimPass(Pass):
|
|
|
44
43
|
|
|
45
44
|
def unsafe_run(self, mt: Method) -> RewriteResult:
|
|
46
45
|
|
|
47
|
-
cp_frame, _ = const.Propagate(dialects=mt.dialects).run_analysis(mt)
|
|
48
|
-
cp_results = cp_frame.entries
|
|
49
|
-
|
|
50
|
-
# Assume that address analysis and
|
|
51
|
-
# wrapping has been done before this pass!
|
|
52
46
|
# inline aggressively:
|
|
53
47
|
rewrite_result = InlinePass(
|
|
54
48
|
dialects=mt.dialects, no_raise=self.no_raise
|
|
@@ -117,11 +111,7 @@ class SquinToStimPass(Pass):
|
|
|
117
111
|
)
|
|
118
112
|
|
|
119
113
|
# Rewrite the noise statements first.
|
|
120
|
-
rewrite_result = (
|
|
121
|
-
Walk(SquinNoiseToStim(cp_results=cp_results))
|
|
122
|
-
.rewrite(mt.code)
|
|
123
|
-
.join(rewrite_result)
|
|
124
|
-
)
|
|
114
|
+
rewrite_result = Walk(SquinNoiseToStim()).rewrite(mt.code).join(rewrite_result)
|
|
125
115
|
|
|
126
116
|
# Wrap Rewrite + SquinToStim can happen w/ standard walk
|
|
127
117
|
rewrite_result = Walk(SquinU3ToClifford()).rewrite(mt.code).join(rewrite_result)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Tuple
|
|
2
2
|
from dataclasses import dataclass
|
|
3
3
|
|
|
4
4
|
from kirin.ir import SSAValue, Statement
|
|
5
|
-
from kirin.
|
|
6
|
-
from kirin.dialects import py
|
|
5
|
+
from kirin.dialects import py, ilist
|
|
7
6
|
from kirin.rewrite.abc import RewriteRule, RewriteResult
|
|
8
7
|
|
|
9
|
-
from bloqade.squin import wire, noise as squin_noise, qubit
|
|
8
|
+
from bloqade.squin import op, wire, noise as squin_noise, qubit
|
|
10
9
|
from bloqade.stim.dialects import noise as stim_noise
|
|
11
10
|
from bloqade.stim.rewrite.util import (
|
|
11
|
+
get_const_value,
|
|
12
12
|
create_wire_passthrough,
|
|
13
13
|
insert_qubit_idx_after_apply,
|
|
14
14
|
)
|
|
@@ -17,8 +17,6 @@ from bloqade.stim.rewrite.util import (
|
|
|
17
17
|
@dataclass
|
|
18
18
|
class SquinNoiseToStim(RewriteRule):
|
|
19
19
|
|
|
20
|
-
cp_results: Dict[SSAValue, const.Result]
|
|
21
|
-
|
|
22
20
|
def rewrite_Statement(self, node: Statement) -> RewriteResult:
|
|
23
21
|
match node:
|
|
24
22
|
case qubit.Apply() | qubit.Broadcast():
|
|
@@ -34,17 +32,17 @@ class SquinNoiseToStim(RewriteRule):
|
|
|
34
32
|
# this is an SSAValue, need it to be the actual operator
|
|
35
33
|
applied_op = stmt.operator.owner
|
|
36
34
|
|
|
35
|
+
if isinstance(applied_op, squin_noise.stmts.QubitLoss):
|
|
36
|
+
return RewriteResult()
|
|
37
|
+
|
|
37
38
|
if isinstance(applied_op, squin_noise.stmts.NoiseChannel):
|
|
38
39
|
|
|
39
40
|
qubit_idx_ssas = insert_qubit_idx_after_apply(stmt=stmt)
|
|
40
41
|
if qubit_idx_ssas is None:
|
|
41
42
|
return RewriteResult()
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
stim_stmt = self.rewrite_SingleQubitPauliChannel(stmt, qubit_idx_ssas)
|
|
46
|
-
elif isinstance(applied_op, squin_noise.stmts.TwoQubitPauliChannel):
|
|
47
|
-
stim_stmt = self.rewrite_TwoQubitPauliChannel(stmt, qubit_idx_ssas)
|
|
44
|
+
rewrite_method = getattr(self, f"rewrite_{type(applied_op).__name__}")
|
|
45
|
+
stim_stmt = rewrite_method(stmt, qubit_idx_ssas)
|
|
48
46
|
|
|
49
47
|
if isinstance(stmt, (wire.Apply, wire.Broadcast)):
|
|
50
48
|
create_wire_passthrough(stmt)
|
|
@@ -57,6 +55,29 @@ class SquinNoiseToStim(RewriteRule):
|
|
|
57
55
|
return RewriteResult(has_done_something=True)
|
|
58
56
|
return RewriteResult()
|
|
59
57
|
|
|
58
|
+
def rewrite_PauliError(
|
|
59
|
+
self,
|
|
60
|
+
stmt: qubit.Apply | qubit.Broadcast | wire.Broadcast | wire.Apply,
|
|
61
|
+
qubit_idx_ssas: Tuple[SSAValue],
|
|
62
|
+
) -> Statement:
|
|
63
|
+
"""Rewrite squin.noise.PauliError to XError, YError, ZError."""
|
|
64
|
+
squin_channel = stmt.operator.owner
|
|
65
|
+
assert isinstance(squin_channel, squin_noise.stmts.PauliError)
|
|
66
|
+
basis = squin_channel.basis.owner
|
|
67
|
+
assert isinstance(basis, op.stmts.PauliOp)
|
|
68
|
+
p = get_const_value(float, squin_channel.p)
|
|
69
|
+
|
|
70
|
+
p_stmt = py.Constant(p)
|
|
71
|
+
p_stmt.insert_before(stmt)
|
|
72
|
+
|
|
73
|
+
if isinstance(basis, op.stmts.X):
|
|
74
|
+
stim_stmt = stim_noise.XError(targets=qubit_idx_ssas, p=p_stmt.result)
|
|
75
|
+
elif isinstance(basis, op.stmts.Y):
|
|
76
|
+
stim_stmt = stim_noise.YError(targets=qubit_idx_ssas, p=p_stmt.result)
|
|
77
|
+
else:
|
|
78
|
+
stim_stmt = stim_noise.ZError(targets=qubit_idx_ssas, p=p_stmt.result)
|
|
79
|
+
return stim_stmt
|
|
80
|
+
|
|
60
81
|
def rewrite_SingleQubitPauliChannel(
|
|
61
82
|
self,
|
|
62
83
|
stmt: qubit.Apply | qubit.Broadcast | wire.Broadcast | wire.Apply,
|
|
@@ -67,7 +88,7 @@ class SquinNoiseToStim(RewriteRule):
|
|
|
67
88
|
squin_channel = stmt.operator.owner
|
|
68
89
|
assert isinstance(squin_channel, squin_noise.stmts.SingleQubitPauliChannel)
|
|
69
90
|
|
|
70
|
-
params =
|
|
91
|
+
params = get_const_value(ilist.IList, squin_channel.params)
|
|
71
92
|
new_stmts = [
|
|
72
93
|
p_x := py.Constant(params[0]),
|
|
73
94
|
p_y := py.Constant(params[1]),
|
|
@@ -94,7 +115,7 @@ class SquinNoiseToStim(RewriteRule):
|
|
|
94
115
|
squin_channel = stmt.operator.owner
|
|
95
116
|
assert isinstance(squin_channel, squin_noise.stmts.TwoQubitPauliChannel)
|
|
96
117
|
|
|
97
|
-
params =
|
|
118
|
+
params = get_const_value(ilist.IList, squin_channel.params)
|
|
98
119
|
param_stmts = [py.Constant(p) for p in params]
|
|
99
120
|
for param_stmt in param_stmts:
|
|
100
121
|
param_stmt.insert_before(stmt)
|
|
@@ -118,3 +139,37 @@ class SquinNoiseToStim(RewriteRule):
|
|
|
118
139
|
pzz=param_stmts[14].result,
|
|
119
140
|
)
|
|
120
141
|
return stim_stmt
|
|
142
|
+
|
|
143
|
+
def rewrite_Depolarize2(
|
|
144
|
+
self,
|
|
145
|
+
stmt: qubit.Apply | qubit.Broadcast | wire.Broadcast | wire.Apply,
|
|
146
|
+
qubit_idx_ssas: Tuple[SSAValue],
|
|
147
|
+
) -> Statement:
|
|
148
|
+
"""Rewrite squin.noise.Depolarize2 to stim.Depolarize2."""
|
|
149
|
+
|
|
150
|
+
squin_channel = stmt.operator.owner
|
|
151
|
+
assert isinstance(squin_channel, squin_noise.stmts.Depolarize2)
|
|
152
|
+
|
|
153
|
+
p = get_const_value(float, squin_channel.p)
|
|
154
|
+
p_stmt = py.Constant(p)
|
|
155
|
+
p_stmt.insert_before(stmt)
|
|
156
|
+
|
|
157
|
+
stim_stmt = stim_noise.Depolarize2(targets=qubit_idx_ssas, p=p_stmt.result)
|
|
158
|
+
return stim_stmt
|
|
159
|
+
|
|
160
|
+
def rewrite_Depolarize(
|
|
161
|
+
self,
|
|
162
|
+
stmt: qubit.Apply | qubit.Broadcast | wire.Broadcast | wire.Apply,
|
|
163
|
+
qubit_idx_ssas: Tuple[SSAValue],
|
|
164
|
+
) -> Statement:
|
|
165
|
+
"""Rewrite squin.noise.Depolarize to stim.Depolarize1."""
|
|
166
|
+
|
|
167
|
+
squin_channel = stmt.operator.owner
|
|
168
|
+
assert isinstance(squin_channel, squin_noise.stmts.Depolarize)
|
|
169
|
+
|
|
170
|
+
p = get_const_value(float, squin_channel.p)
|
|
171
|
+
p_stmt = py.Constant(p)
|
|
172
|
+
p_stmt.insert_before(stmt)
|
|
173
|
+
|
|
174
|
+
stim_stmt = stim_noise.Depolarize1(targets=qubit_idx_ssas, p=p_stmt.result)
|
|
175
|
+
return stim_stmt
|
bloqade/stim/rewrite/util.py
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
from
|
|
1
|
+
from typing import TypeVar
|
|
2
|
+
|
|
3
|
+
from kirin import ir, interp
|
|
4
|
+
from kirin.analysis import const
|
|
2
5
|
from kirin.dialects import py
|
|
3
6
|
from kirin.rewrite.abc import RewriteResult
|
|
4
7
|
|
|
@@ -201,3 +204,19 @@ def is_measure_result_used(
|
|
|
201
204
|
Check if the result of a measure statement is used in the program.
|
|
202
205
|
"""
|
|
203
206
|
return bool(stmt.result.uses)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
T = TypeVar("T")
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def get_const_value(typ: type[T], value: ir.SSAValue) -> T:
|
|
213
|
+
if isinstance(hint := value.hints.get("const"), const.Value):
|
|
214
|
+
data = hint.data
|
|
215
|
+
if isinstance(data, typ):
|
|
216
|
+
return hint.data
|
|
217
|
+
raise interp.InterpreterError(
|
|
218
|
+
f"Expected constant value <type = {typ}>, got {data}"
|
|
219
|
+
)
|
|
220
|
+
raise interp.InterpreterError(
|
|
221
|
+
f"Expected constant value <type = {typ}>, got {value}"
|
|
222
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bloqade-circuit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
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
|
|
@@ -37,7 +37,7 @@ bloqade/pyqrack/squin/wire.py,sha256=rqlAeU-r_EHOwJMqHrEAxpZ_rKsvUpwGG7MP4BW75Nw
|
|
|
37
37
|
bloqade/pyqrack/squin/noise/__init__.py,sha256=uXgRQPOrHNRp3k2ff2HD8mheUEaqxZPKEnwV-s4BiV4,31
|
|
38
38
|
bloqade/pyqrack/squin/noise/native.py,sha256=KF4VGzU5Ps92DeLcIDIMsxQQtQ97z_3KUHqBPPkZFaM,2286
|
|
39
39
|
bloqade/qasm2/__init__.py,sha256=W9dR4Qnvigc7e7Ay7puSJHAIuiQk8vWqY-W64SMu5oU,515
|
|
40
|
-
bloqade/qasm2/_qasm_loading.py,sha256=
|
|
40
|
+
bloqade/qasm2/_qasm_loading.py,sha256=dSfjlB6Bm1ednfxc9L42dEa48s5q4N5SGQ9Iw21sBZQ,4753
|
|
41
41
|
bloqade/qasm2/_wrappers.py,sha256=4x3fldC4sV2K_XZ0FPZOorQKAbs_7pualListXtak4A,11148
|
|
42
42
|
bloqade/qasm2/glob.py,sha256=dDZW2KYXi9e0JmEbpVJIJvQytVEr86G7eism9ghlABM,579
|
|
43
43
|
bloqade/qasm2/groups.py,sha256=3-BGCVqJm6ZDgQeDapac65OLedoskJMVHX78YBKV7jY,2531
|
|
@@ -81,7 +81,7 @@ bloqade/qasm2/emit/impls/noise.py,sha256=-N9PmCbz8MwC6xtd55GOpjDoWMyJPJBMVDWT3G8
|
|
|
81
81
|
bloqade/qasm2/parse/__init__.py,sha256=01tlLfrR015nAAPWw3i_Cs9IXsShpXMnJMagcJ_Vuik,986
|
|
82
82
|
bloqade/qasm2/parse/ast.py,sha256=a48ssf0D_xaE-27PsyeBD5lBvwN2Dojj-RWIBhy7jJE,2904
|
|
83
83
|
bloqade/qasm2/parse/build.py,sha256=2CibD1ZRX3_aknmhb5XvFQcI2sBOn97DlQHomb9CMEw,10621
|
|
84
|
-
bloqade/qasm2/parse/lowering.py,sha256=
|
|
84
|
+
bloqade/qasm2/parse/lowering.py,sha256=bVAdctfa9LnWl0pQZZrHyTFwROpTXUfV7ktJPl6AzHg,21101
|
|
85
85
|
bloqade/qasm2/parse/parser.py,sha256=fxqp65dv8NnXE-Ie7ryLESfSH3Xr0unx1EBQysctiHM,121
|
|
86
86
|
bloqade/qasm2/parse/print.py,sha256=PaigQ5RbcfhOteWvDdQHoKsTE3tcNefpVfh1sp5eZEI,8973
|
|
87
87
|
bloqade/qasm2/parse/qasm2.lark,sha256=IYrBydUoVLn1VCNDPP5uNN5BHDET3fQ2yG11cOy900k,2238
|
|
@@ -123,7 +123,7 @@ bloqade/rewrite/rules/split_ifs.py,sha256=Nm4lpEUHZcnCeewIld0tt7UuGO69LiBGl7Uybu
|
|
|
123
123
|
bloqade/squin/__init__.py,sha256=MH7i5gR9DhTjLMI6vsP_NT7_yoaEowYiQwsYhrrUEX0,454
|
|
124
124
|
bloqade/squin/_typeinfer.py,sha256=bilWfC6whTMwewFCqDgB6vDHZsgXPr3azNOYqqnvtB4,780
|
|
125
125
|
bloqade/squin/groups.py,sha256=RXGJnNZUSXF_f5ljjhZ9At8UhaijayoxFoWvxEsUOWc,1310
|
|
126
|
-
bloqade/squin/lowering.py,sha256=
|
|
126
|
+
bloqade/squin/lowering.py,sha256=SR6q-IfV8WHPKT97M7UFu5KoRgAojfDno8Bft1mUSKM,1736
|
|
127
127
|
bloqade/squin/qubit.py,sha256=LgNJsm6qCyP7_O-lZg3YT8IiqzF5W5ff1VwQ79nXN4c,5148
|
|
128
128
|
bloqade/squin/types.py,sha256=T3lkqid4HEWuAK_wRns_p-K5DbLDwlldoyZtVay7A3o,119
|
|
129
129
|
bloqade/squin/wire.py,sha256=GZhF0EHCu7OU70zTV_N83yann-eQnYG_lM2u0QYFoAs,6596
|
|
@@ -141,24 +141,24 @@ bloqade/squin/cirq/emit/noise.py,sha256=rESjGC_66s2Y4FwwYda4rY3mYHYjbqLlKE_vnqpZ
|
|
|
141
141
|
bloqade/squin/cirq/emit/op.py,sha256=z54NP5KqMxffXeFGWamEzvunpTNrxmYuluurk4j2-ps,4000
|
|
142
142
|
bloqade/squin/cirq/emit/qubit.py,sha256=Z2HUsZmJ5F2uHCPGru81ux2usoX77KwtS97_cgeJRMI,1910
|
|
143
143
|
bloqade/squin/cirq/emit/runtime.py,sha256=dH7JSMt2mALPhVFjmZETQzvnTUQ3BFY5poe0YZpM5vQ,6819
|
|
144
|
-
bloqade/squin/noise/__init__.py,sha256=
|
|
144
|
+
bloqade/squin/noise/__init__.py,sha256=xST2qojx6ZApRoiKIXOtifDzSpTZgo-67ja309FFvWw,364
|
|
145
145
|
bloqade/squin/noise/_dialect.py,sha256=2IR98J-lXm5Y3srP9g-FD4JC-qTq2seureM6mKKq1xg,63
|
|
146
|
-
bloqade/squin/noise/_wrapper.py,sha256=
|
|
146
|
+
bloqade/squin/noise/_wrapper.py,sha256=P8fkr1_2U47PtvqnQqeTI7VzThNIK17cNh2QX6ABh_w,815
|
|
147
147
|
bloqade/squin/noise/rewrite.py,sha256=-IqFfDGnhuaFI-9b6PXjhSuiXFM1C5Qu0ibL5GvZldI,3917
|
|
148
|
-
bloqade/squin/noise/stmts.py,sha256=
|
|
148
|
+
bloqade/squin/noise/stmts.py,sha256=F8AsDp2xsLez9vkSamDW985MUCubz3TMRrE0L745GmI,1875
|
|
149
149
|
bloqade/squin/op/__init__.py,sha256=6JOjPdzc6RKO4299ZFz4Jk-wtVyPlGTkakYewHBueXw,841
|
|
150
150
|
bloqade/squin/op/_dialect.py,sha256=66G1IYqmsqUEaCTyUqn2shSHmGYduiTU8GfDXcoMvw4,55
|
|
151
151
|
bloqade/squin/op/_wrapper.py,sha256=bg6MLA6u-qkPpo-sKL3lib1VVtQWKCe6RMZb57w8PJQ,1929
|
|
152
152
|
bloqade/squin/op/number.py,sha256=yujWUqLrOAr8i8OBDsiS5M882wV7t08u345NgNA6TUc,95
|
|
153
153
|
bloqade/squin/op/rewrite.py,sha256=Itxz_hTAPNLyLYeLS0PCVk143J1Z558UR7N9-urbnoU,1327
|
|
154
154
|
bloqade/squin/op/stdlib.py,sha256=4UFK3wKImpums2v5a9OFKuVvz2TLYbYwidg3JYYEi2o,1073
|
|
155
|
-
bloqade/squin/op/stmts.py,sha256=
|
|
155
|
+
bloqade/squin/op/stmts.py,sha256=wPfEzial7_onG9zUaFxQ7iz2wrojQ1PIC9--NX-InFc,6001
|
|
156
156
|
bloqade/squin/op/traits.py,sha256=jjsnzWtPtmQK7K3H_D2fvc8XiW1Y3EMBcgeyPax2sjc,1065
|
|
157
157
|
bloqade/squin/op/types.py,sha256=ozUT0Bv9NuUxPjB2vAeqJ9cpdvUaBfP9trB5mybYxgc,663
|
|
158
158
|
bloqade/squin/rewrite/U3_to_clifford.py,sha256=72ECWFrjeaEelR5e6IgNgaJXnTQ6ZXL4ZakZfXQbi8I,5670
|
|
159
159
|
bloqade/squin/rewrite/__init__.py,sha256=cY1GbXQXKvDeXi0YE4PgjORm6iGBPk63xzMCpVjiCgw,349
|
|
160
160
|
bloqade/squin/rewrite/canonicalize.py,sha256=hcfsn4ntsvnJ_cVnoUgcE5Zk9EqvwgixGArLPx4OjP0,2100
|
|
161
|
-
bloqade/squin/rewrite/desugar.py,sha256=
|
|
161
|
+
bloqade/squin/rewrite/desugar.py,sha256=sZKqnwyoM7_gIEKbXOVE9aQKLrRiSfC8f6Lddada0So,4075
|
|
162
162
|
bloqade/squin/rewrite/remove_dangling_qubits.py,sha256=iTuWV-03YW5wtYbSeKMlnnWjNzDj9SmflyqYPgoYGy8,469
|
|
163
163
|
bloqade/squin/rewrite/wrap_analysis.py,sha256=JUPS4OAYbDHOK0VIrdz1pprSizISUfN7osuoP_P-bIo,2256
|
|
164
164
|
bloqade/stim/__init__.py,sha256=QPZnQRWiiC66pwZ4yRiX2m5doqgPQorQLqc3b7fav2A,935
|
|
@@ -200,14 +200,14 @@ bloqade/stim/parse/__init__.py,sha256=l2DjReB2KkgrDjP_4nP6RnoziiOewoSeZfTno1sVYT
|
|
|
200
200
|
bloqade/stim/parse/lowering.py,sha256=L-IcR_exlxsTVv4SQ0bhzIF4_L82P-GEdK6qRd6B86Y,23723
|
|
201
201
|
bloqade/stim/passes/__init__.py,sha256=SO4OJLaRxq9Lt2AaUxNqiAz-eJnfWsJ6TijUAX64DM4,62
|
|
202
202
|
bloqade/stim/passes/simplify_ifs.py,sha256=45lWKmc6ybt0KjEuE297IouPVJ7NwX_j9q4GNUsIkEc,690
|
|
203
|
-
bloqade/stim/passes/squin_to_stim.py,sha256=
|
|
203
|
+
bloqade/stim/passes/squin_to_stim.py,sha256=pZvSd1rmOnLRfZONctQAb6ORjcoMd1Qjpbhyf-7m-MQ,5125
|
|
204
204
|
bloqade/stim/rewrite/__init__.py,sha256=SHWryh7rZHXOlIz8BMNpj-w7-8VQCRMLt6PfzYFbBfw,434
|
|
205
205
|
bloqade/stim/rewrite/ifs_to_stim.py,sha256=LXkmmTIgi8-Exrz1EGjG8QpdRn6EV3HZM-bZeAaf-cQ,6718
|
|
206
206
|
bloqade/stim/rewrite/py_constant_to_stim.py,sha256=PV8bHvn759-d_0JW4akaGSORW_oxigrlUBhAC51PJAU,1354
|
|
207
207
|
bloqade/stim/rewrite/qubit_to_stim.py,sha256=oiKmi8BlBwXJq-8kGhN1nXgyxJ2UIt_9uouNkU1J8vs,2624
|
|
208
208
|
bloqade/stim/rewrite/squin_measure.py,sha256=zPH2q_ciV2D615GK9l9LWGYmjv3dOju18jKMYERIL7c,4817
|
|
209
|
-
bloqade/stim/rewrite/squin_noise.py,sha256=
|
|
210
|
-
bloqade/stim/rewrite/util.py,sha256=
|
|
209
|
+
bloqade/stim/rewrite/squin_noise.py,sha256=NafmAiByT4Y5895fZM4Od8arKjsJuW6F5wvRpAFFo70,6240
|
|
210
|
+
bloqade/stim/rewrite/util.py,sha256=xnLDiEj45CBoG3mpG-ywE1Jjh1k_OVP4iI1A75VR6sw,7257
|
|
211
211
|
bloqade/stim/rewrite/wire_identity_elimination.py,sha256=Cscu8yaSslPuW04HvbXx4HJ3JzdUZNUMyFqcvuc4sxY,795
|
|
212
212
|
bloqade/stim/rewrite/wire_to_stim.py,sha256=rZY4Ya4I2b4C3tk84LvJvEi--jyUgza8WmtDtTxCajI,1814
|
|
213
213
|
bloqade/stim/upstream/__init__.py,sha256=Skev79lMyfz2bFoih-Fn_9iXbMArqlKxHSd1agHAtlA,55
|
|
@@ -223,7 +223,7 @@ bloqade/visual/animation/runtime/atoms.py,sha256=EmjxhujLiHHPS_HtH_B-7TiqeHgvW5u
|
|
|
223
223
|
bloqade/visual/animation/runtime/ppoly.py,sha256=JB9IP53N1w6adBJEue6J5Nmj818Id9JvrlgrmiQTU1I,1385
|
|
224
224
|
bloqade/visual/animation/runtime/qpustate.py,sha256=rlmxQeJSvaohXrTpXQL5y-NJcpvfW33xPaYM1slv7cc,4270
|
|
225
225
|
bloqade/visual/animation/runtime/utils.py,sha256=ju9IzOWX-vKwfpqUjlUKu3Ssr_UFPFFq-tzH_Nqyo_c,1212
|
|
226
|
-
bloqade_circuit-0.
|
|
227
|
-
bloqade_circuit-0.
|
|
228
|
-
bloqade_circuit-0.
|
|
229
|
-
bloqade_circuit-0.
|
|
226
|
+
bloqade_circuit-0.6.1.dist-info/METADATA,sha256=UulZPuoA-eaFH24p9sAdzlPQ2exC05Yvl7mdxTtuDJ0,3849
|
|
227
|
+
bloqade_circuit-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
228
|
+
bloqade_circuit-0.6.1.dist-info/licenses/LICENSE,sha256=S5GIJwR6QCixPA9wryYb44ZEek0Nz4rt_zLUqP05UbU,13160
|
|
229
|
+
bloqade_circuit-0.6.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|