bloqade-circuit 0.6.4__py3-none-any.whl → 0.9.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.
Files changed (191) hide show
  1. bloqade/analysis/address/__init__.py +8 -4
  2. bloqade/analysis/address/analysis.py +123 -33
  3. bloqade/analysis/address/impls.py +293 -90
  4. bloqade/analysis/address/lattice.py +209 -24
  5. bloqade/analysis/fidelity/analysis.py +11 -23
  6. bloqade/analysis/measure_id/analysis.py +18 -20
  7. bloqade/analysis/measure_id/impls.py +31 -29
  8. bloqade/annotate/__init__.py +6 -0
  9. bloqade/annotate/_dialect.py +3 -0
  10. bloqade/annotate/_interface.py +22 -0
  11. bloqade/annotate/stmts.py +29 -0
  12. bloqade/annotate/types.py +13 -0
  13. bloqade/cirq_utils/__init__.py +4 -2
  14. bloqade/cirq_utils/emit/__init__.py +3 -0
  15. bloqade/cirq_utils/emit/base.py +246 -0
  16. bloqade/cirq_utils/emit/gate.py +104 -0
  17. bloqade/cirq_utils/emit/noise.py +90 -0
  18. bloqade/cirq_utils/emit/qubit.py +35 -0
  19. bloqade/cirq_utils/lowering.py +660 -0
  20. bloqade/cirq_utils/noise/__init__.py +0 -2
  21. bloqade/cirq_utils/noise/_two_zone_utils.py +7 -15
  22. bloqade/cirq_utils/noise/model.py +151 -191
  23. bloqade/cirq_utils/noise/transform.py +2 -2
  24. bloqade/cirq_utils/parallelize.py +9 -6
  25. bloqade/gemini/__init__.py +1 -0
  26. bloqade/gemini/analysis/__init__.py +3 -0
  27. bloqade/gemini/analysis/logical_validation/__init__.py +1 -0
  28. bloqade/gemini/analysis/logical_validation/analysis.py +17 -0
  29. bloqade/gemini/analysis/logical_validation/impls.py +101 -0
  30. bloqade/gemini/groups.py +67 -0
  31. bloqade/native/__init__.py +23 -0
  32. bloqade/native/_prelude.py +45 -0
  33. bloqade/native/dialects/__init__.py +0 -0
  34. bloqade/native/dialects/gate/__init__.py +2 -0
  35. bloqade/native/dialects/gate/_dialect.py +3 -0
  36. bloqade/native/dialects/gate/_interface.py +32 -0
  37. bloqade/native/dialects/gate/stmts.py +31 -0
  38. bloqade/native/stdlib/__init__.py +0 -0
  39. bloqade/native/stdlib/broadcast.py +246 -0
  40. bloqade/native/stdlib/simple.py +220 -0
  41. bloqade/native/upstream/__init__.py +4 -0
  42. bloqade/native/upstream/squin2native.py +79 -0
  43. bloqade/pyqrack/__init__.py +2 -2
  44. bloqade/pyqrack/base.py +7 -1
  45. bloqade/pyqrack/device.py +192 -18
  46. bloqade/pyqrack/native.py +49 -0
  47. bloqade/pyqrack/reg.py +6 -6
  48. bloqade/pyqrack/squin/gate/__init__.py +1 -0
  49. bloqade/pyqrack/squin/gate/gate.py +136 -0
  50. bloqade/pyqrack/squin/noise/native.py +120 -54
  51. bloqade/pyqrack/squin/qubit.py +39 -36
  52. bloqade/pyqrack/target.py +5 -4
  53. bloqade/pyqrack/task.py +114 -7
  54. bloqade/qasm2/_qasm_loading.py +3 -3
  55. bloqade/qasm2/dialects/core/address.py +21 -12
  56. bloqade/qasm2/dialects/expr/_emit.py +19 -8
  57. bloqade/qasm2/dialects/expr/stmts.py +7 -7
  58. bloqade/qasm2/dialects/noise/fidelity.py +4 -8
  59. bloqade/qasm2/dialects/noise/model.py +2 -1
  60. bloqade/qasm2/emit/base.py +16 -11
  61. bloqade/qasm2/emit/gate.py +11 -8
  62. bloqade/qasm2/emit/main.py +103 -3
  63. bloqade/qasm2/emit/target.py +9 -5
  64. bloqade/qasm2/groups.py +3 -2
  65. bloqade/qasm2/parse/lowering.py +0 -1
  66. bloqade/qasm2/passes/fold.py +14 -73
  67. bloqade/qasm2/passes/glob.py +2 -2
  68. bloqade/qasm2/passes/noise.py +1 -1
  69. bloqade/qasm2/passes/parallel.py +7 -5
  70. bloqade/qasm2/rewrite/__init__.py +0 -1
  71. bloqade/qasm2/rewrite/noise/heuristic_noise.py +7 -17
  72. bloqade/qasm2/rewrite/parallel_to_glob.py +28 -15
  73. bloqade/qasm2/rewrite/parallel_to_uop.py +2 -8
  74. bloqade/qasm2/rewrite/register.py +2 -2
  75. bloqade/qasm2/rewrite/uop_to_parallel.py +4 -2
  76. bloqade/qbraid/lowering.py +1 -0
  77. bloqade/qbraid/schema.py +2 -2
  78. bloqade/qubit/__init__.py +12 -0
  79. bloqade/qubit/_dialect.py +3 -0
  80. bloqade/qubit/_interface.py +49 -0
  81. bloqade/qubit/_prelude.py +45 -0
  82. bloqade/qubit/analysis/__init__.py +1 -0
  83. bloqade/qubit/analysis/address_impl.py +40 -0
  84. bloqade/qubit/stdlib/__init__.py +2 -0
  85. bloqade/qubit/stdlib/_new.py +34 -0
  86. bloqade/qubit/stdlib/broadcast.py +62 -0
  87. bloqade/qubit/stdlib/simple.py +59 -0
  88. bloqade/qubit/stmts.py +60 -0
  89. bloqade/rewrite/passes/__init__.py +6 -0
  90. bloqade/rewrite/passes/aggressive_unroll.py +103 -0
  91. bloqade/rewrite/passes/callgraph.py +116 -0
  92. bloqade/rewrite/passes/canonicalize_ilist.py +20 -14
  93. bloqade/rewrite/rules/split_ifs.py +18 -1
  94. bloqade/squin/__init__.py +47 -14
  95. bloqade/squin/analysis/__init__.py +0 -1
  96. bloqade/squin/analysis/schedule.py +10 -11
  97. bloqade/squin/gate/__init__.py +2 -0
  98. bloqade/squin/gate/_dialect.py +3 -0
  99. bloqade/squin/gate/_interface.py +98 -0
  100. bloqade/squin/gate/stmts.py +125 -0
  101. bloqade/squin/groups.py +5 -22
  102. bloqade/squin/noise/__init__.py +1 -10
  103. bloqade/squin/noise/_dialect.py +1 -1
  104. bloqade/squin/noise/_interface.py +45 -0
  105. bloqade/squin/noise/stmts.py +66 -28
  106. bloqade/squin/rewrite/U3_to_clifford.py +70 -51
  107. bloqade/squin/rewrite/__init__.py +0 -2
  108. bloqade/squin/rewrite/remove_dangling_qubits.py +2 -2
  109. bloqade/squin/rewrite/wrap_analysis.py +4 -35
  110. bloqade/squin/stdlib/__init__.py +0 -0
  111. bloqade/squin/stdlib/broadcast/__init__.py +34 -0
  112. bloqade/squin/stdlib/broadcast/_qubit.py +4 -0
  113. bloqade/squin/stdlib/broadcast/gate.py +260 -0
  114. bloqade/squin/stdlib/broadcast/noise.py +144 -0
  115. bloqade/squin/stdlib/simple/__init__.py +33 -0
  116. bloqade/squin/stdlib/simple/gate.py +242 -0
  117. bloqade/squin/stdlib/simple/noise.py +126 -0
  118. bloqade/stim/__init__.py +1 -0
  119. bloqade/stim/_wrappers.py +6 -0
  120. bloqade/stim/dialects/auxiliary/emit.py +19 -18
  121. bloqade/stim/dialects/collapse/emit_str.py +7 -8
  122. bloqade/stim/dialects/gate/emit.py +9 -10
  123. bloqade/stim/dialects/noise/emit.py +17 -13
  124. bloqade/stim/dialects/noise/stmts.py +5 -3
  125. bloqade/stim/emit/__init__.py +1 -0
  126. bloqade/stim/emit/impls.py +16 -0
  127. bloqade/stim/emit/stim_str.py +48 -31
  128. bloqade/stim/groups.py +12 -2
  129. bloqade/stim/parse/lowering.py +14 -17
  130. bloqade/stim/passes/__init__.py +0 -2
  131. bloqade/stim/passes/flatten.py +26 -0
  132. bloqade/stim/passes/simplify_ifs.py +6 -1
  133. bloqade/stim/passes/squin_to_stim.py +9 -84
  134. bloqade/stim/rewrite/__init__.py +2 -4
  135. bloqade/stim/rewrite/get_record_util.py +24 -0
  136. bloqade/stim/rewrite/ifs_to_stim.py +24 -25
  137. bloqade/stim/rewrite/qubit_to_stim.py +90 -41
  138. bloqade/stim/rewrite/set_detector_to_stim.py +68 -0
  139. bloqade/stim/rewrite/set_observable_to_stim.py +52 -0
  140. bloqade/stim/rewrite/squin_measure.py +9 -18
  141. bloqade/stim/rewrite/squin_noise.py +134 -108
  142. bloqade/stim/rewrite/util.py +5 -192
  143. bloqade/test_utils.py +1 -1
  144. bloqade/types.py +10 -0
  145. bloqade/validation/__init__.py +2 -0
  146. bloqade/validation/analysis/__init__.py +5 -0
  147. bloqade/validation/analysis/analysis.py +41 -0
  148. bloqade/validation/analysis/lattice.py +58 -0
  149. bloqade/validation/kernel_validation.py +77 -0
  150. {bloqade_circuit-0.6.4.dist-info → bloqade_circuit-0.9.1.dist-info}/METADATA +5 -6
  151. bloqade_circuit-0.9.1.dist-info/RECORD +265 -0
  152. bloqade/pyqrack/squin/op.py +0 -180
  153. bloqade/pyqrack/squin/runtime.py +0 -535
  154. bloqade/pyqrack/squin/wire.py +0 -51
  155. bloqade/rewrite/rules/flatten_ilist.py +0 -51
  156. bloqade/rewrite/rules/inline_getitem_ilist.py +0 -31
  157. bloqade/squin/_typeinfer.py +0 -20
  158. bloqade/squin/analysis/address_impl.py +0 -71
  159. bloqade/squin/analysis/nsites/__init__.py +0 -9
  160. bloqade/squin/analysis/nsites/analysis.py +0 -50
  161. bloqade/squin/analysis/nsites/impls.py +0 -92
  162. bloqade/squin/analysis/nsites/lattice.py +0 -49
  163. bloqade/squin/cirq/__init__.py +0 -280
  164. bloqade/squin/cirq/emit/emit_circuit.py +0 -109
  165. bloqade/squin/cirq/emit/noise.py +0 -49
  166. bloqade/squin/cirq/emit/op.py +0 -125
  167. bloqade/squin/cirq/emit/qubit.py +0 -60
  168. bloqade/squin/cirq/emit/runtime.py +0 -242
  169. bloqade/squin/cirq/lowering.py +0 -440
  170. bloqade/squin/lowering.py +0 -54
  171. bloqade/squin/noise/_wrapper.py +0 -40
  172. bloqade/squin/noise/rewrite.py +0 -111
  173. bloqade/squin/op/__init__.py +0 -41
  174. bloqade/squin/op/_dialect.py +0 -3
  175. bloqade/squin/op/_wrapper.py +0 -121
  176. bloqade/squin/op/number.py +0 -5
  177. bloqade/squin/op/rewrite.py +0 -46
  178. bloqade/squin/op/stdlib.py +0 -62
  179. bloqade/squin/op/stmts.py +0 -276
  180. bloqade/squin/op/traits.py +0 -43
  181. bloqade/squin/op/types.py +0 -26
  182. bloqade/squin/qubit.py +0 -184
  183. bloqade/squin/rewrite/canonicalize.py +0 -60
  184. bloqade/squin/rewrite/desugar.py +0 -124
  185. bloqade/squin/types.py +0 -8
  186. bloqade/squin/wire.py +0 -201
  187. bloqade/stim/rewrite/wire_identity_elimination.py +0 -24
  188. bloqade/stim/rewrite/wire_to_stim.py +0 -57
  189. bloqade_circuit-0.6.4.dist-info/RECORD +0 -234
  190. {bloqade_circuit-0.6.4.dist-info → bloqade_circuit-0.9.1.dist-info}/WHEEL +0 -0
  191. {bloqade_circuit-0.6.4.dist-info → bloqade_circuit-0.9.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,121 +0,0 @@
1
- from kirin.lowering import wraps
2
-
3
- from . import stmts, types
4
-
5
-
6
- @wraps(stmts.Kron)
7
- def kron(lhs: types.Op, rhs: types.Op) -> types.Op: ...
8
-
9
-
10
- @wraps(stmts.Mult)
11
- def mult(lhs: types.Op, rhs: types.Op) -> types.Op: ...
12
-
13
-
14
- @wraps(stmts.Scale)
15
- def scale(op: types.Op, factor: complex) -> types.Op: ...
16
-
17
-
18
- @wraps(stmts.Adjoint)
19
- def adjoint(op: types.Op) -> types.Op: ...
20
-
21
-
22
- @wraps(stmts.Control)
23
- def control(op: types.Op, *, n_controls: int) -> types.Op:
24
- """
25
- Create a controlled operator.
26
-
27
- Note, that when considering atom loss, the operator will not be applied if
28
- any of the controls has been lost.
29
-
30
- Args:
31
- operator: The operator to apply under the control.
32
- n_controls: The number qubits to be used as control.
33
-
34
- Returns:
35
- Operator
36
- """
37
- ...
38
-
39
-
40
- @wraps(stmts.Reset)
41
- def reset() -> types.Op: ...
42
-
43
-
44
- @wraps(stmts.ResetToOne)
45
- def reset_to_one() -> types.Op: ...
46
-
47
-
48
- @wraps(stmts.Identity)
49
- def identity(*, sites: int) -> types.Op: ...
50
-
51
-
52
- @wraps(stmts.Rot)
53
- def rot(axis: types.Op, angle: float) -> types.Op: ...
54
-
55
-
56
- @wraps(stmts.ShiftOp)
57
- def shift(theta: float) -> types.Op: ...
58
-
59
-
60
- @wraps(stmts.PhaseOp)
61
- def phase(theta: float) -> types.Op: ...
62
-
63
-
64
- @wraps(stmts.X)
65
- def x() -> types.Op: ...
66
-
67
-
68
- @wraps(stmts.Y)
69
- def y() -> types.Op: ...
70
-
71
-
72
- @wraps(stmts.Z)
73
- def z() -> types.Op: ...
74
-
75
-
76
- @wraps(stmts.SqrtX)
77
- def sqrt_x() -> types.Op: ...
78
-
79
-
80
- @wraps(stmts.SqrtY)
81
- def sqrt_y() -> types.Op: ...
82
-
83
-
84
- @wraps(stmts.S)
85
- def sqrt_z() -> types.Op: ...
86
-
87
-
88
- @wraps(stmts.H)
89
- def h() -> types.Op: ...
90
-
91
-
92
- @wraps(stmts.S)
93
- def s() -> types.Op: ...
94
-
95
-
96
- @wraps(stmts.T)
97
- def t() -> types.Op: ...
98
-
99
-
100
- @wraps(stmts.P0)
101
- def p0() -> types.Op: ...
102
-
103
-
104
- @wraps(stmts.P1)
105
- def p1() -> types.Op: ...
106
-
107
-
108
- @wraps(stmts.Sn)
109
- def spin_n() -> types.Op: ...
110
-
111
-
112
- @wraps(stmts.Sp)
113
- def spin_p() -> types.Op: ...
114
-
115
-
116
- @wraps(stmts.U3)
117
- def u(theta: float, phi: float, lam: float) -> types.Op: ...
118
-
119
-
120
- @wraps(stmts.PauliString)
121
- def pauli_string(*, string: str) -> types.Op: ...
@@ -1,5 +0,0 @@
1
- import numbers
2
-
3
- from kirin.ir.attrs.types import PyClass
4
-
5
- NumberType = PyClass(numbers.Number)
@@ -1,46 +0,0 @@
1
- """Rewrite py.binop.mult to Mult stmt"""
2
-
3
- from kirin import ir
4
- from kirin.passes import Pass
5
- from kirin.rewrite import Walk
6
- from kirin.dialects import py
7
- from kirin.rewrite.abc import RewriteRule, RewriteResult
8
-
9
- from .stmts import Mult, Scale
10
- from .types import OpType
11
-
12
-
13
- class _PyMultToSquinMult(RewriteRule):
14
-
15
- def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
16
- if not isinstance(node, py.Mult):
17
- return RewriteResult()
18
-
19
- lhs_is_op = node.lhs.type.is_subseteq(OpType)
20
- rhs_is_op = node.rhs.type.is_subseteq(OpType)
21
-
22
- if not lhs_is_op and not rhs_is_op:
23
- return RewriteResult()
24
-
25
- if lhs_is_op and rhs_is_op:
26
- mult = Mult(node.lhs, node.rhs)
27
- node.replace_by(mult)
28
- return RewriteResult(has_done_something=True)
29
-
30
- if lhs_is_op:
31
- scale = Scale(node.lhs, node.rhs)
32
- node.replace_by(scale)
33
- return RewriteResult(has_done_something=True)
34
-
35
- if rhs_is_op:
36
- scale = Scale(node.rhs, node.lhs)
37
- node.replace_by(scale)
38
- return RewriteResult(has_done_something=True)
39
-
40
- return RewriteResult()
41
-
42
-
43
- class PyMultToSquinMult(Pass):
44
-
45
- def unsafe_run(self, mt: ir.Method) -> RewriteResult:
46
- return Walk(_PyMultToSquinMult()).rewrite(mt.code)
@@ -1,62 +0,0 @@
1
- from kirin import ir
2
- from kirin.prelude import structural_no_opt
3
-
4
- from . import types
5
- from ._dialect import dialect
6
- from ._wrapper import h, x, y, z, rot, phase, control
7
-
8
-
9
- @ir.dialect_group(structural_no_opt.add(dialect))
10
- def op(self):
11
- def run_pass(method):
12
- pass
13
-
14
- return run_pass
15
-
16
-
17
- @op
18
- def rx(theta: float) -> types.Op:
19
- """Rotation X gate."""
20
- return rot(x(), theta)
21
-
22
-
23
- @op
24
- def ry(theta: float) -> types.Op:
25
- """Rotation Y gate."""
26
- return rot(y(), theta)
27
-
28
-
29
- @op
30
- def rz(theta: float) -> types.Op:
31
- """Rotation Z gate."""
32
- return rot(z(), theta)
33
-
34
-
35
- @op
36
- def cx() -> types.Op:
37
- """Controlled X gate."""
38
- return control(x(), n_controls=1)
39
-
40
-
41
- @op
42
- def cy() -> types.Op:
43
- """Controlled Y gate."""
44
- return control(y(), n_controls=1)
45
-
46
-
47
- @op
48
- def cz() -> types.Op:
49
- """Control Z gate."""
50
- return control(z(), n_controls=1)
51
-
52
-
53
- @op
54
- def ch() -> types.Op:
55
- """Control H gate."""
56
- return control(h(), n_controls=1)
57
-
58
-
59
- @op
60
- def cphase(theta: float) -> types.Op:
61
- """Control Phase gate."""
62
- return control(phase(theta), n_controls=1)
bloqade/squin/op/stmts.py DELETED
@@ -1,276 +0,0 @@
1
- from kirin import ir, types, lowering
2
- from kirin.decl import info, statement
3
-
4
- from .types import OpType
5
- from .number import NumberType
6
- from .traits import Unitary, HasSites, FixedSites, MaybeUnitary
7
- from ._dialect import dialect
8
-
9
-
10
- @statement
11
- class Operator(ir.Statement):
12
- result: ir.ResultValue = info.result(OpType)
13
-
14
-
15
- @statement
16
- class PrimitiveOp(Operator):
17
- pass
18
-
19
-
20
- @statement
21
- class CompositeOp(Operator):
22
- pass
23
-
24
-
25
- @statement
26
- class BinaryOp(CompositeOp):
27
- lhs: ir.SSAValue = info.argument(OpType)
28
- rhs: ir.SSAValue = info.argument(OpType)
29
-
30
-
31
- @statement(dialect=dialect)
32
- class Kron(BinaryOp):
33
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), MaybeUnitary()})
34
- is_unitary: bool = info.attribute(default=False)
35
-
36
-
37
- @statement(dialect=dialect)
38
- class Mult(BinaryOp):
39
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), MaybeUnitary()})
40
- is_unitary: bool = info.attribute(default=False)
41
-
42
-
43
- @statement(dialect=dialect)
44
- class Adjoint(CompositeOp):
45
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), MaybeUnitary()})
46
- is_unitary: bool = info.attribute(default=False)
47
- op: ir.SSAValue = info.argument(OpType)
48
-
49
-
50
- @statement(dialect=dialect)
51
- class Scale(CompositeOp):
52
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), MaybeUnitary()})
53
- is_unitary: bool = info.attribute(default=False)
54
- op: ir.SSAValue = info.argument(OpType)
55
- factor: ir.SSAValue = info.argument(NumberType)
56
-
57
-
58
- @statement(dialect=dialect)
59
- class Control(CompositeOp):
60
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), MaybeUnitary()})
61
- is_unitary: bool = info.attribute(default=False)
62
- op: ir.SSAValue = info.argument(OpType)
63
- n_controls: int = info.attribute()
64
-
65
-
66
- @statement(dialect=dialect)
67
- class Rot(CompositeOp):
68
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), Unitary()})
69
- axis: ir.SSAValue = info.argument(OpType)
70
- angle: ir.SSAValue = info.argument(types.Float)
71
-
72
-
73
- @statement(dialect=dialect)
74
- class Identity(CompositeOp):
75
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), Unitary(), HasSites()})
76
- sites: int = info.attribute()
77
-
78
-
79
- @statement
80
- class ConstantOp(PrimitiveOp):
81
- traits = frozenset(
82
- {ir.Pure(), lowering.FromPythonCall(), ir.ConstantLike(), FixedSites(1)}
83
- )
84
-
85
-
86
- @statement
87
- class ConstantUnitary(ConstantOp):
88
- traits = frozenset(
89
- {
90
- ir.Pure(),
91
- lowering.FromPythonCall(),
92
- ir.ConstantLike(),
93
- Unitary(),
94
- FixedSites(1),
95
- }
96
- )
97
-
98
-
99
- @statement(dialect=dialect)
100
- class U3(PrimitiveOp):
101
- """
102
- The rotation operator U3(theta, phi, lam).
103
- Note that we use the convention from the QASM2 specification, namely
104
-
105
- $$
106
- U_3(\\theta, \\phi, \\lambda) = R_z(\\phi) R_y(\\theta) R_z(\\lambda)
107
- $$
108
- """
109
-
110
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), Unitary(), FixedSites(1)})
111
- theta: ir.SSAValue = info.argument(types.Float)
112
- phi: ir.SSAValue = info.argument(types.Float)
113
- lam: ir.SSAValue = info.argument(types.Float)
114
-
115
-
116
- @statement(dialect=dialect)
117
- class PhaseOp(PrimitiveOp):
118
- """
119
- A phase operator.
120
-
121
- $$
122
- \\text{PhaseOp}(\\theta) = e^{i \\theta} I
123
- $$
124
- """
125
-
126
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), Unitary(), FixedSites(1)})
127
- theta: ir.SSAValue = info.argument(types.Float)
128
-
129
-
130
- @statement(dialect=dialect)
131
- class ShiftOp(PrimitiveOp):
132
- """
133
- A phase shift operator.
134
-
135
- $$
136
- \\text{Shift}(\\theta) = \\begin{bmatrix} 1 & 0 \\\\ 0 & e^{i \\theta} \\end{bmatrix}
137
- $$
138
- """
139
-
140
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), Unitary(), FixedSites(1)})
141
- theta: ir.SSAValue = info.argument(types.Float)
142
-
143
-
144
- @statement(dialect=dialect)
145
- class Reset(PrimitiveOp):
146
- """
147
- Reset operator for qubits and wires.
148
- """
149
-
150
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), FixedSites(1)})
151
-
152
-
153
- @statement(dialect=dialect)
154
- class ResetToOne(PrimitiveOp):
155
- """
156
- Reset qubits to the one state. Mainly needed to accommodate cirq's GeneralizedAmplitudeDampingChannel
157
- """
158
-
159
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), FixedSites(1)})
160
-
161
-
162
- @statement
163
- class CliffordOp(ConstantUnitary):
164
- pass
165
-
166
-
167
- @statement
168
- class PauliOp(CliffordOp):
169
- pass
170
-
171
-
172
- @statement(dialect=dialect)
173
- class PauliString(ConstantUnitary):
174
- traits = frozenset({ir.Pure(), lowering.FromPythonCall(), Unitary(), HasSites()})
175
- string: str = info.attribute()
176
-
177
- def verify(self) -> None:
178
- if not set("XYZ").issuperset(self.string):
179
- raise ValueError(
180
- f"Invalid Pauli string: {self.string}. Must be a combination of 'X', 'Y', and 'Z'."
181
- )
182
-
183
-
184
- @statement(dialect=dialect)
185
- class X(PauliOp):
186
- pass
187
-
188
-
189
- @statement(dialect=dialect)
190
- class Y(PauliOp):
191
- pass
192
-
193
-
194
- @statement(dialect=dialect)
195
- class Z(PauliOp):
196
- pass
197
-
198
-
199
- @statement(dialect=dialect)
200
- class SqrtX(ConstantUnitary):
201
- pass
202
-
203
-
204
- @statement(dialect=dialect)
205
- class SqrtY(ConstantUnitary):
206
- pass
207
-
208
-
209
- # NOTE no SqrtZ since its equal to S
210
-
211
-
212
- @statement(dialect=dialect)
213
- class H(ConstantUnitary):
214
- pass
215
-
216
-
217
- @statement(dialect=dialect)
218
- class S(ConstantUnitary):
219
- pass
220
-
221
-
222
- @statement(dialect=dialect)
223
- class T(ConstantUnitary):
224
- pass
225
-
226
-
227
- @statement(dialect=dialect)
228
- class P0(ConstantOp):
229
- """
230
- The $P_0$ projection operator.
231
-
232
- $$
233
- P0 = \\begin{bmatrix} 1 & 0 \\\\ 0 & 0 \\end{bmatrix}
234
- $$
235
- """
236
-
237
- pass
238
-
239
-
240
- @statement(dialect=dialect)
241
- class P1(ConstantOp):
242
- """
243
- The $P_1$ projection operator.
244
-
245
- $$
246
- P1 = \\begin{bmatrix} 0 & 0 \\\\ 0 & 1 \\end{bmatrix}
247
- $$
248
- """
249
-
250
- pass
251
-
252
-
253
- @statement(dialect=dialect)
254
- class Sn(ConstantOp):
255
- """
256
- $S_{-}$ operator.
257
-
258
- $$
259
- Sn = \\frac{1}{2} (S_x - i S_y) = \\frac{1}{2} \\begin{bmatrix} 0 & 0 \\\\ 1 & 0 \\end{bmatrix}
260
- $$
261
- """
262
-
263
- pass
264
-
265
-
266
- @statement(dialect=dialect)
267
- class Sp(ConstantOp):
268
- """
269
- $S_{+}$ operator.
270
-
271
- $$
272
- Sp = \\frac{1}{2} (S_x + i S_y) = \\frac{1}{2}\\begin{bmatrix} 0 & 1 \\\\ 0 & 0 \\end{bmatrix}
273
- $$
274
- """
275
-
276
- pass
@@ -1,43 +0,0 @@
1
- from typing import cast
2
- from dataclasses import dataclass
3
-
4
- from kirin import ir
5
-
6
-
7
- @dataclass(frozen=True)
8
- class FixedSites(ir.StmtTrait):
9
- data: int
10
-
11
-
12
- @dataclass(frozen=True)
13
- class HasSites(ir.StmtTrait):
14
- """An operator with a `sites` attribute."""
15
-
16
- def get_sites(self, stmt: ir.Statement):
17
- attr = stmt.get_attr_or_prop("sites")
18
- if attr is None:
19
- raise ValueError(f"Missing sites attribute in {stmt}")
20
- return cast(ir.PyAttr[int], attr).data
21
-
22
- def set_sites(self, stmt: ir.Statement, value: int):
23
- stmt.attributes["sites"] = ir.PyAttr(value)
24
- return
25
-
26
-
27
- @dataclass(frozen=True)
28
- class Unitary(ir.StmtTrait):
29
- pass
30
-
31
-
32
- @dataclass(frozen=True)
33
- class MaybeUnitary(ir.StmtTrait):
34
-
35
- def is_unitary(self, stmt: ir.Statement):
36
- attr = stmt.get_attr_or_prop("is_unitary")
37
- if attr is None:
38
- return False
39
- return cast(ir.PyAttr[bool], attr).data
40
-
41
- def set_unitary(self, stmt: ir.Statement, value: bool):
42
- stmt.attributes["is_unitary"] = ir.PyAttr(value)
43
- return
bloqade/squin/op/types.py DELETED
@@ -1,26 +0,0 @@
1
- from typing import overload
2
-
3
- from kirin import types
4
-
5
-
6
- class Op:
7
-
8
- def __matmul__(self, other: "Op") -> "Op":
9
- raise NotImplementedError("@ can only be used within a squin kernel program")
10
-
11
- @overload
12
- def __mul__(self, other: "Op") -> "Op": ...
13
-
14
- @overload
15
- def __mul__(self, other: complex) -> "Op": ...
16
-
17
- def __mul__(self, other) -> "Op":
18
- raise NotImplementedError("@ can only be used within a squin kernel program")
19
-
20
- def __rmul__(self, other: complex) -> "Op":
21
- raise NotImplementedError("@ can only be used within a squin kernel program")
22
-
23
-
24
- OpType = types.PyClass(Op)
25
-
26
- NumOperators = types.TypeVar("NumOperators")