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.
- bloqade/analysis/address/__init__.py +8 -4
- bloqade/analysis/address/analysis.py +119 -29
- bloqade/analysis/address/impls.py +290 -87
- bloqade/analysis/address/lattice.py +209 -24
- bloqade/analysis/fidelity/analysis.py +2 -2
- bloqade/analysis/measure_id/impls.py +3 -27
- bloqade/cirq_utils/__init__.py +3 -1
- bloqade/cirq_utils/emit/__init__.py +3 -0
- bloqade/cirq_utils/emit/base.py +243 -0
- bloqade/cirq_utils/emit/gate.py +104 -0
- bloqade/cirq_utils/emit/noise.py +90 -0
- bloqade/cirq_utils/emit/qubit.py +35 -0
- bloqade/cirq_utils/lowering.py +664 -0
- bloqade/native/__init__.py +0 -1
- bloqade/native/_prelude.py +3 -3
- bloqade/native/dialects/gate/__init__.py +2 -0
- bloqade/native/dialects/gate/_dialect.py +3 -0
- bloqade/native/dialects/{gates → gate}/_interface.py +5 -5
- bloqade/native/dialects/{gates → gate}/stmts.py +5 -5
- bloqade/native/stdlib/broadcast.py +19 -19
- bloqade/native/stdlib/simple.py +14 -13
- bloqade/native/upstream/__init__.py +5 -0
- bloqade/native/upstream/squin2native.py +136 -0
- bloqade/pyqrack/__init__.py +1 -2
- bloqade/pyqrack/device.py +6 -17
- bloqade/pyqrack/native.py +17 -17
- bloqade/pyqrack/reg.py +1 -6
- bloqade/pyqrack/squin/gate/__init__.py +1 -0
- bloqade/pyqrack/squin/gate/gate.py +136 -0
- bloqade/pyqrack/squin/noise/native.py +120 -54
- bloqade/pyqrack/squin/qubit.py +25 -41
- bloqade/pyqrack/target.py +2 -2
- bloqade/qasm2/dialects/core/address.py +21 -12
- bloqade/qasm2/dialects/noise/fidelity.py +2 -6
- bloqade/qasm2/dialects/noise/model.py +2 -1
- bloqade/qasm2/passes/parallel.py +3 -1
- bloqade/qasm2/rewrite/__init__.py +0 -1
- bloqade/qasm2/rewrite/noise/heuristic_noise.py +7 -17
- bloqade/qasm2/rewrite/parallel_to_glob.py +28 -15
- bloqade/qasm2/rewrite/parallel_to_uop.py +2 -8
- bloqade/qubit/__init__.py +12 -0
- bloqade/qubit/_dialect.py +3 -0
- bloqade/qubit/_interface.py +49 -0
- bloqade/qubit/_prelude.py +45 -0
- bloqade/qubit/analysis/__init__.py +1 -0
- bloqade/qubit/analysis/address_impl.py +40 -0
- bloqade/qubit/stdlib/__init__.py +2 -0
- bloqade/qubit/stdlib/_new.py +34 -0
- bloqade/qubit/stdlib/broadcast.py +62 -0
- bloqade/qubit/stdlib/simple.py +59 -0
- bloqade/qubit/stmts.py +60 -0
- bloqade/rewrite/passes/aggressive_unroll.py +2 -1
- bloqade/squin/__init__.py +44 -17
- bloqade/squin/analysis/__init__.py +0 -1
- bloqade/squin/analysis/schedule.py +2 -2
- bloqade/squin/gate/__init__.py +2 -0
- bloqade/squin/gate/_dialect.py +3 -0
- bloqade/squin/gate/_interface.py +98 -0
- bloqade/squin/gate/stmts.py +119 -0
- bloqade/squin/groups.py +4 -21
- bloqade/squin/noise/__init__.py +1 -9
- bloqade/squin/noise/_dialect.py +1 -1
- bloqade/squin/noise/_interface.py +45 -0
- bloqade/squin/noise/stmts.py +65 -29
- bloqade/squin/rewrite/U3_to_clifford.py +70 -51
- bloqade/squin/rewrite/__init__.py +0 -2
- bloqade/squin/rewrite/remove_dangling_qubits.py +2 -2
- bloqade/squin/rewrite/wrap_analysis.py +4 -35
- bloqade/squin/stdlib/broadcast/__init__.py +34 -0
- bloqade/squin/stdlib/broadcast/_qubit.py +4 -0
- bloqade/squin/stdlib/broadcast/gate.py +260 -0
- bloqade/squin/stdlib/broadcast/noise.py +144 -0
- bloqade/squin/stdlib/simple/__init__.py +33 -0
- bloqade/squin/stdlib/simple/gate.py +242 -0
- bloqade/squin/stdlib/simple/noise.py +126 -0
- bloqade/stim/__init__.py +1 -0
- bloqade/stim/_wrappers.py +6 -0
- bloqade/stim/dialects/noise/emit.py +6 -1
- bloqade/stim/dialects/noise/stmts.py +5 -3
- bloqade/stim/emit/stim_str.py +2 -0
- bloqade/stim/parse/lowering.py +12 -17
- bloqade/stim/passes/__init__.py +0 -1
- bloqade/stim/passes/flatten.py +26 -0
- bloqade/stim/passes/simplify_ifs.py +6 -1
- bloqade/stim/passes/squin_to_stim.py +4 -70
- bloqade/stim/rewrite/__init__.py +0 -4
- bloqade/stim/rewrite/ifs_to_stim.py +23 -29
- bloqade/stim/rewrite/qubit_to_stim.py +96 -51
- bloqade/stim/rewrite/squin_measure.py +9 -18
- bloqade/stim/rewrite/squin_noise.py +132 -108
- bloqade/stim/rewrite/util.py +5 -204
- bloqade/types.py +10 -0
- {bloqade_circuit-0.7.13.dist-info → bloqade_circuit-0.8.0.dist-info}/METADATA +2 -2
- {bloqade_circuit-0.7.13.dist-info → bloqade_circuit-0.8.0.dist-info}/RECORD +96 -100
- bloqade/native/dialects/gates/__init__.py +0 -3
- bloqade/native/dialects/gates/_dialect.py +0 -3
- bloqade/pyqrack/squin/op.py +0 -180
- bloqade/pyqrack/squin/runtime.py +0 -543
- bloqade/pyqrack/squin/wire.py +0 -51
- bloqade/squin/_typeinfer.py +0 -20
- bloqade/squin/analysis/address_impl.py +0 -71
- bloqade/squin/analysis/nsites/__init__.py +0 -9
- bloqade/squin/analysis/nsites/analysis.py +0 -50
- bloqade/squin/analysis/nsites/impls.py +0 -99
- bloqade/squin/analysis/nsites/lattice.py +0 -49
- bloqade/squin/cirq/__init__.py +0 -306
- bloqade/squin/cirq/emit/emit_circuit.py +0 -129
- bloqade/squin/cirq/emit/noise.py +0 -49
- bloqade/squin/cirq/emit/op.py +0 -176
- bloqade/squin/cirq/emit/qubit.py +0 -58
- bloqade/squin/cirq/emit/runtime.py +0 -242
- bloqade/squin/cirq/lowering.py +0 -439
- bloqade/squin/lowering.py +0 -80
- bloqade/squin/noise/_wrapper.py +0 -36
- bloqade/squin/noise/rewrite.py +0 -129
- bloqade/squin/op/__init__.py +0 -41
- bloqade/squin/op/_dialect.py +0 -3
- bloqade/squin/op/_wrapper.py +0 -121
- bloqade/squin/op/number.py +0 -5
- bloqade/squin/op/rewrite.py +0 -46
- bloqade/squin/op/stdlib.py +0 -62
- bloqade/squin/op/stmts.py +0 -300
- bloqade/squin/op/traits.py +0 -43
- bloqade/squin/op/types.py +0 -128
- bloqade/squin/parallel.py +0 -200
- bloqade/squin/qubit.py +0 -194
- bloqade/squin/rewrite/canonicalize.py +0 -60
- bloqade/squin/rewrite/desugar.py +0 -102
- bloqade/squin/stdlib/channel.py +0 -86
- bloqade/squin/stdlib/gate.py +0 -201
- bloqade/squin/types.py +0 -8
- bloqade/squin/wire.py +0 -201
- bloqade/stim/rewrite/wire_identity_elimination.py +0 -24
- bloqade/stim/rewrite/wire_to_stim.py +0 -57
- {bloqade_circuit-0.7.13.dist-info → bloqade_circuit-0.8.0.dist-info}/WHEEL +0 -0
- {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 ()
|