bloqade-circuit 0.7.13__py3-none-any.whl → 0.8.0__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.

Files changed (136) hide show
  1. bloqade/analysis/address/__init__.py +8 -4
  2. bloqade/analysis/address/analysis.py +119 -29
  3. bloqade/analysis/address/impls.py +290 -87
  4. bloqade/analysis/address/lattice.py +209 -24
  5. bloqade/analysis/fidelity/analysis.py +2 -2
  6. bloqade/analysis/measure_id/impls.py +3 -27
  7. bloqade/cirq_utils/__init__.py +3 -1
  8. bloqade/cirq_utils/emit/__init__.py +3 -0
  9. bloqade/cirq_utils/emit/base.py +243 -0
  10. bloqade/cirq_utils/emit/gate.py +104 -0
  11. bloqade/cirq_utils/emit/noise.py +90 -0
  12. bloqade/cirq_utils/emit/qubit.py +35 -0
  13. bloqade/cirq_utils/lowering.py +664 -0
  14. bloqade/native/__init__.py +0 -1
  15. bloqade/native/_prelude.py +3 -3
  16. bloqade/native/dialects/gate/__init__.py +2 -0
  17. bloqade/native/dialects/gate/_dialect.py +3 -0
  18. bloqade/native/dialects/{gates → gate}/_interface.py +5 -5
  19. bloqade/native/dialects/{gates → gate}/stmts.py +5 -5
  20. bloqade/native/stdlib/broadcast.py +19 -19
  21. bloqade/native/stdlib/simple.py +14 -13
  22. bloqade/native/upstream/__init__.py +5 -0
  23. bloqade/native/upstream/squin2native.py +136 -0
  24. bloqade/pyqrack/__init__.py +1 -2
  25. bloqade/pyqrack/device.py +6 -17
  26. bloqade/pyqrack/native.py +17 -17
  27. bloqade/pyqrack/reg.py +1 -6
  28. bloqade/pyqrack/squin/gate/__init__.py +1 -0
  29. bloqade/pyqrack/squin/gate/gate.py +136 -0
  30. bloqade/pyqrack/squin/noise/native.py +120 -54
  31. bloqade/pyqrack/squin/qubit.py +25 -41
  32. bloqade/pyqrack/target.py +2 -2
  33. bloqade/qasm2/dialects/core/address.py +21 -12
  34. bloqade/qasm2/dialects/noise/fidelity.py +2 -6
  35. bloqade/qasm2/dialects/noise/model.py +2 -1
  36. bloqade/qasm2/passes/parallel.py +3 -1
  37. bloqade/qasm2/rewrite/__init__.py +0 -1
  38. bloqade/qasm2/rewrite/noise/heuristic_noise.py +7 -17
  39. bloqade/qasm2/rewrite/parallel_to_glob.py +28 -15
  40. bloqade/qasm2/rewrite/parallel_to_uop.py +2 -8
  41. bloqade/qubit/__init__.py +12 -0
  42. bloqade/qubit/_dialect.py +3 -0
  43. bloqade/qubit/_interface.py +49 -0
  44. bloqade/qubit/_prelude.py +45 -0
  45. bloqade/qubit/analysis/__init__.py +1 -0
  46. bloqade/qubit/analysis/address_impl.py +40 -0
  47. bloqade/qubit/stdlib/__init__.py +2 -0
  48. bloqade/qubit/stdlib/_new.py +34 -0
  49. bloqade/qubit/stdlib/broadcast.py +62 -0
  50. bloqade/qubit/stdlib/simple.py +59 -0
  51. bloqade/qubit/stmts.py +60 -0
  52. bloqade/rewrite/passes/aggressive_unroll.py +2 -1
  53. bloqade/squin/__init__.py +44 -17
  54. bloqade/squin/analysis/__init__.py +0 -1
  55. bloqade/squin/analysis/schedule.py +2 -2
  56. bloqade/squin/gate/__init__.py +2 -0
  57. bloqade/squin/gate/_dialect.py +3 -0
  58. bloqade/squin/gate/_interface.py +98 -0
  59. bloqade/squin/gate/stmts.py +119 -0
  60. bloqade/squin/groups.py +4 -21
  61. bloqade/squin/noise/__init__.py +1 -9
  62. bloqade/squin/noise/_dialect.py +1 -1
  63. bloqade/squin/noise/_interface.py +45 -0
  64. bloqade/squin/noise/stmts.py +65 -29
  65. bloqade/squin/rewrite/U3_to_clifford.py +70 -51
  66. bloqade/squin/rewrite/__init__.py +0 -2
  67. bloqade/squin/rewrite/remove_dangling_qubits.py +2 -2
  68. bloqade/squin/rewrite/wrap_analysis.py +4 -35
  69. bloqade/squin/stdlib/broadcast/__init__.py +34 -0
  70. bloqade/squin/stdlib/broadcast/_qubit.py +4 -0
  71. bloqade/squin/stdlib/broadcast/gate.py +260 -0
  72. bloqade/squin/stdlib/broadcast/noise.py +144 -0
  73. bloqade/squin/stdlib/simple/__init__.py +33 -0
  74. bloqade/squin/stdlib/simple/gate.py +242 -0
  75. bloqade/squin/stdlib/simple/noise.py +126 -0
  76. bloqade/stim/__init__.py +1 -0
  77. bloqade/stim/_wrappers.py +6 -0
  78. bloqade/stim/dialects/noise/emit.py +6 -1
  79. bloqade/stim/dialects/noise/stmts.py +5 -3
  80. bloqade/stim/emit/stim_str.py +2 -0
  81. bloqade/stim/parse/lowering.py +12 -17
  82. bloqade/stim/passes/__init__.py +0 -1
  83. bloqade/stim/passes/flatten.py +26 -0
  84. bloqade/stim/passes/simplify_ifs.py +6 -1
  85. bloqade/stim/passes/squin_to_stim.py +4 -70
  86. bloqade/stim/rewrite/__init__.py +0 -4
  87. bloqade/stim/rewrite/ifs_to_stim.py +23 -29
  88. bloqade/stim/rewrite/qubit_to_stim.py +96 -51
  89. bloqade/stim/rewrite/squin_measure.py +9 -18
  90. bloqade/stim/rewrite/squin_noise.py +132 -108
  91. bloqade/stim/rewrite/util.py +5 -204
  92. bloqade/types.py +10 -0
  93. {bloqade_circuit-0.7.13.dist-info → bloqade_circuit-0.8.0.dist-info}/METADATA +2 -2
  94. {bloqade_circuit-0.7.13.dist-info → bloqade_circuit-0.8.0.dist-info}/RECORD +96 -100
  95. bloqade/native/dialects/gates/__init__.py +0 -3
  96. bloqade/native/dialects/gates/_dialect.py +0 -3
  97. bloqade/pyqrack/squin/op.py +0 -180
  98. bloqade/pyqrack/squin/runtime.py +0 -543
  99. bloqade/pyqrack/squin/wire.py +0 -51
  100. bloqade/squin/_typeinfer.py +0 -20
  101. bloqade/squin/analysis/address_impl.py +0 -71
  102. bloqade/squin/analysis/nsites/__init__.py +0 -9
  103. bloqade/squin/analysis/nsites/analysis.py +0 -50
  104. bloqade/squin/analysis/nsites/impls.py +0 -99
  105. bloqade/squin/analysis/nsites/lattice.py +0 -49
  106. bloqade/squin/cirq/__init__.py +0 -306
  107. bloqade/squin/cirq/emit/emit_circuit.py +0 -129
  108. bloqade/squin/cirq/emit/noise.py +0 -49
  109. bloqade/squin/cirq/emit/op.py +0 -176
  110. bloqade/squin/cirq/emit/qubit.py +0 -58
  111. bloqade/squin/cirq/emit/runtime.py +0 -242
  112. bloqade/squin/cirq/lowering.py +0 -439
  113. bloqade/squin/lowering.py +0 -80
  114. bloqade/squin/noise/_wrapper.py +0 -36
  115. bloqade/squin/noise/rewrite.py +0 -129
  116. bloqade/squin/op/__init__.py +0 -41
  117. bloqade/squin/op/_dialect.py +0 -3
  118. bloqade/squin/op/_wrapper.py +0 -121
  119. bloqade/squin/op/number.py +0 -5
  120. bloqade/squin/op/rewrite.py +0 -46
  121. bloqade/squin/op/stdlib.py +0 -62
  122. bloqade/squin/op/stmts.py +0 -300
  123. bloqade/squin/op/traits.py +0 -43
  124. bloqade/squin/op/types.py +0 -128
  125. bloqade/squin/parallel.py +0 -200
  126. bloqade/squin/qubit.py +0 -194
  127. bloqade/squin/rewrite/canonicalize.py +0 -60
  128. bloqade/squin/rewrite/desugar.py +0 -102
  129. bloqade/squin/stdlib/channel.py +0 -86
  130. bloqade/squin/stdlib/gate.py +0 -201
  131. bloqade/squin/types.py +0 -8
  132. bloqade/squin/wire.py +0 -201
  133. bloqade/stim/rewrite/wire_identity_elimination.py +0 -24
  134. bloqade/stim/rewrite/wire_to_stim.py +0 -57
  135. {bloqade_circuit-0.7.13.dist-info → bloqade_circuit-0.8.0.dist-info}/WHEEL +0 -0
  136. {bloqade_circuit-0.7.13.dist-info → bloqade_circuit-0.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,104 @@
1
+ import math
2
+
3
+ import cirq
4
+ from kirin.interp import MethodTable, impl
5
+
6
+ from bloqade.squin import gate
7
+
8
+ from .base import EmitCirq, EmitCirqFrame
9
+
10
+
11
+ @gate.dialect.register(key="emit.cirq")
12
+ class __EmitCirqGateMethods(MethodTable):
13
+
14
+ @impl(gate.stmts.X)
15
+ @impl(gate.stmts.Y)
16
+ @impl(gate.stmts.Z)
17
+ @impl(gate.stmts.H)
18
+ def hermitian(
19
+ self, emit: EmitCirq, frame: EmitCirqFrame, stmt: gate.stmts.SingleQubitGate
20
+ ):
21
+ qubits = frame.get(stmt.qubits)
22
+ cirq_op = getattr(cirq, stmt.name.upper())
23
+ frame.circuit.append(cirq_op.on_each(qubits))
24
+ return ()
25
+
26
+ @impl(gate.stmts.S)
27
+ @impl(gate.stmts.T)
28
+ def unitary(
29
+ self,
30
+ emit: EmitCirq,
31
+ frame: EmitCirqFrame,
32
+ stmt: gate.stmts.SingleQubitNonHermitianGate,
33
+ ):
34
+ qubits = frame.get(stmt.qubits)
35
+ cirq_op = getattr(cirq, stmt.name.upper())
36
+ if stmt.adjoint:
37
+ cirq_op = cirq_op ** (-1)
38
+
39
+ frame.circuit.append(cirq_op.on_each(qubits))
40
+ return ()
41
+
42
+ @impl(gate.stmts.SqrtX)
43
+ @impl(gate.stmts.SqrtY)
44
+ def sqrt(
45
+ self,
46
+ emit: EmitCirq,
47
+ frame: EmitCirqFrame,
48
+ stmt: gate.stmts.SqrtX | gate.stmts.SqrtY,
49
+ ):
50
+ qubits = frame.get(stmt.qubits)
51
+
52
+ exponent = 0.5
53
+ if stmt.adjoint:
54
+ exponent *= -1
55
+
56
+ if isinstance(stmt, gate.stmts.SqrtX):
57
+ cirq_op = cirq.XPowGate(exponent=exponent)
58
+ else:
59
+ cirq_op = cirq.YPowGate(exponent=exponent)
60
+
61
+ frame.circuit.append(cirq_op.on_each(qubits))
62
+ return ()
63
+
64
+ @impl(gate.stmts.CX)
65
+ @impl(gate.stmts.CY)
66
+ @impl(gate.stmts.CZ)
67
+ def control(
68
+ self, emit: EmitCirq, frame: EmitCirqFrame, stmt: gate.stmts.ControlledGate
69
+ ):
70
+ controls = frame.get(stmt.controls)
71
+ targets = frame.get(stmt.targets)
72
+ cirq_op = getattr(cirq, stmt.name.upper())
73
+ cirq_qubits = [(ctrl, target) for ctrl, target in zip(controls, targets)]
74
+ frame.circuit.append(cirq_op.on_each(cirq_qubits))
75
+ return ()
76
+
77
+ @impl(gate.stmts.Rx)
78
+ @impl(gate.stmts.Ry)
79
+ @impl(gate.stmts.Rz)
80
+ def rot(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: gate.stmts.RotationGate):
81
+ qubits = frame.get(stmt.qubits)
82
+
83
+ turns = frame.get(stmt.angle)
84
+ angle = turns * 2 * math.pi
85
+ cirq_op = getattr(cirq, stmt.name.title())(rads=angle)
86
+
87
+ frame.circuit.append(cirq_op.on_each(qubits))
88
+ return ()
89
+
90
+ @impl(gate.stmts.U3)
91
+ def u3(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: gate.stmts.U3):
92
+ qubits = frame.get(stmt.qubits)
93
+
94
+ theta = frame.get(stmt.theta) * 2 * math.pi
95
+ phi = frame.get(stmt.phi) * 2 * math.pi
96
+ lam = frame.get(stmt.lam) * 2 * math.pi
97
+
98
+ frame.circuit.append(cirq.Rz(rads=lam).on_each(*qubits))
99
+
100
+ frame.circuit.append(cirq.Ry(rads=theta).on_each(*qubits))
101
+
102
+ frame.circuit.append(cirq.Rz(rads=phi).on_each(*qubits))
103
+
104
+ return ()
@@ -0,0 +1,90 @@
1
+ import cirq
2
+ from kirin.interp import MethodTable, impl
3
+
4
+ from bloqade.squin import noise
5
+
6
+ from .base import EmitCirq, EmitCirqFrame
7
+
8
+
9
+ @noise.dialect.register(key="emit.cirq")
10
+ class __EmitCirqNoiseMethods(MethodTable):
11
+
12
+ two_qubit_paulis = (
13
+ "IX",
14
+ "IY",
15
+ "IZ",
16
+ "XI",
17
+ "XX",
18
+ "XY",
19
+ "XZ",
20
+ "YI",
21
+ "YX",
22
+ "YY",
23
+ "YZ",
24
+ "ZI",
25
+ "ZX",
26
+ "ZY",
27
+ "ZZ",
28
+ )
29
+
30
+ @impl(noise.stmts.Depolarize)
31
+ def depolarize(
32
+ self, interp: EmitCirq, frame: EmitCirqFrame, stmt: noise.stmts.Depolarize
33
+ ):
34
+ p = frame.get(stmt.p)
35
+ qubits = frame.get(stmt.qubits)
36
+ cirfq_op = cirq.depolarize(p, n_qubits=1).on_each(qubits)
37
+ frame.circuit.append(cirfq_op)
38
+ return ()
39
+
40
+ @impl(noise.stmts.Depolarize2)
41
+ def depolarize2(
42
+ self, interp: EmitCirq, frame: EmitCirqFrame, stmt: noise.stmts.Depolarize2
43
+ ):
44
+ p = frame.get(stmt.p)
45
+ controls = frame.get(stmt.controls)
46
+ targets = frame.get(stmt.targets)
47
+ cirq_qubits = [(ctrl, target) for ctrl, target in zip(controls, targets)]
48
+ cirq_op = cirq.depolarize(p, n_qubits=2).on_each(cirq_qubits)
49
+ frame.circuit.append(cirq_op)
50
+ return ()
51
+
52
+ @impl(noise.stmts.SingleQubitPauliChannel)
53
+ def single_qubit_pauli_channel(
54
+ self,
55
+ interp: EmitCirq,
56
+ frame: EmitCirqFrame,
57
+ stmt: noise.stmts.SingleQubitPauliChannel,
58
+ ):
59
+ px = frame.get(stmt.px)
60
+ py = frame.get(stmt.py)
61
+ pz = frame.get(stmt.pz)
62
+ qubits = frame.get(stmt.qubits)
63
+
64
+ cirq_op = cirq.asymmetric_depolarize(px, py, pz).on_each(qubits)
65
+ frame.circuit.append(cirq_op)
66
+
67
+ return ()
68
+
69
+ @impl(noise.stmts.TwoQubitPauliChannel)
70
+ def two_qubit_pauli_channel(
71
+ self,
72
+ interp: EmitCirq,
73
+ frame: EmitCirqFrame,
74
+ stmt: noise.stmts.TwoQubitPauliChannel,
75
+ ):
76
+ ps = frame.get(stmt.probabilities)
77
+ error_probabilities = {
78
+ key: p for (key, p) in zip(self.two_qubit_paulis, ps) if p != 0
79
+ }
80
+
81
+ controls = frame.get(stmt.controls)
82
+ targets = frame.get(stmt.targets)
83
+ cirq_qubits = [(ctrl, target) for ctrl, target in zip(controls, targets)]
84
+
85
+ cirq_op = cirq.asymmetric_depolarize(
86
+ error_probabilities=error_probabilities
87
+ ).on_each(cirq_qubits)
88
+ frame.circuit.append(cirq_op)
89
+
90
+ return ()
@@ -0,0 +1,35 @@
1
+ import cirq
2
+ from kirin.interp import MethodTable, impl
3
+
4
+ from bloqade.qubit import stmts as qubit
5
+
6
+ from .base import EmitCirq, EmitCirqFrame
7
+
8
+
9
+ @qubit.dialect.register(key="emit.cirq")
10
+ class EmitCirqQubitMethods(MethodTable):
11
+ @impl(qubit.New)
12
+ def new(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.New):
13
+ if frame.qubits is not None:
14
+ cirq_qubit = frame.qubits[frame.qubit_index]
15
+ else:
16
+ cirq_qubit = cirq.LineQubit(frame.qubit_index)
17
+
18
+ frame.qubit_index += 1
19
+ return (cirq_qubit,)
20
+
21
+ @impl(qubit.Measure)
22
+ def measure_qubit_list(
23
+ self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.Measure
24
+ ):
25
+ qbits = frame.get(stmt.qubits)
26
+ frame.circuit.append(cirq.measure(qbits))
27
+ return (emit.void,)
28
+
29
+ @impl(qubit.Reset)
30
+ def reset(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.Reset):
31
+ qubits = frame.get(stmt.qubits)
32
+ frame.circuit.append(
33
+ cirq.ResetChannel().on_each(*qubits),
34
+ )
35
+ return ()