bloqade-circuit 0.4.3__tar.gz → 0.4.5__tar.gz
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_circuit-0.4.3 → bloqade_circuit-0.4.5}/.pre-commit-config.yaml +1 -1
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/PKG-INFO +1 -1
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/pyproject.toml +1 -1
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/analysis/nsites/impls.py +7 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/cirq/__init__.py +74 -9
- bloqade_circuit-0.4.5/src/bloqade/squin/cirq/emit/noise.py +49 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/cirq/emit/runtime.py +9 -1
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/cirq/lowering.py +27 -21
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/noise/_wrapper.py +9 -2
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/noise/rewrite.py +3 -3
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/__init__.py +3 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/_wrapper.py +12 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/stmts.py +19 -1
- bloqade_circuit-0.4.5/src/bloqade/squin/rewrite/U3_to_clifford.py +149 -0
- bloqade_circuit-0.4.5/src/bloqade/squin/rewrite/__init__.py +7 -0
- bloqade_circuit-0.4.5/src/bloqade/squin/rewrite/remove_dangling_qubits.py +19 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/rewrite/wrap_analysis.py +34 -19
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/__init__.py +1 -1
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/stmts/const.py +1 -1
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/stmts/__init__.py +6 -0
- bloqade_circuit-0.4.5/src/bloqade/stim/passes/__init__.py +1 -0
- bloqade_circuit-0.4.5/src/bloqade/stim/passes/squin_to_stim.py +86 -0
- {bloqade_circuit-0.4.3/src/bloqade/squin → bloqade_circuit-0.4.5/src/bloqade/stim}/rewrite/__init__.py +1 -5
- bloqade_circuit-0.4.5/src/bloqade/stim/rewrite/py_constant_to_stim.py +42 -0
- {bloqade_circuit-0.4.3/src/bloqade/squin → bloqade_circuit-0.4.5/src/bloqade/stim}/rewrite/qubit_to_stim.py +18 -3
- {bloqade_circuit-0.4.3/src/bloqade/squin → bloqade_circuit-0.4.5/src/bloqade/stim}/rewrite/squin_measure.py +2 -2
- bloqade_circuit-0.4.3/src/bloqade/squin/rewrite/stim_rewrite_util.py → bloqade_circuit-0.4.5/src/bloqade/stim/rewrite/util.py +36 -17
- {bloqade_circuit-0.4.3/src/bloqade/squin → bloqade_circuit-0.4.5/src/bloqade/stim}/rewrite/wire_to_stim.py +1 -1
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/squin/cirq/test_cirq_to_squin.py +76 -0
- bloqade_circuit-0.4.5/test/squin/cirq/test_squin_noise_to_cirq.py +88 -0
- bloqade_circuit-0.4.5/test/squin/rewrite/test_U3_to_clifford.py +471 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/qubit/qubit.txt +5 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/qubit/qubit_broadcast.txt +3 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/qubit/qubit_reset.txt +3 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire.txt +3 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire_apply.txt +2 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire_apply_control.txt +2 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire_broadcast.txt +2 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire_broadcast_control.txt +6 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire_measure.txt +2 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire_multiple_apply.txt +5 -0
- bloqade_circuit-0.4.5/test/stim/passes/stim_reference_programs/wire/wire_reset.txt +3 -0
- bloqade_circuit-0.4.5/test/stim/passes/test_squin_qubit_to_stim.py +96 -0
- bloqade_circuit-0.4.5/test/stim/passes/test_squin_wire_to_stim.py +335 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/uv.lock +1 -1
- bloqade_circuit-0.4.3/src/bloqade/squin/passes/__init__.py +0 -1
- bloqade_circuit-0.4.3/src/bloqade/squin/passes/stim.py +0 -68
- bloqade_circuit-0.4.3/test/squin/stim/test_stim.py +0 -440
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/.github/dependabot.yml +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/.github/workflows/ci.yml +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/.github/workflows/isort.yml +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/.github/workflows/lint.yml +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/.github/workflows/release.yml +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/.gitignore +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/LICENSE +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/README.md +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/_typos.toml +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/justfile +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/analysis/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/analysis/address/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/analysis/address/analysis.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/analysis/address/impls.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/analysis/address/lattice.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/analysis/fidelity/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/analysis/fidelity/analysis.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/device.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/base.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/device.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/noise/native.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/qasm2/core.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/qasm2/glob.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/qasm2/parallel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/qasm2/uop.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/reg.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/squin/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/squin/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/squin/noise/native.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/squin/op.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/squin/qubit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/squin/runtime.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/squin/wire.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/target.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/pyqrack/task.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/_qasm_loading.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/_wrappers.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/core/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/core/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/core/_emit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/core/_typeinfer.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/core/address.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/core/stmts.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/expr/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/expr/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/expr/_emit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/expr/_from_python.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/expr/_interp.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/expr/stmts.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/glob.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/indexing.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/inline.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/noise/fidelity.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/noise/model.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/parallel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/uop/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/uop/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/uop/_emit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/uop/schedule.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/dialects/uop/stmts.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/emit/base.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/emit/gate.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/emit/impls/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/emit/impls/noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/emit/main.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/emit/target.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/glob.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/groups.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parallel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/ast.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/build.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/lowering.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/parser.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/print.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/qasm2.lark +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/visitor.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/parse/visitor.pyi +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/fold.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/glob.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/lift_qubits.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/parallel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/py2qasm.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/qasm2py.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/passes/unroll_if.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/desugar.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/glob.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/insert_qubits.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/native_gates.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/noise/heuristic_noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/noise/remove_noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/parallel_to_uop.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/register.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/split_ifs.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/rewrite/uop_to_parallel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qasm2/types.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qbraid/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qbraid/lowering.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qbraid/schema.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qbraid/simulation_result.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/qbraid/target.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/analysis/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/analysis/nsites/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/analysis/nsites/analysis.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/analysis/nsites/lattice.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/analysis/schedule.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/cirq/emit/emit_circuit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/cirq/emit/op.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/cirq/emit/qubit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/groups.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/lowering.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/number.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/rewrite.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/stdlib.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/traits.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/op/types.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/qubit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/rewrite/desugar.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/squin/wire.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/_wrappers.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/emit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/interp.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/lowering.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/stmts/annotate.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/auxiliary/types.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/collapse/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/collapse/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/collapse/emit_str.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/collapse/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/collapse/stmts/measure.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/collapse/stmts/pp_measure.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/collapse/stmts/reset.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/emit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/stmts/base.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/stmts/clifford_1q.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/stmts/clifford_2q.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/stmts/control_2q.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/gate/stmts/pp.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/noise/emit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/dialects/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/emit/stim_str.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/groups.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/stim/parse/lowering.py +0 -0
- {bloqade_circuit-0.4.3/src/bloqade/squin → bloqade_circuit-0.4.5/src/bloqade/stim}/rewrite/wire_identity_elimination.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/task.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/test_utils.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/types.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/animate.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/base.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/gate_event.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/runtime/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/runtime/aod.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/runtime/atoms.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/runtime/ppoly.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/runtime/qpustate.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/src/bloqade/visual/animation/runtime/utils.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/analysis/address/test_analysis.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/analysis/address/test_lattice.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/analysis/fidelity/test_fidelity.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/runtime/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/runtime/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/runtime/noise/qasm2/test_loss.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/runtime/noise/qasm2/test_pauli.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/runtime/test_dyn_memory.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/runtime/test_qrack.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/squin/test_kernel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/squin/test_noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/pyqrack/test_target.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/analysis/test_dag.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/emit/test_extended.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/emit/test_extended_noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/emit/test_qasm2.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/emit/test_qasm2_emit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/invalid_programs/invalid_if.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/README.md +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/global.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/iqft1.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/main.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/noise.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/para.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/process_tomo.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/qelib1.inc +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/qft.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/qft2.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/rb.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/rep_code.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/ripple_carry_adder.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/tele.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/programs/valid_if.qasm +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/test_ast.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/parse/test_roundtrip.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/test_global_to_parallel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/test_global_to_uop.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/test_heuristic_noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/test_parallel_to_uop.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/test_qasm2py.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/test_unroll_if.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/passes/test_uop_to_parallel.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/test_count.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/test_inline.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/test_lowering.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/test_native.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qasm2/test_two2one.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qbraid/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qbraid/test_clean_circuit.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qbraid/test_lowering.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/qbraid/test_target.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/sample/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/sample/test_noise_model.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/squin/analysis/test_nsites_analysis.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/squin/cirq/test_squin_to_cirq.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/squin/op/test_reset.py +0 -0
- {bloqade_circuit-0.4.3/test/squin → bloqade_circuit-0.4.5/test/squin/rewrite}/test_mult_rewrite.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/squin/test_constprop.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/squin/test_sugar.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/base.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_1q.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_ctrl.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_detector.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_meas.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_obs_inc.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_ppmeas.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_qubit_coords.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/emit/test_stim_spp.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/test_stim_circuits.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/dialects/stim/test_stim_const.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/base.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/test_parse.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/test_parse_clifford.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/test_parse_control.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/test_parse_custom.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/test_parse_noise.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/parse/test_parse_spp.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/wrapper/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/stim/wrapper/test_wrapper.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/test_serialization.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/test_zone_model.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/visual/__init__.py +0 -0
- {bloqade_circuit-0.4.3 → bloqade_circuit-0.4.5}/test/visual/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bloqade-circuit
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.5
|
|
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
|
|
@@ -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
|
|
@@ -9,8 +9,9 @@ from . import lowering as lowering
|
|
|
9
9
|
from .. import kernel
|
|
10
10
|
|
|
11
11
|
# NOTE: just to register methods
|
|
12
|
-
from .emit import op as op, qubit as qubit
|
|
12
|
+
from .emit import op as op, noise as noise, qubit as qubit
|
|
13
13
|
from .lowering import Squin
|
|
14
|
+
from ..noise.rewrite import RewriteNoiseStmts
|
|
14
15
|
from .emit.emit_circuit import EmitCirq
|
|
15
16
|
|
|
16
17
|
|
|
@@ -18,6 +19,9 @@ def load_circuit(
|
|
|
18
19
|
circuit: cirq.Circuit,
|
|
19
20
|
kernel_name: str = "main",
|
|
20
21
|
dialects: ir.DialectGroup = kernel,
|
|
22
|
+
register_as_argument: bool = False,
|
|
23
|
+
return_register: bool = False,
|
|
24
|
+
register_argument_name: str = "q",
|
|
21
25
|
globals: dict[str, Any] | None = None,
|
|
22
26
|
file: str | None = None,
|
|
23
27
|
lineno_offset: int = 0,
|
|
@@ -32,13 +36,23 @@ def load_circuit(
|
|
|
32
36
|
Keyword Args:
|
|
33
37
|
kernel_name (str): The name of the kernel to load. Defaults to "main".
|
|
34
38
|
dialects (ir.DialectGroup | None): The dialects to use. Defaults to `squin.kernel`.
|
|
39
|
+
register_as_argument (bool): Determine whether the resulting kernel function should accept
|
|
40
|
+
a single `ilist.IList[Qubit, Any]` argument that is a list of qubits used within the
|
|
41
|
+
function. This allows you to compose kernel functions generated from circuits.
|
|
42
|
+
Defaults to `False`.
|
|
43
|
+
return_register (bool): Determine whether the resulting kernel functionr returns a
|
|
44
|
+
single value of type `ilist.IList[Qubit, Any]` that is the list of qubits used
|
|
45
|
+
in the kernel function. Useful when you want to compose multiple kernel functions
|
|
46
|
+
generated from circuits. Defaults to `False`.
|
|
47
|
+
register_argument_name (str): The name of the argument that represents the qubit register.
|
|
48
|
+
Only used when `register_as_argument=True`. Defaults to "q".
|
|
35
49
|
globals (dict[str, Any] | None): The global variables to use. Defaults to None.
|
|
36
50
|
file (str | None): The file name for error reporting. Defaults to None.
|
|
37
51
|
lineno_offset (int): The line number offset for error reporting. Defaults to 0.
|
|
38
52
|
col_offset (int): The column number offset for error reporting. Defaults to 0.
|
|
39
53
|
compactify (bool): Whether to compactify the output. Defaults to True.
|
|
40
54
|
|
|
41
|
-
|
|
55
|
+
## Usage Examples:
|
|
42
56
|
|
|
43
57
|
```python
|
|
44
58
|
# from cirq's "hello qubit" example
|
|
@@ -60,6 +74,30 @@ def load_circuit(
|
|
|
60
74
|
# print the resulting IR
|
|
61
75
|
main.print()
|
|
62
76
|
```
|
|
77
|
+
|
|
78
|
+
You can also compose kernel functions generated from circuits by passing in
|
|
79
|
+
and / or returning the respective quantum registers:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
q = cirq.LineQubit.range(2)
|
|
83
|
+
circuit = cirq.Circuit(cirq.H(q[0]), cirq.CX(*q))
|
|
84
|
+
|
|
85
|
+
get_entangled_qubits = squin.cirq.load_circuit(
|
|
86
|
+
circuit, return_register=True, kernel_name="get_entangled_qubits"
|
|
87
|
+
)
|
|
88
|
+
get_entangled_qubits.print()
|
|
89
|
+
|
|
90
|
+
entangle_qubits = squin.cirq.load_circuit(
|
|
91
|
+
circuit, register_as_argument=True, kernel_name="entangle_qubits"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
@squin.kernel
|
|
95
|
+
def main():
|
|
96
|
+
qreg = get_entangled_qubits()
|
|
97
|
+
qreg2 = squin.qubit.new(1)
|
|
98
|
+
entangle_qubits([qreg[1], qreg2[0]])
|
|
99
|
+
return squin.qubit.measure(qreg2)
|
|
100
|
+
```
|
|
63
101
|
"""
|
|
64
102
|
|
|
65
103
|
target = Squin(dialects=dialects, circuit=circuit)
|
|
@@ -71,16 +109,38 @@ def load_circuit(
|
|
|
71
109
|
lineno_offset=lineno_offset,
|
|
72
110
|
col_offset=col_offset,
|
|
73
111
|
compactify=compactify,
|
|
112
|
+
register_as_argument=register_as_argument,
|
|
113
|
+
register_argument_name=register_argument_name,
|
|
74
114
|
)
|
|
75
115
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
116
|
+
if return_register:
|
|
117
|
+
return_value = target.qreg
|
|
118
|
+
else:
|
|
119
|
+
return_value = func.ConstantNone()
|
|
120
|
+
body.blocks[0].stmts.append(return_value)
|
|
121
|
+
|
|
122
|
+
return_node = func.Return(value_or_stmt=return_value)
|
|
123
|
+
body.blocks[0].stmts.append(return_node)
|
|
124
|
+
|
|
125
|
+
self_arg_name = kernel_name + "_self"
|
|
126
|
+
arg_names = [self_arg_name]
|
|
127
|
+
if register_as_argument:
|
|
128
|
+
args = (target.qreg.type,)
|
|
129
|
+
arg_names.append(register_argument_name)
|
|
130
|
+
else:
|
|
131
|
+
args = ()
|
|
132
|
+
|
|
133
|
+
# NOTE: add _self as argument; need to know signature before so do it after lowering
|
|
134
|
+
signature = func.Signature(args, return_node.value.type)
|
|
135
|
+
body.blocks[0].args.insert_from(
|
|
136
|
+
0,
|
|
137
|
+
types.Generic(ir.Method, types.Tuple.where(signature.inputs), signature.output),
|
|
138
|
+
self_arg_name,
|
|
139
|
+
)
|
|
80
140
|
|
|
81
141
|
code = func.Function(
|
|
82
142
|
sym_name=kernel_name,
|
|
83
|
-
signature=
|
|
143
|
+
signature=signature,
|
|
84
144
|
body=body,
|
|
85
145
|
)
|
|
86
146
|
|
|
@@ -88,7 +148,7 @@ def load_circuit(
|
|
|
88
148
|
mod=None,
|
|
89
149
|
py_func=None,
|
|
90
150
|
sym_name=kernel_name,
|
|
91
|
-
arg_names=
|
|
151
|
+
arg_names=arg_names,
|
|
92
152
|
dialects=dialects,
|
|
93
153
|
code=code,
|
|
94
154
|
)
|
|
@@ -176,7 +236,12 @@ def emit_circuit(
|
|
|
176
236
|
)
|
|
177
237
|
|
|
178
238
|
emitter = EmitCirq(qubits=qubits)
|
|
179
|
-
|
|
239
|
+
|
|
240
|
+
# Rewrite noise statements
|
|
241
|
+
mt_ = mt.similar(mt.dialects)
|
|
242
|
+
RewriteNoiseStmts(mt_.dialects)(mt_)
|
|
243
|
+
|
|
244
|
+
return emitter.run(mt_, args=())
|
|
180
245
|
|
|
181
246
|
|
|
182
247
|
def dump_circuit(mt: ir.Method, qubits: Sequence[cirq.Qid] | None = None, **kwargs):
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import cirq
|
|
2
|
+
from kirin.emit import EmitError
|
|
3
|
+
from kirin.interp import MethodTable, impl
|
|
4
|
+
|
|
5
|
+
from ... import noise
|
|
6
|
+
from .runtime import (
|
|
7
|
+
KronRuntime,
|
|
8
|
+
BasicOpRuntime,
|
|
9
|
+
OperatorRuntimeABC,
|
|
10
|
+
PauliStringRuntime,
|
|
11
|
+
)
|
|
12
|
+
from .emit_circuit import EmitCirq, EmitCirqFrame
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@noise.dialect.register(key="emit.cirq")
|
|
16
|
+
class EmitCirqNoiseMethods(MethodTable):
|
|
17
|
+
|
|
18
|
+
@impl(noise.stmts.StochasticUnitaryChannel)
|
|
19
|
+
def stochastic_unitary_channel(
|
|
20
|
+
self,
|
|
21
|
+
emit: EmitCirq,
|
|
22
|
+
frame: EmitCirqFrame,
|
|
23
|
+
stmt: noise.stmts.StochasticUnitaryChannel,
|
|
24
|
+
):
|
|
25
|
+
ops = frame.get(stmt.operators)
|
|
26
|
+
ps = frame.get(stmt.probabilities)
|
|
27
|
+
|
|
28
|
+
error_probabilities = {self._op_to_key(op_): p for op_, p in zip(ops, ps)}
|
|
29
|
+
cirq_op = cirq.asymmetric_depolarize(error_probabilities=error_probabilities)
|
|
30
|
+
return (BasicOpRuntime(cirq_op),)
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def _op_to_key(operator: OperatorRuntimeABC) -> str:
|
|
34
|
+
match operator:
|
|
35
|
+
case KronRuntime():
|
|
36
|
+
key_lhs = EmitCirqNoiseMethods._op_to_key(operator.lhs)
|
|
37
|
+
key_rhs = EmitCirqNoiseMethods._op_to_key(operator.rhs)
|
|
38
|
+
return key_lhs + key_rhs
|
|
39
|
+
|
|
40
|
+
case BasicOpRuntime():
|
|
41
|
+
return str(operator.gate)
|
|
42
|
+
|
|
43
|
+
case PauliStringRuntime():
|
|
44
|
+
return operator.string
|
|
45
|
+
|
|
46
|
+
case _:
|
|
47
|
+
raise EmitError(
|
|
48
|
+
f"Unexpected operator runtime in StochasticUnitaryChannel of type {type(operator).__name__} encountered!"
|
|
49
|
+
)
|
|
@@ -21,7 +21,10 @@ class OperatorRuntimeABC:
|
|
|
21
21
|
|
|
22
22
|
def unsafe_apply(
|
|
23
23
|
self, qubits: Sequence[cirq.Qid], adjoint: bool = False
|
|
24
|
-
) -> list[cirq.Operation]:
|
|
24
|
+
) -> list[cirq.Operation]:
|
|
25
|
+
raise NotImplementedError(
|
|
26
|
+
f"Apply method needs to be implemented in {self.__class__.__name__}"
|
|
27
|
+
)
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
@dataclass
|
|
@@ -38,6 +41,11 @@ class BasicOpRuntime(UnsafeOperatorRuntimeABC):
|
|
|
38
41
|
def num_qubits(self) -> int:
|
|
39
42
|
return self.gate.num_qubits()
|
|
40
43
|
|
|
44
|
+
def unsafe_apply(
|
|
45
|
+
self, qubits: Sequence[cirq.Qid], adjoint: bool = False
|
|
46
|
+
) -> list[cirq.Operation]:
|
|
47
|
+
return [self.gate(*qubits)]
|
|
48
|
+
|
|
41
49
|
|
|
42
50
|
@dataclass
|
|
43
51
|
class UnitaryRuntime(BasicOpRuntime):
|
|
@@ -3,7 +3,7 @@ from typing import Any
|
|
|
3
3
|
from dataclasses import field, dataclass
|
|
4
4
|
|
|
5
5
|
import cirq
|
|
6
|
-
from kirin import ir, lowering
|
|
6
|
+
from kirin import ir, types, lowering
|
|
7
7
|
from kirin.rewrite import Walk, CFGCompactify
|
|
8
8
|
from kirin.dialects import py, scf, ilist
|
|
9
9
|
|
|
@@ -25,27 +25,26 @@ class Squin(lowering.LoweringABC[CirqNode]):
|
|
|
25
25
|
"""Lower a cirq.Circuit object to a squin kernel"""
|
|
26
26
|
|
|
27
27
|
circuit: cirq.Circuit
|
|
28
|
-
qreg:
|
|
28
|
+
qreg: ir.SSAValue = field(init=False)
|
|
29
29
|
qreg_index: dict[cirq.Qid, int] = field(init=False, default_factory=dict)
|
|
30
30
|
next_qreg_index: int = field(init=False, default=0)
|
|
31
31
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
index = self.next_qreg_index
|
|
37
|
-
self.qreg_index[qid] = index
|
|
38
|
-
self.next_qreg_index += 1
|
|
32
|
+
def __post_init__(self):
|
|
33
|
+
# TODO: sort by cirq ordering
|
|
34
|
+
qbits = sorted(self.circuit.all_qubits())
|
|
35
|
+
self.qreg_index = {qid: idx for (idx, qid) in enumerate(qbits)}
|
|
39
36
|
|
|
37
|
+
def lower_qubit_getindex(self, state: lowering.State[CirqNode], qid: cirq.Qid):
|
|
38
|
+
index = self.qreg_index[qid]
|
|
40
39
|
index_ssa = state.current_frame.push(py.Constant(index)).result
|
|
41
|
-
qbit_getitem = state.current_frame.push(py.GetItem(self.qreg
|
|
40
|
+
qbit_getitem = state.current_frame.push(py.GetItem(self.qreg, index_ssa))
|
|
42
41
|
return qbit_getitem.result
|
|
43
42
|
|
|
44
43
|
def lower_qubit_getindices(
|
|
45
44
|
self, state: lowering.State[CirqNode], qids: list[cirq.Qid]
|
|
46
45
|
):
|
|
47
46
|
qbits_getitem = [self.lower_qubit_getindex(state, qid) for qid in qids]
|
|
48
|
-
qbits_stmt = ilist.New(values=qbits_getitem)
|
|
47
|
+
qbits_stmt = ilist.New(values=qbits_getitem, elem_type=qubit.QubitType)
|
|
49
48
|
qbits_result = state.current_frame.get(qbits_stmt.name)
|
|
50
49
|
|
|
51
50
|
if qbits_result is not None:
|
|
@@ -64,6 +63,8 @@ class Squin(lowering.LoweringABC[CirqNode]):
|
|
|
64
63
|
lineno_offset: int = 0,
|
|
65
64
|
col_offset: int = 0,
|
|
66
65
|
compactify: bool = True,
|
|
66
|
+
register_as_argument: bool = False,
|
|
67
|
+
register_argument_name: str = "q",
|
|
67
68
|
) -> ir.Region:
|
|
68
69
|
|
|
69
70
|
state = lowering.State(
|
|
@@ -73,16 +74,21 @@ class Squin(lowering.LoweringABC[CirqNode]):
|
|
|
73
74
|
col_offset=col_offset,
|
|
74
75
|
)
|
|
75
76
|
|
|
76
|
-
with state.frame(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
77
|
+
with state.frame([stmt], globals=globals, finalize_next=False) as frame:
|
|
78
|
+
|
|
79
|
+
# NOTE: need a register of qubits before lowering statements
|
|
80
|
+
if register_as_argument:
|
|
81
|
+
# NOTE: register as argument to the kernel; we have freedom of choice for the name here
|
|
82
|
+
frame.curr_block.args.append_from(
|
|
83
|
+
ilist.IListType[qubit.QubitType, types.Any],
|
|
84
|
+
name=register_argument_name,
|
|
85
|
+
)
|
|
86
|
+
self.qreg = frame.curr_block.args[0]
|
|
87
|
+
else:
|
|
88
|
+
# NOTE: create a new register of appropriate size
|
|
89
|
+
n_qubits = len(self.qreg_index)
|
|
90
|
+
n = frame.push(py.Constant(n_qubits))
|
|
91
|
+
self.qreg = frame.push(qubit.New(n_qubits=n.result)).result
|
|
86
92
|
|
|
87
93
|
self.visit(state, stmt)
|
|
88
94
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from kirin.dialects import ilist
|
|
1
4
|
from kirin.lowering import wraps
|
|
2
5
|
|
|
3
6
|
from bloqade.squin.op.types import Op
|
|
@@ -18,11 +21,15 @@ def depolarize(p: float) -> Op: ...
|
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
@wraps(stmts.SingleQubitPauliChannel)
|
|
21
|
-
def single_qubit_pauli_channel(
|
|
24
|
+
def single_qubit_pauli_channel(
|
|
25
|
+
params: ilist.IList[float, Literal[3]] | list[float] | tuple[float, float, float],
|
|
26
|
+
) -> Op: ...
|
|
22
27
|
|
|
23
28
|
|
|
24
29
|
@wraps(stmts.TwoQubitPauliChannel)
|
|
25
|
-
def two_qubit_pauli_channel(
|
|
30
|
+
def two_qubit_pauli_channel(
|
|
31
|
+
params: ilist.IList[float, Literal[15]] | list[float] | tuple[float, ...],
|
|
32
|
+
) -> Op: ...
|
|
26
33
|
|
|
27
34
|
|
|
28
35
|
@wraps(stmts.QubitLoss)
|
|
@@ -58,12 +58,12 @@ class _RewriteNoiseStmts(RewriteRule):
|
|
|
58
58
|
def rewrite_two_qubit_pauli_channel(
|
|
59
59
|
self, node: TwoQubitPauliChannel
|
|
60
60
|
) -> RewriteResult:
|
|
61
|
-
paulis = (
|
|
61
|
+
paulis = (Identity(sites=1), X(), Y(), Z())
|
|
62
62
|
for op in paulis:
|
|
63
63
|
op.insert_before(node)
|
|
64
64
|
|
|
65
|
-
# NOTE: collect list so we can skip the
|
|
66
|
-
combinations = list(itertools.product(paulis, repeat=2))[
|
|
65
|
+
# NOTE: collect list so we can skip the first entry, which will be two identities
|
|
66
|
+
combinations = list(itertools.product(paulis, repeat=2))[1:]
|
|
67
67
|
operators: list[ir.SSAValue] = []
|
|
68
68
|
for pauli_1, pauli_2 in combinations:
|
|
69
69
|
op = Kron(pauli_1.result, pauli_2.result)
|
|
@@ -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
|
|
|
@@ -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()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .wrap_analysis import (
|
|
2
|
+
SitesAttribute as SitesAttribute,
|
|
3
|
+
AddressAttribute as AddressAttribute,
|
|
4
|
+
WrapOpSiteAnalysis as WrapOpSiteAnalysis,
|
|
5
|
+
WrapAddressAnalysis as WrapAddressAnalysis,
|
|
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)
|