bloqade-circuit 0.4.1__tar.gz → 0.4.3__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.1 → bloqade_circuit-0.4.3}/PKG-INFO +1 -1
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/pyproject.toml +1 -1
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/lowering.py +67 -73
- bloqade_circuit-0.4.3/src/bloqade/squin/cirq/__init__.py +200 -0
- bloqade_circuit-0.4.3/src/bloqade/squin/cirq/emit/emit_circuit.py +109 -0
- bloqade_circuit-0.4.3/src/bloqade/squin/cirq/emit/op.py +125 -0
- bloqade_circuit-0.4.3/src/bloqade/squin/cirq/emit/qubit.py +60 -0
- bloqade_circuit-0.4.3/src/bloqade/squin/cirq/emit/runtime.py +234 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/cirq/lowering.py +73 -4
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/squin/test_noise.py +1 -1
- bloqade_circuit-0.4.3/test/qasm2/test_lowering.py +165 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/squin/cirq/test_cirq_to_squin.py +56 -0
- bloqade_circuit-0.4.3/test/squin/cirq/test_squin_to_cirq.py +337 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/uv.lock +1 -1
- bloqade_circuit-0.4.1/src/bloqade/squin/cirq/__init__.py +0 -89
- bloqade_circuit-0.4.1/test/qasm2/test_lowering.py +0 -79
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/.github/dependabot.yml +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/.github/workflows/ci.yml +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/.github/workflows/isort.yml +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/.github/workflows/lint.yml +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/.github/workflows/release.yml +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/.gitignore +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/.pre-commit-config.yaml +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/LICENSE +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/README.md +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/_typos.toml +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/justfile +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/analysis/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/analysis/address/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/analysis/address/analysis.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/analysis/address/impls.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/analysis/address/lattice.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/analysis/fidelity/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/analysis/fidelity/analysis.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/device.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/base.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/device.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/noise/native.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/qasm2/core.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/qasm2/glob.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/qasm2/parallel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/qasm2/uop.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/reg.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/squin/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/squin/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/squin/noise/native.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/squin/op.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/squin/qubit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/squin/runtime.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/squin/wire.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/target.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/pyqrack/task.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/_qasm_loading.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/_wrappers.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/core/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/core/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/core/_emit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/core/_typeinfer.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/core/address.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/core/stmts.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/expr/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/expr/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/expr/_emit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/expr/_from_python.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/expr/_interp.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/expr/stmts.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/glob.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/indexing.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/inline.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/noise/fidelity.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/noise/model.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/parallel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/uop/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/uop/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/uop/_emit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/uop/schedule.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/dialects/uop/stmts.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/emit/base.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/emit/gate.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/emit/impls/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/emit/impls/noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/emit/main.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/emit/target.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/glob.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/groups.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parallel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/ast.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/build.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/parser.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/print.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/qasm2.lark +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/visitor.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/parse/visitor.pyi +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/fold.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/glob.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/lift_qubits.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/parallel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/py2qasm.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/qasm2py.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/passes/unroll_if.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/desugar.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/glob.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/insert_qubits.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/native_gates.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/noise/heuristic_noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/noise/remove_noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/parallel_to_uop.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/register.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/split_ifs.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/rewrite/uop_to_parallel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qasm2/types.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qbraid/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qbraid/lowering.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qbraid/schema.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qbraid/simulation_result.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/qbraid/target.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/analysis/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/analysis/nsites/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/analysis/nsites/analysis.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/analysis/nsites/impls.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/analysis/nsites/lattice.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/analysis/schedule.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/groups.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/lowering.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/noise/_wrapper.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/noise/rewrite.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/_wrapper.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/number.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/rewrite.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/stdlib.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/stmts.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/traits.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/op/types.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/passes/stim.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/qubit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/desugar.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/qubit_to_stim.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/squin_measure.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/stim_rewrite_util.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/wire_identity_elimination.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/wire_to_stim.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/rewrite/wrap_analysis.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/squin/wire.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/_wrappers.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/emit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/interp.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/lowering.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/stmts/annotate.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/stmts/const.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/auxiliary/types.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/collapse/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/collapse/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/collapse/emit_str.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/collapse/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/collapse/stmts/measure.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/collapse/stmts/pp_measure.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/collapse/stmts/reset.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/emit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/stmts/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/stmts/base.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/stmts/clifford_1q.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/stmts/clifford_2q.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/stmts/control_2q.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/gate/stmts/pp.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/noise/_dialect.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/noise/emit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/dialects/noise/stmts.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/emit/stim_str.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/groups.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/stim/parse/lowering.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/task.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/test_utils.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/types.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/animate.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/base.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/gate_event.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/runtime/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/runtime/aod.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/runtime/atoms.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/runtime/ppoly.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/runtime/qpustate.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/src/bloqade/visual/animation/runtime/utils.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/analysis/address/test_analysis.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/analysis/address/test_lattice.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/analysis/fidelity/test_fidelity.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/runtime/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/runtime/noise/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/runtime/noise/qasm2/test_loss.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/runtime/noise/qasm2/test_pauli.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/runtime/test_dyn_memory.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/runtime/test_qrack.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/squin/test_kernel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/pyqrack/test_target.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/analysis/test_dag.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/emit/test_extended.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/emit/test_extended_noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/emit/test_qasm2.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/emit/test_qasm2_emit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/invalid_programs/invalid_if.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/README.md +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/global.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/iqft1.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/main.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/noise.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/para.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/process_tomo.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/qelib1.inc +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/qft.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/qft2.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/rb.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/rep_code.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/ripple_carry_adder.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/tele.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/programs/valid_if.qasm +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/test_ast.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/parse/test_roundtrip.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/test_global_to_parallel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/test_global_to_uop.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/test_heuristic_noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/test_parallel_to_uop.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/test_qasm2py.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/test_unroll_if.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/passes/test_uop_to_parallel.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/test_count.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/test_inline.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/test_native.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qasm2/test_two2one.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qbraid/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qbraid/test_clean_circuit.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qbraid/test_lowering.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/qbraid/test_target.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/sample/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/sample/test_noise_model.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/squin/analysis/test_nsites_analysis.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/squin/op/test_reset.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/squin/stim/test_stim.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/squin/test_constprop.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/squin/test_mult_rewrite.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/squin/test_sugar.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/base.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_1q.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_ctrl.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_detector.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_meas.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_obs_inc.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_ppmeas.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_qubit_coords.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/emit/test_stim_spp.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/test_stim_circuits.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/dialects/stim/test_stim_const.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/base.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/test_parse.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/test_parse_clifford.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/test_parse_control.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/test_parse_custom.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/test_parse_noise.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/parse/test_parse_spp.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/wrapper/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/stim/wrapper/test_wrapper.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/test_serialization.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/test_zone_model.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/test/visual/__init__.py +0 -0
- {bloqade_circuit-0.4.1 → bloqade_circuit-0.4.3}/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.3
|
|
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
|
|
@@ -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,200 @@
|
|
|
1
|
+
from typing import Any, Sequence
|
|
2
|
+
|
|
3
|
+
import cirq
|
|
4
|
+
from kirin import ir, types
|
|
5
|
+
from kirin.emit import EmitError
|
|
6
|
+
from kirin.dialects import func
|
|
7
|
+
|
|
8
|
+
from . import lowering as lowering
|
|
9
|
+
from .. import kernel
|
|
10
|
+
|
|
11
|
+
# NOTE: just to register methods
|
|
12
|
+
from .emit import op as op, qubit as qubit
|
|
13
|
+
from .lowering import Squin
|
|
14
|
+
from .emit.emit_circuit import EmitCirq
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def load_circuit(
|
|
18
|
+
circuit: cirq.Circuit,
|
|
19
|
+
kernel_name: str = "main",
|
|
20
|
+
dialects: ir.DialectGroup = kernel,
|
|
21
|
+
globals: dict[str, Any] | None = None,
|
|
22
|
+
file: str | None = None,
|
|
23
|
+
lineno_offset: int = 0,
|
|
24
|
+
col_offset: int = 0,
|
|
25
|
+
compactify: bool = True,
|
|
26
|
+
):
|
|
27
|
+
"""Converts a cirq.Circuit object into a squin kernel.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
circuit (cirq.Circuit): The circuit to load.
|
|
31
|
+
|
|
32
|
+
Keyword Args:
|
|
33
|
+
kernel_name (str): The name of the kernel to load. Defaults to "main".
|
|
34
|
+
dialects (ir.DialectGroup | None): The dialects to use. Defaults to `squin.kernel`.
|
|
35
|
+
globals (dict[str, Any] | None): The global variables to use. Defaults to None.
|
|
36
|
+
file (str | None): The file name for error reporting. Defaults to None.
|
|
37
|
+
lineno_offset (int): The line number offset for error reporting. Defaults to 0.
|
|
38
|
+
col_offset (int): The column number offset for error reporting. Defaults to 0.
|
|
39
|
+
compactify (bool): Whether to compactify the output. Defaults to True.
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
# from cirq's "hello qubit" example
|
|
45
|
+
import cirq
|
|
46
|
+
from bloqade import squin
|
|
47
|
+
|
|
48
|
+
# Pick a qubit.
|
|
49
|
+
qubit = cirq.GridQubit(0, 0)
|
|
50
|
+
|
|
51
|
+
# Create a circuit.
|
|
52
|
+
circuit = cirq.Circuit(
|
|
53
|
+
cirq.X(qubit)**0.5, # Square root of NOT.
|
|
54
|
+
cirq.measure(qubit, key='m') # Measurement.
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# load the circuit as squin
|
|
58
|
+
main = squin.load_circuit(circuit)
|
|
59
|
+
|
|
60
|
+
# print the resulting IR
|
|
61
|
+
main.print()
|
|
62
|
+
```
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
target = Squin(dialects=dialects, circuit=circuit)
|
|
66
|
+
body = target.run(
|
|
67
|
+
circuit,
|
|
68
|
+
source=str(circuit), # TODO: proper source string
|
|
69
|
+
file=file,
|
|
70
|
+
globals=globals,
|
|
71
|
+
lineno_offset=lineno_offset,
|
|
72
|
+
col_offset=col_offset,
|
|
73
|
+
compactify=compactify,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# NOTE: no return value
|
|
77
|
+
return_value = func.ConstantNone()
|
|
78
|
+
body.blocks[0].stmts.append(return_value)
|
|
79
|
+
body.blocks[0].stmts.append(func.Return(value_or_stmt=return_value))
|
|
80
|
+
|
|
81
|
+
code = func.Function(
|
|
82
|
+
sym_name=kernel_name,
|
|
83
|
+
signature=func.Signature((), types.NoneType),
|
|
84
|
+
body=body,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return ir.Method(
|
|
88
|
+
mod=None,
|
|
89
|
+
py_func=None,
|
|
90
|
+
sym_name=kernel_name,
|
|
91
|
+
arg_names=[],
|
|
92
|
+
dialects=dialects,
|
|
93
|
+
code=code,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def emit_circuit(
|
|
98
|
+
mt: ir.Method,
|
|
99
|
+
qubits: Sequence[cirq.Qid] | None = None,
|
|
100
|
+
) -> cirq.Circuit:
|
|
101
|
+
"""Converts a squin.kernel method to a cirq.Circuit object.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
mt (ir.Method): The kernel method from which to construct the circuit.
|
|
105
|
+
|
|
106
|
+
Keyword Args:
|
|
107
|
+
qubits (Sequence[cirq.Qid] | None):
|
|
108
|
+
A list of qubits to use as the qubits in the circuit. Defaults to None.
|
|
109
|
+
If this is None, then `cirq.LineQubit`s are inserted for every `squin.qubit.new`
|
|
110
|
+
statement in the order they appear inside the kernel.
|
|
111
|
+
**Note**: If a list of qubits is provided, make sure that there is a sufficient
|
|
112
|
+
number of qubits for the resulting circuit.
|
|
113
|
+
|
|
114
|
+
## Examples:
|
|
115
|
+
|
|
116
|
+
Here's a very basic example:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from bloqade import squin
|
|
120
|
+
|
|
121
|
+
@squin.kernel
|
|
122
|
+
def main():
|
|
123
|
+
q = squin.qubit.new(2)
|
|
124
|
+
h = squin.op.h()
|
|
125
|
+
squin.qubit.apply(h, q[0])
|
|
126
|
+
cx = squin.op.cx()
|
|
127
|
+
squin.qubit.apply(cx, q)
|
|
128
|
+
|
|
129
|
+
circuit = squin.cirq.emit_circuit(main)
|
|
130
|
+
|
|
131
|
+
print(circuit)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
You can also compose multiple kernels. Those are emitted as subcircuits within the "main" circuit.
|
|
135
|
+
Subkernels can accept arguments and return a value.
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from bloqade import squin
|
|
139
|
+
from kirin.dialects import ilist
|
|
140
|
+
from typing import Literal
|
|
141
|
+
import cirq
|
|
142
|
+
|
|
143
|
+
@squin.kernel
|
|
144
|
+
def entangle(q: ilist.IList[squin.qubit.Qubit, Literal[2]]):
|
|
145
|
+
h = squin.op.h()
|
|
146
|
+
squin.qubit.apply(h, q[0])
|
|
147
|
+
cx = squin.op.cx()
|
|
148
|
+
squin.qubit.apply(cx, q)
|
|
149
|
+
return cx
|
|
150
|
+
|
|
151
|
+
@squin.kernel
|
|
152
|
+
def main():
|
|
153
|
+
q = squin.qubit.new(2)
|
|
154
|
+
cx = entangle(q)
|
|
155
|
+
q2 = squin.qubit.new(3)
|
|
156
|
+
squin.qubit.apply(cx, [q[1], q2[2]])
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# custom list of qubits on grid
|
|
160
|
+
qubits = [cirq.GridQubit(i, i+1) for i in range(5)]
|
|
161
|
+
|
|
162
|
+
circuit = squin.cirq.emit_circuit(main, qubits=qubits)
|
|
163
|
+
print(circuit)
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
We also passed in a custom list of qubits above. This allows you to provide a custom geometry
|
|
168
|
+
and manipulate the qubits in other circuits directly written in cirq as well.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
if isinstance(mt.code, func.Function) and not mt.code.signature.output.is_subseteq(
|
|
172
|
+
types.NoneType
|
|
173
|
+
):
|
|
174
|
+
raise EmitError(
|
|
175
|
+
"The method you are trying to convert to a circuit has a return value, but returning from a circuit is not supported."
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
emitter = EmitCirq(qubits=qubits)
|
|
179
|
+
return emitter.run(mt, args=())
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def dump_circuit(mt: ir.Method, qubits: Sequence[cirq.Qid] | None = None, **kwargs):
|
|
183
|
+
"""Converts a squin.kernel method to a cirq.Circuit object and dumps it as JSON.
|
|
184
|
+
|
|
185
|
+
This just runs `emit_circuit` and calls the `cirq.to_json` function to emit a JSON.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
mt (ir.Method): The kernel method from which to construct the circuit.
|
|
189
|
+
|
|
190
|
+
Keyword Args:
|
|
191
|
+
qubits (Sequence[cirq.Qid] | None):
|
|
192
|
+
A list of qubits to use as the qubits in the circuit. Defaults to None.
|
|
193
|
+
If this is None, then `cirq.LineQubit`s are inserted for every `squin.qubit.new`
|
|
194
|
+
statement in the order they appear inside the kernel.
|
|
195
|
+
**Note**: If a list of qubits is provided, make sure that there is a sufficient
|
|
196
|
+
number of qubits for the resulting circuit.
|
|
197
|
+
|
|
198
|
+
"""
|
|
199
|
+
circuit = emit_circuit(mt, qubits=qubits)
|
|
200
|
+
return cirq.to_json(circuit, **kwargs)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from typing import Sequence
|
|
2
|
+
from dataclasses import field, dataclass
|
|
3
|
+
|
|
4
|
+
import cirq
|
|
5
|
+
from kirin import ir
|
|
6
|
+
from kirin.emit import EmitABC, EmitError, EmitFrame
|
|
7
|
+
from kirin.interp import MethodTable, impl
|
|
8
|
+
from kirin.dialects import func
|
|
9
|
+
from typing_extensions import Self
|
|
10
|
+
|
|
11
|
+
from ... import kernel
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class EmitCirqFrame(EmitFrame):
|
|
16
|
+
qubit_index: int = 0
|
|
17
|
+
qubits: Sequence[cirq.Qid] | None = None
|
|
18
|
+
circuit: cirq.Circuit = field(default_factory=cirq.Circuit)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _default_kernel():
|
|
22
|
+
return kernel
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class EmitCirq(EmitABC[EmitCirqFrame, cirq.Circuit]):
|
|
27
|
+
keys = ["emit.cirq", "main"]
|
|
28
|
+
dialects: ir.DialectGroup = field(default_factory=_default_kernel)
|
|
29
|
+
void = cirq.Circuit()
|
|
30
|
+
qubits: Sequence[cirq.Qid] | None = None
|
|
31
|
+
_cached_circuit_operations: dict[int, cirq.CircuitOperation] = field(
|
|
32
|
+
init=False, default_factory=dict
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def initialize(self) -> Self:
|
|
36
|
+
return super().initialize()
|
|
37
|
+
|
|
38
|
+
def initialize_frame(
|
|
39
|
+
self, code: ir.Statement, *, has_parent_access: bool = False
|
|
40
|
+
) -> EmitCirqFrame:
|
|
41
|
+
return EmitCirqFrame(
|
|
42
|
+
code, has_parent_access=has_parent_access, qubits=self.qubits
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def run_method(self, method: ir.Method, args: tuple[cirq.Circuit, ...]):
|
|
46
|
+
return self.run_callable(method.code, args)
|
|
47
|
+
|
|
48
|
+
def emit_block(self, frame: EmitCirqFrame, block: ir.Block) -> cirq.Circuit:
|
|
49
|
+
for stmt in block.stmts:
|
|
50
|
+
result = self.eval_stmt(frame, stmt)
|
|
51
|
+
if isinstance(result, tuple):
|
|
52
|
+
frame.set_values(stmt.results, result)
|
|
53
|
+
|
|
54
|
+
return frame.circuit
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@func.dialect.register(key="emit.cirq")
|
|
58
|
+
class FuncEmit(MethodTable):
|
|
59
|
+
|
|
60
|
+
@impl(func.Function)
|
|
61
|
+
def emit_func(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: func.Function):
|
|
62
|
+
emit.run_ssacfg_region(frame, stmt.body, ())
|
|
63
|
+
return (frame.circuit,)
|
|
64
|
+
|
|
65
|
+
@impl(func.Invoke)
|
|
66
|
+
def emit_invoke(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: func.Invoke):
|
|
67
|
+
stmt_hash = hash((stmt.callee, stmt.inputs))
|
|
68
|
+
if (
|
|
69
|
+
cached_circuit_op := emit._cached_circuit_operations.get(stmt_hash)
|
|
70
|
+
) is not None:
|
|
71
|
+
# NOTE: cache hit
|
|
72
|
+
frame.circuit.append(cached_circuit_op)
|
|
73
|
+
return ()
|
|
74
|
+
|
|
75
|
+
ret = stmt.result
|
|
76
|
+
|
|
77
|
+
with emit.new_frame(stmt.callee.code, has_parent_access=True) as sub_frame:
|
|
78
|
+
sub_frame.qubit_index = frame.qubit_index
|
|
79
|
+
sub_frame.qubits = frame.qubits
|
|
80
|
+
|
|
81
|
+
region = stmt.callee.callable_region
|
|
82
|
+
if len(region.blocks) > 1:
|
|
83
|
+
raise EmitError(
|
|
84
|
+
"Subroutine with more than a single block encountered. This is not supported!"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# NOTE: get the arguments, "self" is just an empty circuit
|
|
88
|
+
method_self = emit.void
|
|
89
|
+
args = [frame.get(arg_) for arg_ in stmt.inputs]
|
|
90
|
+
emit.run_ssacfg_region(
|
|
91
|
+
sub_frame, stmt.callee.callable_region, args=(method_self, *args)
|
|
92
|
+
)
|
|
93
|
+
sub_circuit = sub_frame.circuit
|
|
94
|
+
|
|
95
|
+
# NOTE: check to see if the call terminates with a return value and fetch the value;
|
|
96
|
+
# we don't support multiple return statements via control flow so we just pick the first one
|
|
97
|
+
block = region.blocks[0]
|
|
98
|
+
return_stmt = next(
|
|
99
|
+
(stmt for stmt in block.stmts if isinstance(stmt, func.Return)), None
|
|
100
|
+
)
|
|
101
|
+
if return_stmt is not None:
|
|
102
|
+
frame.entries[ret] = sub_frame.get(return_stmt.value)
|
|
103
|
+
|
|
104
|
+
circuit_op = cirq.CircuitOperation(
|
|
105
|
+
sub_circuit.freeze(), use_repetition_ids=False
|
|
106
|
+
)
|
|
107
|
+
emit._cached_circuit_operations[stmt_hash] = circuit_op
|
|
108
|
+
frame.circuit.append(circuit_op)
|
|
109
|
+
return ()
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import cirq
|
|
4
|
+
import numpy as np
|
|
5
|
+
from kirin.interp import MethodTable, impl
|
|
6
|
+
|
|
7
|
+
from ... import op
|
|
8
|
+
from .runtime import (
|
|
9
|
+
SnRuntime,
|
|
10
|
+
SpRuntime,
|
|
11
|
+
U3Runtime,
|
|
12
|
+
KronRuntime,
|
|
13
|
+
MultRuntime,
|
|
14
|
+
ScaleRuntime,
|
|
15
|
+
AdjointRuntime,
|
|
16
|
+
ControlRuntime,
|
|
17
|
+
UnitaryRuntime,
|
|
18
|
+
HermitianRuntime,
|
|
19
|
+
ProjectorRuntime,
|
|
20
|
+
OperatorRuntimeABC,
|
|
21
|
+
PauliStringRuntime,
|
|
22
|
+
)
|
|
23
|
+
from .emit_circuit import EmitCirq, EmitCirqFrame
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@op.dialect.register(key="emit.cirq")
|
|
27
|
+
class EmitCirqOpMethods(MethodTable):
|
|
28
|
+
|
|
29
|
+
@impl(op.stmts.X)
|
|
30
|
+
@impl(op.stmts.Y)
|
|
31
|
+
@impl(op.stmts.Z)
|
|
32
|
+
@impl(op.stmts.H)
|
|
33
|
+
def hermitian(
|
|
34
|
+
self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.ConstantUnitary
|
|
35
|
+
):
|
|
36
|
+
cirq_op = getattr(cirq, stmt.name.upper())
|
|
37
|
+
return (HermitianRuntime(cirq_op),)
|
|
38
|
+
|
|
39
|
+
@impl(op.stmts.S)
|
|
40
|
+
@impl(op.stmts.T)
|
|
41
|
+
def unitary(
|
|
42
|
+
self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.ConstantUnitary
|
|
43
|
+
):
|
|
44
|
+
cirq_op = getattr(cirq, stmt.name.upper())
|
|
45
|
+
return (UnitaryRuntime(cirq_op),)
|
|
46
|
+
|
|
47
|
+
@impl(op.stmts.P0)
|
|
48
|
+
@impl(op.stmts.P1)
|
|
49
|
+
def projector(
|
|
50
|
+
self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.P0 | op.stmts.P1
|
|
51
|
+
):
|
|
52
|
+
return (ProjectorRuntime(isinstance(stmt, op.stmts.P1)),)
|
|
53
|
+
|
|
54
|
+
@impl(op.stmts.Sn)
|
|
55
|
+
def sn(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Sn):
|
|
56
|
+
return (SnRuntime(),)
|
|
57
|
+
|
|
58
|
+
@impl(op.stmts.Sp)
|
|
59
|
+
def sp(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Sp):
|
|
60
|
+
return (SpRuntime(),)
|
|
61
|
+
|
|
62
|
+
@impl(op.stmts.Identity)
|
|
63
|
+
def identity(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Identity):
|
|
64
|
+
op = HermitianRuntime(cirq.IdentityGate(num_qubits=stmt.sites))
|
|
65
|
+
return (op,)
|
|
66
|
+
|
|
67
|
+
@impl(op.stmts.Control)
|
|
68
|
+
def control(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Control):
|
|
69
|
+
op: OperatorRuntimeABC = frame.get(stmt.op)
|
|
70
|
+
return (ControlRuntime(op, stmt.n_controls),)
|
|
71
|
+
|
|
72
|
+
@impl(op.stmts.Kron)
|
|
73
|
+
def kron(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Kron):
|
|
74
|
+
lhs = frame.get(stmt.lhs)
|
|
75
|
+
rhs = frame.get(stmt.rhs)
|
|
76
|
+
op = KronRuntime(lhs, rhs)
|
|
77
|
+
return (op,)
|
|
78
|
+
|
|
79
|
+
@impl(op.stmts.Mult)
|
|
80
|
+
def mult(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Mult):
|
|
81
|
+
lhs = frame.get(stmt.lhs)
|
|
82
|
+
rhs = frame.get(stmt.rhs)
|
|
83
|
+
op = MultRuntime(lhs, rhs)
|
|
84
|
+
return (op,)
|
|
85
|
+
|
|
86
|
+
@impl(op.stmts.Adjoint)
|
|
87
|
+
def adjoint(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Adjoint):
|
|
88
|
+
op_ = frame.get(stmt.op)
|
|
89
|
+
return (AdjointRuntime(op_),)
|
|
90
|
+
|
|
91
|
+
@impl(op.stmts.Scale)
|
|
92
|
+
def scale(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Scale):
|
|
93
|
+
op_ = frame.get(stmt.op)
|
|
94
|
+
factor = frame.get(stmt.factor)
|
|
95
|
+
return (ScaleRuntime(operator=op_, factor=factor),)
|
|
96
|
+
|
|
97
|
+
@impl(op.stmts.U3)
|
|
98
|
+
def u3(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.U3):
|
|
99
|
+
theta = frame.get(stmt.theta)
|
|
100
|
+
phi = frame.get(stmt.phi)
|
|
101
|
+
lam = frame.get(stmt.lam)
|
|
102
|
+
return (U3Runtime(theta=theta, phi=phi, lam=lam),)
|
|
103
|
+
|
|
104
|
+
@impl(op.stmts.PhaseOp)
|
|
105
|
+
def phaseop(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.PhaseOp):
|
|
106
|
+
theta = frame.get(stmt.theta)
|
|
107
|
+
op_ = HermitianRuntime(cirq.IdentityGate(num_qubits=1))
|
|
108
|
+
return (ScaleRuntime(operator=op_, factor=np.exp(1j * theta)),)
|
|
109
|
+
|
|
110
|
+
@impl(op.stmts.ShiftOp)
|
|
111
|
+
def shiftop(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.ShiftOp):
|
|
112
|
+
theta = frame.get(stmt.theta)
|
|
113
|
+
|
|
114
|
+
# NOTE: ShiftOp(theta) == U3(pi, theta, 0)
|
|
115
|
+
return (U3Runtime(math.pi, theta, 0),)
|
|
116
|
+
|
|
117
|
+
@impl(op.stmts.Reset)
|
|
118
|
+
def reset(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.Reset):
|
|
119
|
+
return (HermitianRuntime(cirq.ResetChannel()),)
|
|
120
|
+
|
|
121
|
+
@impl(op.stmts.PauliString)
|
|
122
|
+
def pauli_string(
|
|
123
|
+
self, emit: EmitCirq, frame: EmitCirqFrame, stmt: op.stmts.PauliString
|
|
124
|
+
):
|
|
125
|
+
return (PauliStringRuntime(stmt.string),)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import cirq
|
|
2
|
+
from kirin.interp import MethodTable, impl
|
|
3
|
+
|
|
4
|
+
from ... import qubit
|
|
5
|
+
from .op import OperatorRuntimeABC
|
|
6
|
+
from .emit_circuit import EmitCirq, EmitCirqFrame
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@qubit.dialect.register(key="emit.cirq")
|
|
10
|
+
class EmitCirqQubitMethods(MethodTable):
|
|
11
|
+
@impl(qubit.New)
|
|
12
|
+
def new(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.New):
|
|
13
|
+
n_qubits = frame.get(stmt.n_qubits)
|
|
14
|
+
|
|
15
|
+
if frame.qubits is not None:
|
|
16
|
+
cirq_qubits = [frame.qubits[i + frame.qubit_index] for i in range(n_qubits)]
|
|
17
|
+
else:
|
|
18
|
+
cirq_qubits = [
|
|
19
|
+
cirq.LineQubit(i + frame.qubit_index) for i in range(n_qubits)
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
frame.qubit_index += n_qubits
|
|
23
|
+
return (cirq_qubits,)
|
|
24
|
+
|
|
25
|
+
@impl(qubit.Apply)
|
|
26
|
+
def apply(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.Apply):
|
|
27
|
+
op: OperatorRuntimeABC = frame.get(stmt.operator)
|
|
28
|
+
qbits = frame.get(stmt.qubits)
|
|
29
|
+
operations = op.apply(qbits)
|
|
30
|
+
for operation in operations:
|
|
31
|
+
frame.circuit.append(operation)
|
|
32
|
+
return ()
|
|
33
|
+
|
|
34
|
+
@impl(qubit.Broadcast)
|
|
35
|
+
def broadcast(self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.Broadcast):
|
|
36
|
+
op = frame.get(stmt.operator)
|
|
37
|
+
qbits = frame.get(stmt.qubits)
|
|
38
|
+
|
|
39
|
+
cirq_ops = []
|
|
40
|
+
for qbit in qbits:
|
|
41
|
+
cirq_ops.extend(op.apply([qbit]))
|
|
42
|
+
|
|
43
|
+
frame.circuit.append(cirq.Moment(cirq_ops))
|
|
44
|
+
return ()
|
|
45
|
+
|
|
46
|
+
@impl(qubit.MeasureQubit)
|
|
47
|
+
def measure_qubit(
|
|
48
|
+
self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.MeasureQubit
|
|
49
|
+
):
|
|
50
|
+
qbit = frame.get(stmt.qubit)
|
|
51
|
+
frame.circuit.append(cirq.measure(qbit))
|
|
52
|
+
return ()
|
|
53
|
+
|
|
54
|
+
@impl(qubit.MeasureQubitList)
|
|
55
|
+
def measure_qubit_list(
|
|
56
|
+
self, emit: EmitCirq, frame: EmitCirqFrame, stmt: qubit.MeasureQubitList
|
|
57
|
+
):
|
|
58
|
+
qbits = frame.get(stmt.qubits)
|
|
59
|
+
frame.circuit.append(cirq.measure(qbits))
|
|
60
|
+
return ()
|