bloqade-circuit 0.4.0__tar.gz → 0.4.2__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.0 → bloqade_circuit-0.4.2}/PKG-INFO +1 -1
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/pyproject.toml +1 -1
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/__init__.py +1 -1
- bloqade_circuit-0.4.2/src/bloqade/pyqrack/squin/noise/__init__.py +1 -0
- bloqade_circuit-0.4.2/src/bloqade/pyqrack/squin/noise/native.py +72 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/lowering.py +67 -73
- bloqade_circuit-0.4.2/src/bloqade/squin/__init__.py +17 -0
- bloqade_circuit-0.4.2/src/bloqade/squin/cirq/__init__.py +89 -0
- bloqade_circuit-0.4.2/src/bloqade/squin/cirq/lowering.py +303 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/groups.py +3 -3
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/noise/__init__.py +3 -1
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/noise/_wrapper.py +7 -3
- bloqade_circuit-0.4.2/src/bloqade/squin/noise/rewrite.py +111 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/noise/stmts.py +21 -16
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/stmts.py +1 -12
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/types.py +2 -0
- bloqade_circuit-0.4.2/test/pyqrack/squin/test_noise.py +159 -0
- bloqade_circuit-0.4.2/test/qasm2/test_lowering.py +165 -0
- bloqade_circuit-0.4.2/test/squin/cirq/test_cirq_to_squin.py +161 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/uv.lock +1 -1
- bloqade_circuit-0.4.0/src/bloqade/squin/__init__.py +0 -8
- bloqade_circuit-0.4.0/test/qasm2/test_lowering.py +0 -79
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/.github/dependabot.yml +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/.github/workflows/ci.yml +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/.github/workflows/isort.yml +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/.github/workflows/lint.yml +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/.github/workflows/release.yml +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/.gitignore +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/.pre-commit-config.yaml +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/LICENSE +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/README.md +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/_typos.toml +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/justfile +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/analysis/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/analysis/address/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/analysis/address/analysis.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/analysis/address/impls.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/analysis/address/lattice.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/analysis/fidelity/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/analysis/fidelity/analysis.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/device.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/base.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/device.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/noise/native.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/qasm2/core.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/qasm2/glob.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/qasm2/parallel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/qasm2/uop.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/reg.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/squin/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/squin/op.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/squin/qubit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/squin/runtime.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/squin/wire.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/target.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/pyqrack/task.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/_qasm_loading.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/_wrappers.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/core/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/core/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/core/_emit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/core/_typeinfer.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/core/address.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/core/stmts.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/expr/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/expr/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/expr/_emit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/expr/_from_python.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/expr/_interp.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/expr/stmts.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/glob.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/indexing.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/inline.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/noise/fidelity.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/noise/model.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/parallel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/uop/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/uop/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/uop/_emit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/uop/schedule.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/dialects/uop/stmts.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/emit/base.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/emit/gate.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/emit/impls/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/emit/impls/noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/emit/main.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/emit/target.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/glob.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/groups.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parallel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/ast.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/build.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/parser.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/print.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/qasm2.lark +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/visitor.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/parse/visitor.pyi +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/fold.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/glob.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/lift_qubits.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/parallel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/py2qasm.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/qasm2py.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/passes/unroll_if.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/desugar.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/glob.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/insert_qubits.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/native_gates.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/noise/heuristic_noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/noise/remove_noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/parallel_to_uop.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/register.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/split_ifs.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/rewrite/uop_to_parallel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qasm2/types.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qbraid/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qbraid/lowering.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qbraid/schema.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qbraid/simulation_result.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/qbraid/target.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/analysis/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/analysis/nsites/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/analysis/nsites/analysis.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/analysis/nsites/impls.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/analysis/nsites/lattice.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/analysis/schedule.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/lowering.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/_wrapper.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/number.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/rewrite.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/stdlib.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/op/traits.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/passes/stim.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/qubit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/desugar.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/qubit_to_stim.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/squin_measure.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/stim_rewrite_util.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/wire_identity_elimination.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/wire_to_stim.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/rewrite/wrap_analysis.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/squin/wire.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/_wrappers.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/emit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/interp.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/lowering.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/stmts/annotate.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/stmts/const.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/auxiliary/types.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/collapse/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/collapse/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/collapse/emit_str.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/collapse/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/collapse/stmts/measure.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/collapse/stmts/pp_measure.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/collapse/stmts/reset.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/emit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/stmts/base.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/stmts/clifford_1q.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/stmts/clifford_2q.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/stmts/control_2q.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/gate/stmts/pp.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/noise/emit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/dialects/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/emit/stim_str.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/groups.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/stim/parse/lowering.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/task.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/test_utils.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/types.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/animate.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/base.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/gate_event.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/runtime/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/runtime/aod.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/runtime/atoms.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/runtime/ppoly.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/runtime/qpustate.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/src/bloqade/visual/animation/runtime/utils.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/analysis/address/test_analysis.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/analysis/address/test_lattice.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/analysis/fidelity/test_fidelity.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/runtime/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/runtime/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/runtime/noise/qasm2/test_loss.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/runtime/noise/qasm2/test_pauli.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/runtime/test_dyn_memory.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/runtime/test_qrack.py +0 -0
- /bloqade_circuit-0.4.0/test/pyqrack/test_squin.py → /bloqade_circuit-0.4.2/test/pyqrack/squin/test_kernel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/pyqrack/test_target.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/analysis/test_dag.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/emit/test_extended.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/emit/test_extended_noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/emit/test_qasm2.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/emit/test_qasm2_emit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/invalid_programs/invalid_if.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/README.md +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/global.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/iqft1.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/main.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/noise.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/para.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/process_tomo.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/qelib1.inc +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/qft.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/qft2.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/rb.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/rep_code.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/ripple_carry_adder.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/tele.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/programs/valid_if.qasm +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/test_ast.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/parse/test_roundtrip.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/test_global_to_parallel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/test_global_to_uop.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/test_heuristic_noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/test_parallel_to_uop.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/test_qasm2py.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/test_unroll_if.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/passes/test_uop_to_parallel.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/test_count.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/test_inline.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/test_native.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qasm2/test_two2one.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qbraid/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qbraid/test_clean_circuit.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qbraid/test_lowering.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/qbraid/test_target.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/sample/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/sample/test_noise_model.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/squin/analysis/test_nsites_analysis.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/squin/op/test_reset.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/squin/stim/test_stim.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/squin/test_constprop.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/squin/test_mult_rewrite.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/squin/test_sugar.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/base.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_1q.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_ctrl.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_detector.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_meas.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_obs_inc.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_ppmeas.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_qubit_coords.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/emit/test_stim_spp.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/test_stim_circuits.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/dialects/stim/test_stim_const.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/base.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/test_parse.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/test_parse_clifford.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/test_parse_control.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/test_parse_custom.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/test_parse_noise.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/parse/test_parse_spp.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/wrapper/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/stim/wrapper/test_wrapper.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/test_serialization.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/test_zone_model.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/test/visual/__init__.py +0 -0
- {bloqade_circuit-0.4.0 → bloqade_circuit-0.4.2}/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.2
|
|
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
|
|
@@ -16,7 +16,7 @@ from .task import PyQrackSimulatorTask as PyQrackSimulatorTask
|
|
|
16
16
|
# NOTE: The following import is for registering the method tables
|
|
17
17
|
from .noise import native as native
|
|
18
18
|
from .qasm2 import uop as uop, core as core, glob as glob, parallel as parallel
|
|
19
|
-
from .squin import op as op, qubit as qubit
|
|
19
|
+
from .squin import op as op, noise as noise, qubit as qubit
|
|
20
20
|
from .device import (
|
|
21
21
|
StackMemorySimulator as StackMemorySimulator,
|
|
22
22
|
DynamicMemorySimulator as DynamicMemorySimulator,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from . import native as native
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import random
|
|
2
|
+
import typing
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from kirin import interp
|
|
6
|
+
from kirin.dialects import ilist
|
|
7
|
+
|
|
8
|
+
from bloqade.pyqrack import QubitState, PyQrackQubit, PyQrackInterpreter
|
|
9
|
+
from bloqade.squin.noise.stmts import QubitLoss, StochasticUnitaryChannel
|
|
10
|
+
from bloqade.squin.noise._dialect import dialect as squin_noise_dialect
|
|
11
|
+
|
|
12
|
+
from ..runtime import OperatorRuntimeABC
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class StochasticUnitaryChannelRuntime(OperatorRuntimeABC):
|
|
17
|
+
operators: ilist.IList[OperatorRuntimeABC, typing.Any]
|
|
18
|
+
probabilities: ilist.IList[float, typing.Any]
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def n_sites(self) -> int:
|
|
22
|
+
n = self.operators[0].n_sites
|
|
23
|
+
for op in self.operators[1:]:
|
|
24
|
+
assert (
|
|
25
|
+
op.n_sites == n
|
|
26
|
+
), "Encountered a stochastic unitary channel with operators of different size!"
|
|
27
|
+
return n
|
|
28
|
+
|
|
29
|
+
def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
|
|
30
|
+
# NOTE: probabilities don't necessarily sum to 1; could be no noise event should occur
|
|
31
|
+
p_no_op = 1 - sum(self.probabilities)
|
|
32
|
+
if random.uniform(0.0, 1.0) < p_no_op:
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
selected_ops = random.choices(self.operators, weights=self.probabilities)
|
|
36
|
+
for op in selected_ops:
|
|
37
|
+
op.apply(*qubits, adjoint=adjoint)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class QubitLossRuntime(OperatorRuntimeABC):
|
|
42
|
+
p: float
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def n_sites(self) -> int:
|
|
46
|
+
return 1
|
|
47
|
+
|
|
48
|
+
def apply(self, qubit: PyQrackQubit, adjoint: bool = False) -> None:
|
|
49
|
+
if random.uniform(0.0, 1.0) < self.p:
|
|
50
|
+
qubit.state = QubitState.Lost
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@squin_noise_dialect.register(key="pyqrack")
|
|
54
|
+
class PyQrackMethods(interp.MethodTable):
|
|
55
|
+
@interp.impl(StochasticUnitaryChannel)
|
|
56
|
+
def stochastic_unitary_channel(
|
|
57
|
+
self,
|
|
58
|
+
interp: PyQrackInterpreter,
|
|
59
|
+
frame: interp.Frame,
|
|
60
|
+
stmt: StochasticUnitaryChannel,
|
|
61
|
+
):
|
|
62
|
+
operators = frame.get(stmt.operators)
|
|
63
|
+
probabilities = frame.get(stmt.probabilities)
|
|
64
|
+
|
|
65
|
+
return (StochasticUnitaryChannelRuntime(operators, probabilities),)
|
|
66
|
+
|
|
67
|
+
@interp.impl(QubitLoss)
|
|
68
|
+
def qubit_loss(
|
|
69
|
+
self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: QubitLoss
|
|
70
|
+
):
|
|
71
|
+
p = frame.get(stmt.p)
|
|
72
|
+
return (QubitLossRuntime(p),)
|
|
@@ -2,9 +2,9 @@ from typing import Any
|
|
|
2
2
|
from dataclasses import field, dataclass
|
|
3
3
|
|
|
4
4
|
from kirin import ir, types, lowering
|
|
5
|
-
from kirin.dialects import cf, func, ilist
|
|
5
|
+
from kirin.dialects import cf, scf, func, ilist
|
|
6
6
|
|
|
7
|
-
from bloqade.qasm2.types import CRegType, QRegType
|
|
7
|
+
from bloqade.qasm2.types import CRegType, QRegType, QubitType
|
|
8
8
|
from bloqade.qasm2.dialects import uop, core, expr, glob, noise, parallel
|
|
9
9
|
|
|
10
10
|
from . import ast
|
|
@@ -101,6 +101,13 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
101
101
|
def lower_global(
|
|
102
102
|
self, state: lowering.State[ast.Node], node: ast.Node
|
|
103
103
|
) -> lowering.LoweringABC.Result:
|
|
104
|
+
if isinstance(node, ast.Name):
|
|
105
|
+
# NOTE: might be a lookup for a gate function invoke
|
|
106
|
+
try:
|
|
107
|
+
return lowering.LoweringABC.Result(state.current_frame.globals[node.id])
|
|
108
|
+
except KeyError:
|
|
109
|
+
pass
|
|
110
|
+
|
|
104
111
|
raise lowering.BuildError("Global variables are not supported in QASM 2.0")
|
|
105
112
|
|
|
106
113
|
def visit_MainProgram(self, state: lowering.State[ast.Node], node: ast.MainProgram):
|
|
@@ -171,7 +178,6 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
171
178
|
def visit_Reset(self, state: lowering.State[ast.Node], node: ast.Reset):
|
|
172
179
|
state.current_frame.push(core.Reset(qarg=state.lower(node.qarg).expect_one()))
|
|
173
180
|
|
|
174
|
-
# TODO: clean this up? copied from cf dialect with a small modification
|
|
175
181
|
def visit_IfStmt(self, state: lowering.State[ast.Node], node: ast.IfStmt):
|
|
176
182
|
cond_stmt = core.CRegEq(
|
|
177
183
|
lhs=state.lower(node.cond.lhs).expect_one(),
|
|
@@ -179,84 +185,23 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
179
185
|
)
|
|
180
186
|
cond = state.current_frame.push(cond_stmt).result
|
|
181
187
|
frame = state.current_frame
|
|
182
|
-
before_block = frame.curr_block
|
|
183
188
|
|
|
184
|
-
with state.frame(node.body
|
|
189
|
+
with state.frame(node.body) as if_frame:
|
|
185
190
|
true_cond = if_frame.entr_block.args.append_from(types.Bool, cond.name)
|
|
186
191
|
if cond.name:
|
|
187
192
|
if_frame.defs[cond.name] = true_cond
|
|
188
193
|
|
|
194
|
+
# NOTE: pass in definitions from outer scope (usually just for the qreg)
|
|
195
|
+
if_frame.defs.update(frame.defs)
|
|
196
|
+
|
|
189
197
|
if_frame.exhaust()
|
|
190
|
-
self.branch_next_if_not_terminated(if_frame)
|
|
191
198
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if cond.name:
|
|
195
|
-
else_frame.defs[cond.name] = true_cond
|
|
196
|
-
else_frame.exhaust()
|
|
197
|
-
self.branch_next_if_not_terminated(else_frame)
|
|
198
|
-
|
|
199
|
-
with state.frame(frame.stream.split(), region=frame.curr_region) as after_frame:
|
|
200
|
-
after_frame.defs.update(frame.defs)
|
|
201
|
-
phi: set[str] = set()
|
|
202
|
-
for name in if_frame.defs.keys():
|
|
203
|
-
if frame.get(name):
|
|
204
|
-
phi.add(name)
|
|
205
|
-
elif name in else_frame.defs:
|
|
206
|
-
phi.add(name)
|
|
207
|
-
|
|
208
|
-
for name in else_frame.defs.keys():
|
|
209
|
-
if frame.get(name): # not defined in if_frame
|
|
210
|
-
phi.add(name)
|
|
211
|
-
|
|
212
|
-
for name in phi:
|
|
213
|
-
after_frame.defs[name] = after_frame.entr_block.args.append_from(
|
|
214
|
-
types.Any, name
|
|
215
|
-
)
|
|
199
|
+
# NOTE: qasm2 can never yield anything from if
|
|
200
|
+
if_frame.push(scf.Yield())
|
|
216
201
|
|
|
217
|
-
|
|
218
|
-
self.branch_next_if_not_terminated(after_frame)
|
|
219
|
-
after_frame.next_block.stmts.append(
|
|
220
|
-
cf.Branch(arguments=(), successor=frame.next_block)
|
|
221
|
-
)
|
|
202
|
+
then_body = if_frame.curr_region
|
|
222
203
|
|
|
223
|
-
|
|
224
|
-
for name in phi:
|
|
225
|
-
if value := if_frame.get(name):
|
|
226
|
-
if_args.append(value)
|
|
227
|
-
else:
|
|
228
|
-
raise lowering.BuildError(f"undefined variable {name} in if branch")
|
|
229
|
-
|
|
230
|
-
else_args = []
|
|
231
|
-
for name in phi:
|
|
232
|
-
if value := else_frame.get(name):
|
|
233
|
-
else_args.append(value)
|
|
234
|
-
else:
|
|
235
|
-
raise lowering.BuildError(f"undefined variable {name} in else branch")
|
|
236
|
-
|
|
237
|
-
if_frame.next_block.stmts.append(
|
|
238
|
-
cf.Branch(
|
|
239
|
-
arguments=tuple(if_args),
|
|
240
|
-
successor=after_frame.entr_block,
|
|
241
|
-
)
|
|
242
|
-
)
|
|
243
|
-
else_frame.next_block.stmts.append(
|
|
244
|
-
cf.Branch(
|
|
245
|
-
arguments=tuple(else_args),
|
|
246
|
-
successor=after_frame.entr_block,
|
|
247
|
-
)
|
|
248
|
-
)
|
|
249
|
-
before_block.stmts.append(
|
|
250
|
-
cf.ConditionalBranch(
|
|
251
|
-
cond=cond,
|
|
252
|
-
then_arguments=(cond,),
|
|
253
|
-
then_successor=if_frame.entr_block,
|
|
254
|
-
else_arguments=(cond,),
|
|
255
|
-
else_successor=else_frame.entr_block,
|
|
256
|
-
)
|
|
257
|
-
)
|
|
258
|
-
frame.defs.update(after_frame.defs)
|
|
259
|
-
frame.jump_next_block()
|
|
204
|
+
state.current_frame.push(scf.IfElse(cond, then_body=then_body))
|
|
260
205
|
|
|
261
206
|
def branch_next_if_not_terminated(self, frame: lowering.Frame):
|
|
262
207
|
"""Branch to the next block if the current block is not terminated.
|
|
@@ -430,7 +375,56 @@ class QASM2(lowering.LoweringABC[ast.Node]):
|
|
|
430
375
|
raise lowering.BuildError(f"Include {node.filename} not found")
|
|
431
376
|
|
|
432
377
|
def visit_Gate(self, state: lowering.State[ast.Node], node: ast.Gate):
|
|
433
|
-
|
|
378
|
+
arg_names = node.cparams + node.qparams
|
|
379
|
+
arg_types = [types.Float for _ in node.cparams] + [
|
|
380
|
+
QubitType for _ in node.qparams
|
|
381
|
+
]
|
|
382
|
+
|
|
383
|
+
with state.frame(
|
|
384
|
+
stmts=node.body,
|
|
385
|
+
finalize_next=False,
|
|
386
|
+
) as body_frame:
|
|
387
|
+
# NOTE: insert _self as arg
|
|
388
|
+
body_frame.curr_block.args.append_from(
|
|
389
|
+
types.Generic(
|
|
390
|
+
ir.Method, types.Tuple.where(tuple(arg_types)), types.NoneType
|
|
391
|
+
),
|
|
392
|
+
name=node.name + "_self",
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
for arg_type, arg_name in zip(arg_types, arg_names):
|
|
396
|
+
# NOTE: append args as block arguments
|
|
397
|
+
block_arg = body_frame.curr_block.args.append_from(
|
|
398
|
+
arg_type, name=arg_name
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
# NOTE: add arguments as definitions to frame
|
|
402
|
+
body_frame.defs[arg_name] = block_arg
|
|
403
|
+
|
|
404
|
+
body_frame.exhaust()
|
|
405
|
+
|
|
406
|
+
# NOTE: append none as return value
|
|
407
|
+
return_val = func.ConstantNone()
|
|
408
|
+
body_frame.push(return_val)
|
|
409
|
+
body_frame.push(func.Return(return_val))
|
|
410
|
+
|
|
411
|
+
body = body_frame.curr_region
|
|
412
|
+
|
|
413
|
+
gate_func = expr.GateFunction(
|
|
414
|
+
sym_name=node.name,
|
|
415
|
+
signature=func.Signature(inputs=tuple(arg_types), output=types.NoneType),
|
|
416
|
+
body=body,
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
mt = ir.Method(
|
|
420
|
+
mod=None,
|
|
421
|
+
py_func=None,
|
|
422
|
+
sym_name=node.name,
|
|
423
|
+
dialects=self.dialects,
|
|
424
|
+
arg_names=[*node.cparams, *node.qparams],
|
|
425
|
+
code=gate_func,
|
|
426
|
+
)
|
|
427
|
+
state.current_frame.globals[node.name] = mt
|
|
434
428
|
|
|
435
429
|
def visit_Instruction(self, state: lowering.State[ast.Node], node: ast.Instruction):
|
|
436
430
|
params = [state.lower(param).expect_one() for param in node.params]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from . import (
|
|
2
|
+
op as op,
|
|
3
|
+
wire as wire,
|
|
4
|
+
noise as noise,
|
|
5
|
+
qubit as qubit,
|
|
6
|
+
lowering as lowering,
|
|
7
|
+
)
|
|
8
|
+
from .groups import wired as wired, kernel as kernel
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
# NOTE: make sure optional cirq dependency is installed
|
|
12
|
+
import cirq as cirq_package # noqa: F401
|
|
13
|
+
except ImportError:
|
|
14
|
+
pass
|
|
15
|
+
else:
|
|
16
|
+
from . import cirq as cirq
|
|
17
|
+
from .cirq import load_circuit as load_circuit
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import cirq
|
|
4
|
+
from kirin import ir, types
|
|
5
|
+
from kirin.dialects import func
|
|
6
|
+
|
|
7
|
+
from . import lowering as lowering
|
|
8
|
+
from .. import kernel
|
|
9
|
+
from .lowering import Squin
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def load_circuit(
|
|
13
|
+
circuit: cirq.Circuit,
|
|
14
|
+
kernel_name: str = "main",
|
|
15
|
+
dialects: ir.DialectGroup = kernel,
|
|
16
|
+
globals: dict[str, Any] | None = None,
|
|
17
|
+
file: str | None = None,
|
|
18
|
+
lineno_offset: int = 0,
|
|
19
|
+
col_offset: int = 0,
|
|
20
|
+
compactify: bool = True,
|
|
21
|
+
):
|
|
22
|
+
"""Converts a cirq.Circuit object into a squin kernel.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
circuit (cirq.Circuit): The circuit to load.
|
|
26
|
+
|
|
27
|
+
Keyword Args:
|
|
28
|
+
kernel_name (str): The name of the kernel to load. Defaults to "main".
|
|
29
|
+
dialects (ir.DialectGroup | None): The dialects to use. Defaults to `squin.kernel`.
|
|
30
|
+
globals (dict[str, Any] | None): The global variables to use. Defaults to None.
|
|
31
|
+
file (str | None): The file name for error reporting. Defaults to None.
|
|
32
|
+
lineno_offset (int): The line number offset for error reporting. Defaults to 0.
|
|
33
|
+
col_offset (int): The column number offset for error reporting. Defaults to 0.
|
|
34
|
+
compactify (bool): Whether to compactify the output. Defaults to True.
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
# from cirq's "hello qubit" example
|
|
40
|
+
import cirq
|
|
41
|
+
from bloqade import squin
|
|
42
|
+
|
|
43
|
+
# Pick a qubit.
|
|
44
|
+
qubit = cirq.GridQubit(0, 0)
|
|
45
|
+
|
|
46
|
+
# Create a circuit.
|
|
47
|
+
circuit = cirq.Circuit(
|
|
48
|
+
cirq.X(qubit)**0.5, # Square root of NOT.
|
|
49
|
+
cirq.measure(qubit, key='m') # Measurement.
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# load the circuit as squin
|
|
53
|
+
main = squin.load_circuit(circuit)
|
|
54
|
+
|
|
55
|
+
# print the resulting IR
|
|
56
|
+
main.print()
|
|
57
|
+
```
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
target = Squin(dialects=dialects, circuit=circuit)
|
|
61
|
+
body = target.run(
|
|
62
|
+
circuit,
|
|
63
|
+
source=str(circuit), # TODO: proper source string
|
|
64
|
+
file=file,
|
|
65
|
+
globals=globals,
|
|
66
|
+
lineno_offset=lineno_offset,
|
|
67
|
+
col_offset=col_offset,
|
|
68
|
+
compactify=compactify,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# NOTE: no return value
|
|
72
|
+
return_value = func.ConstantNone()
|
|
73
|
+
body.blocks[0].stmts.append(return_value)
|
|
74
|
+
body.blocks[0].stmts.append(func.Return(value_or_stmt=return_value))
|
|
75
|
+
|
|
76
|
+
code = func.Function(
|
|
77
|
+
sym_name=kernel_name,
|
|
78
|
+
signature=func.Signature((), types.NoneType),
|
|
79
|
+
body=body,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
return ir.Method(
|
|
83
|
+
mod=None,
|
|
84
|
+
py_func=None,
|
|
85
|
+
sym_name=kernel_name,
|
|
86
|
+
arg_names=[],
|
|
87
|
+
dialects=dialects,
|
|
88
|
+
code=code,
|
|
89
|
+
)
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from typing import Any
|
|
3
|
+
from dataclasses import field, dataclass
|
|
4
|
+
|
|
5
|
+
import cirq
|
|
6
|
+
from kirin import ir, lowering
|
|
7
|
+
from kirin.rewrite import Walk, CFGCompactify
|
|
8
|
+
from kirin.dialects import py, ilist
|
|
9
|
+
|
|
10
|
+
from .. import op, noise, qubit
|
|
11
|
+
|
|
12
|
+
CirqNode = cirq.Circuit | cirq.Moment | cirq.Gate | cirq.Qid | cirq.Operation
|
|
13
|
+
|
|
14
|
+
DecomposeNode = (
|
|
15
|
+
cirq.SwapPowGate
|
|
16
|
+
| cirq.ISwapPowGate
|
|
17
|
+
| cirq.PhasedXPowGate
|
|
18
|
+
| cirq.PhasedXZGate
|
|
19
|
+
| cirq.CSwapGate
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class Squin(lowering.LoweringABC[CirqNode]):
|
|
25
|
+
"""Lower a cirq.Circuit object to a squin kernel"""
|
|
26
|
+
|
|
27
|
+
circuit: cirq.Circuit
|
|
28
|
+
qreg: qubit.New = field(init=False)
|
|
29
|
+
qreg_index: dict[cirq.Qid, int] = field(init=False, default_factory=dict)
|
|
30
|
+
next_qreg_index: int = field(init=False, default=0)
|
|
31
|
+
|
|
32
|
+
def lower_qubit_getindex(self, state: lowering.State[CirqNode], qid: cirq.Qid):
|
|
33
|
+
index = self.qreg_index.get(qid)
|
|
34
|
+
|
|
35
|
+
if index is None:
|
|
36
|
+
index = self.next_qreg_index
|
|
37
|
+
self.qreg_index[qid] = index
|
|
38
|
+
self.next_qreg_index += 1
|
|
39
|
+
|
|
40
|
+
index_ssa = state.current_frame.push(py.Constant(index)).result
|
|
41
|
+
qbit_getitem = state.current_frame.push(py.GetItem(self.qreg.result, index_ssa))
|
|
42
|
+
return qbit_getitem.result
|
|
43
|
+
|
|
44
|
+
def lower_qubit_getindices(
|
|
45
|
+
self, state: lowering.State[CirqNode], qids: list[cirq.Qid]
|
|
46
|
+
):
|
|
47
|
+
qbits_getitem = [self.lower_qubit_getindex(state, qid) for qid in qids]
|
|
48
|
+
qbits_stmt = ilist.New(values=qbits_getitem)
|
|
49
|
+
qbits_result = state.current_frame.get(qbits_stmt.name)
|
|
50
|
+
|
|
51
|
+
if qbits_result is not None:
|
|
52
|
+
return qbits_result
|
|
53
|
+
|
|
54
|
+
state.current_frame.push(qbits_stmt)
|
|
55
|
+
return qbits_stmt.result
|
|
56
|
+
|
|
57
|
+
def run(
|
|
58
|
+
self,
|
|
59
|
+
stmt: CirqNode,
|
|
60
|
+
*,
|
|
61
|
+
source: str | None = None,
|
|
62
|
+
globals: dict[str, Any] | None = None,
|
|
63
|
+
file: str | None = None,
|
|
64
|
+
lineno_offset: int = 0,
|
|
65
|
+
col_offset: int = 0,
|
|
66
|
+
compactify: bool = True,
|
|
67
|
+
) -> ir.Region:
|
|
68
|
+
|
|
69
|
+
state = lowering.State(
|
|
70
|
+
self,
|
|
71
|
+
file=file,
|
|
72
|
+
lineno_offset=lineno_offset,
|
|
73
|
+
col_offset=col_offset,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
with state.frame(
|
|
77
|
+
[stmt],
|
|
78
|
+
globals=globals,
|
|
79
|
+
finalize_next=False,
|
|
80
|
+
) as frame:
|
|
81
|
+
# NOTE: create a global register of qubits first
|
|
82
|
+
# TODO: can there be a circuit without qubits?
|
|
83
|
+
n_qubits = cirq.num_qubits(self.circuit)
|
|
84
|
+
n = frame.push(py.Constant(n_qubits))
|
|
85
|
+
self.qreg = frame.push(qubit.New(n_qubits=n.result))
|
|
86
|
+
|
|
87
|
+
self.visit(state, stmt)
|
|
88
|
+
|
|
89
|
+
if compactify:
|
|
90
|
+
Walk(CFGCompactify()).rewrite(frame.curr_region)
|
|
91
|
+
|
|
92
|
+
region = frame.curr_region
|
|
93
|
+
|
|
94
|
+
return region
|
|
95
|
+
|
|
96
|
+
def visit(self, state: lowering.State[CirqNode], node: CirqNode) -> lowering.Result:
|
|
97
|
+
name = node.__class__.__name__
|
|
98
|
+
return getattr(self, f"visit_{name}", self.generic_visit)(state, node)
|
|
99
|
+
|
|
100
|
+
def generic_visit(self, state: lowering.State[CirqNode], node: CirqNode):
|
|
101
|
+
if isinstance(node, CirqNode):
|
|
102
|
+
raise lowering.BuildError(
|
|
103
|
+
f"Cannot lower {node.__class__.__name__} node: {node}"
|
|
104
|
+
)
|
|
105
|
+
raise lowering.BuildError(
|
|
106
|
+
f"Unexpected `{node.__class__.__name__}` node: {repr(node)} is not an AST node"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def lower_literal(self, state: lowering.State[CirqNode], value) -> ir.SSAValue:
|
|
110
|
+
raise lowering.BuildError("Literals not supported in cirq circuit")
|
|
111
|
+
|
|
112
|
+
def lower_global(
|
|
113
|
+
self, state: lowering.State[CirqNode], node: CirqNode
|
|
114
|
+
) -> lowering.LoweringABC.Result:
|
|
115
|
+
raise lowering.BuildError("Literals not supported in cirq circuit")
|
|
116
|
+
|
|
117
|
+
def visit_Circuit(
|
|
118
|
+
self, state: lowering.State[CirqNode], node: cirq.Circuit
|
|
119
|
+
) -> lowering.Result:
|
|
120
|
+
for moment in node:
|
|
121
|
+
state.lower(moment)
|
|
122
|
+
|
|
123
|
+
def visit_Moment(
|
|
124
|
+
self, state: lowering.State[CirqNode], node: cirq.Moment
|
|
125
|
+
) -> lowering.Result:
|
|
126
|
+
for op_ in node.operations:
|
|
127
|
+
state.lower(op_)
|
|
128
|
+
|
|
129
|
+
def visit_GateOperation(
|
|
130
|
+
self, state: lowering.State[CirqNode], node: cirq.GateOperation
|
|
131
|
+
):
|
|
132
|
+
if isinstance(node.gate, cirq.MeasurementGate):
|
|
133
|
+
# NOTE: special dispatch here, since measurement is a gate + a qubit in cirq,
|
|
134
|
+
# but a single statement in squin
|
|
135
|
+
return self.lower_measurement(state, node)
|
|
136
|
+
|
|
137
|
+
if isinstance(node.gate, DecomposeNode):
|
|
138
|
+
# NOTE: easier to decompose these, but for that we need the qubits too,
|
|
139
|
+
# so we need to do this within this method
|
|
140
|
+
for subnode in cirq.decompose_once(node):
|
|
141
|
+
state.lower(subnode)
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
op_ = state.lower(node.gate).expect_one()
|
|
145
|
+
qbits = self.lower_qubit_getindices(state, node.qubits)
|
|
146
|
+
return state.current_frame.push(qubit.Apply(operator=op_, qubits=qbits))
|
|
147
|
+
|
|
148
|
+
def lower_measurement(
|
|
149
|
+
self, state: lowering.State[CirqNode], node: cirq.GateOperation
|
|
150
|
+
):
|
|
151
|
+
if len(node.qubits) == 1:
|
|
152
|
+
qbit = self.lower_qubit_getindex(state, node.qubits[0])
|
|
153
|
+
return state.current_frame.push(qubit.MeasureQubit(qbit))
|
|
154
|
+
|
|
155
|
+
qbits = self.lower_qubit_getindices(state, node.qubits)
|
|
156
|
+
return state.current_frame.push(qubit.MeasureQubitList(qbits))
|
|
157
|
+
|
|
158
|
+
def visit_SingleQubitPauliStringGateOperation(
|
|
159
|
+
self,
|
|
160
|
+
state: lowering.State[CirqNode],
|
|
161
|
+
node: cirq.SingleQubitPauliStringGateOperation,
|
|
162
|
+
):
|
|
163
|
+
|
|
164
|
+
match node.pauli:
|
|
165
|
+
case cirq.X:
|
|
166
|
+
op_ = op.stmts.X()
|
|
167
|
+
case cirq.Y:
|
|
168
|
+
op_ = op.stmts.Y()
|
|
169
|
+
case cirq.Z:
|
|
170
|
+
op_ = op.stmts.Z()
|
|
171
|
+
case cirq.I:
|
|
172
|
+
op_ = op.stmts.Identity(sites=1)
|
|
173
|
+
case _:
|
|
174
|
+
raise lowering.BuildError(f"Unexpected Pauli operation {node.pauli}")
|
|
175
|
+
|
|
176
|
+
state.current_frame.push(op_)
|
|
177
|
+
qargs = self.lower_qubit_getindices(state, [node.qubit])
|
|
178
|
+
return state.current_frame.push(qubit.Apply(op_.result, qargs))
|
|
179
|
+
|
|
180
|
+
def visit_HPowGate(self, state: lowering.State[CirqNode], node: cirq.HPowGate):
|
|
181
|
+
if node.exponent == 1:
|
|
182
|
+
return state.current_frame.push(op.stmts.H())
|
|
183
|
+
|
|
184
|
+
return state.lower(node.in_su2())
|
|
185
|
+
|
|
186
|
+
def visit_XPowGate(self, state: lowering.State[CirqNode], node: cirq.XPowGate):
|
|
187
|
+
if node.exponent == 1:
|
|
188
|
+
return state.current_frame.push(op.stmts.X())
|
|
189
|
+
|
|
190
|
+
return self.visit(state, node.in_su2())
|
|
191
|
+
|
|
192
|
+
def visit_YPowGate(self, state: lowering.State[CirqNode], node: cirq.YPowGate):
|
|
193
|
+
if node.exponent == 1:
|
|
194
|
+
return state.current_frame.push(op.stmts.Y())
|
|
195
|
+
|
|
196
|
+
return self.visit(state, node.in_su2())
|
|
197
|
+
|
|
198
|
+
def visit_ZPowGate(self, state: lowering.State[CirqNode], node: cirq.ZPowGate):
|
|
199
|
+
if node.exponent == 0.5:
|
|
200
|
+
return state.current_frame.push(op.stmts.S())
|
|
201
|
+
|
|
202
|
+
if node.exponent == 0.25:
|
|
203
|
+
return state.current_frame.push(op.stmts.T())
|
|
204
|
+
|
|
205
|
+
if node.exponent == 1:
|
|
206
|
+
return state.current_frame.push(op.stmts.Z())
|
|
207
|
+
|
|
208
|
+
# NOTE: just for the Z gate, an arbitrary exponent is equivalent to the ShiftOp
|
|
209
|
+
t = node.exponent
|
|
210
|
+
theta = state.current_frame.push(py.Constant(math.pi * t))
|
|
211
|
+
return state.current_frame.push(op.stmts.ShiftOp(theta=theta.result))
|
|
212
|
+
|
|
213
|
+
def visit_Rx(self, state: lowering.State[CirqNode], node: cirq.Rx):
|
|
214
|
+
x = state.current_frame.push(op.stmts.X())
|
|
215
|
+
angle = state.current_frame.push(py.Constant(value=math.pi * node.exponent))
|
|
216
|
+
return state.current_frame.push(op.stmts.Rot(axis=x.result, angle=angle.result))
|
|
217
|
+
|
|
218
|
+
def visit_Ry(self, state: lowering.State[CirqNode], node: cirq.Ry):
|
|
219
|
+
y = state.current_frame.push(op.stmts.Y())
|
|
220
|
+
angle = state.current_frame.push(py.Constant(value=math.pi * node.exponent))
|
|
221
|
+
return state.current_frame.push(op.stmts.Rot(axis=y.result, angle=angle.result))
|
|
222
|
+
|
|
223
|
+
def visit_Rz(self, state: lowering.State[CirqNode], node: cirq.Rz):
|
|
224
|
+
z = state.current_frame.push(op.stmts.Z())
|
|
225
|
+
angle = state.current_frame.push(py.Constant(value=math.pi * node.exponent))
|
|
226
|
+
return state.current_frame.push(op.stmts.Rot(axis=z.result, angle=angle.result))
|
|
227
|
+
|
|
228
|
+
def visit_CXPowGate(self, state: lowering.State[CirqNode], node: cirq.CXPowGate):
|
|
229
|
+
x = state.lower(cirq.XPowGate(exponent=node.exponent)).expect_one()
|
|
230
|
+
return state.current_frame.push(op.stmts.Control(x, n_controls=1))
|
|
231
|
+
|
|
232
|
+
def visit_CZPowGate(self, state: lowering.State[CirqNode], node: cirq.CZPowGate):
|
|
233
|
+
z = state.lower(cirq.ZPowGate(exponent=node.exponent)).expect_one()
|
|
234
|
+
return state.current_frame.push(op.stmts.Control(z, n_controls=1))
|
|
235
|
+
|
|
236
|
+
def visit_ControlledOperation(
|
|
237
|
+
self, state: lowering.State[CirqNode], node: cirq.ControlledOperation
|
|
238
|
+
):
|
|
239
|
+
return self.visit_GateOperation(state, node)
|
|
240
|
+
|
|
241
|
+
def visit_ControlledGate(
|
|
242
|
+
self, state: lowering.State[CirqNode], node: cirq.ControlledGate
|
|
243
|
+
):
|
|
244
|
+
op_ = state.lower(node.sub_gate).expect_one()
|
|
245
|
+
n_controls = node.num_controls()
|
|
246
|
+
return state.current_frame.push(op.stmts.Control(op_, n_controls=n_controls))
|
|
247
|
+
|
|
248
|
+
def visit_XXPowGate(self, state: lowering.State[CirqNode], node: cirq.XXPowGate):
|
|
249
|
+
x = state.lower(cirq.XPowGate(exponent=node.exponent)).expect_one()
|
|
250
|
+
return state.current_frame.push(op.stmts.Kron(x, x))
|
|
251
|
+
|
|
252
|
+
def visit_YYPowGate(self, state: lowering.State[CirqNode], node: cirq.YYPowGate):
|
|
253
|
+
y = state.lower(cirq.YPowGate(exponent=node.exponent)).expect_one()
|
|
254
|
+
return state.current_frame.push(op.stmts.Kron(y, y))
|
|
255
|
+
|
|
256
|
+
def visit_ZZPowGate(self, state: lowering.State[CirqNode], node: cirq.ZZPowGate):
|
|
257
|
+
z = state.lower(cirq.ZPowGate(exponent=node.exponent)).expect_one()
|
|
258
|
+
return state.current_frame.push(op.stmts.Kron(z, z))
|
|
259
|
+
|
|
260
|
+
def visit_CCXPowGate(self, state: lowering.State[CirqNode], node: cirq.CCXPowGate):
|
|
261
|
+
x = state.lower(cirq.XPowGate(exponent=node.exponent)).expect_one()
|
|
262
|
+
return state.current_frame.push(op.stmts.Control(x, n_controls=2))
|
|
263
|
+
|
|
264
|
+
def visit_CCZPowGate(self, state: lowering.State[CirqNode], node: cirq.CCZPowGate):
|
|
265
|
+
z = state.lower(cirq.ZPowGate(exponent=node.exponent)).expect_one()
|
|
266
|
+
return state.current_frame.push(op.stmts.Control(z, n_controls=2))
|
|
267
|
+
|
|
268
|
+
def visit_BitFlipChannel(
|
|
269
|
+
self, state: lowering.State[CirqNode], node: cirq.BitFlipChannel
|
|
270
|
+
):
|
|
271
|
+
x = state.current_frame.push(op.stmts.X())
|
|
272
|
+
p = state.current_frame.push(py.Constant(node.p))
|
|
273
|
+
return state.current_frame.push(
|
|
274
|
+
noise.stmts.PauliError(basis=x.result, p=p.result)
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
def visit_AmplitudeDampingChannel(
|
|
278
|
+
self, state: lowering.State[CirqNode], node: cirq.AmplitudeDampingChannel
|
|
279
|
+
):
|
|
280
|
+
r = state.current_frame.push(op.stmts.Reset())
|
|
281
|
+
p = state.current_frame.push(py.Constant(node.gamma))
|
|
282
|
+
|
|
283
|
+
# TODO: do we need a dedicated noise stmt for this? Using PauliError
|
|
284
|
+
# with this basis feels like a hack
|
|
285
|
+
noise_channel = state.current_frame.push(
|
|
286
|
+
noise.stmts.PauliError(basis=r.result, p=p.result)
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
return noise_channel
|
|
290
|
+
|
|
291
|
+
def visit_GeneralizedAmplitudeDampingChannel(
|
|
292
|
+
self,
|
|
293
|
+
state: lowering.State[CirqNode],
|
|
294
|
+
node: cirq.GeneralizedAmplitudeDampingChannel,
|
|
295
|
+
):
|
|
296
|
+
raise NotImplementedError("TODO: needs a new operator statement")
|
|
297
|
+
# p = state.current_frame.push(py.Constant(node.p))
|
|
298
|
+
# gamma = state.current_frame.push(py.Constant(node.gamma))
|
|
299
|
+
|
|
300
|
+
# p1 =
|
|
301
|
+
|
|
302
|
+
# x = state.current_frame.push(op.stmts.X())
|
|
303
|
+
# noise_channel1 = noise.stmts.PauliError(basis=x.result, p=)
|