qiskit 2.0.3__cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -0
- qiskit/__init__.py +141 -0
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/circuit/__init__.py +1343 -0
- qiskit/circuit/_add_control.py +312 -0
- qiskit/circuit/_classical_resource_map.py +150 -0
- qiskit/circuit/_standard_gates_commutations.py +3849 -0
- qiskit/circuit/_utils.py +167 -0
- qiskit/circuit/annotated_operation.py +279 -0
- qiskit/circuit/barrier.py +46 -0
- qiskit/circuit/classical/__init__.py +41 -0
- qiskit/circuit/classical/expr/__init__.py +266 -0
- qiskit/circuit/classical/expr/constructors.py +764 -0
- qiskit/circuit/classical/expr/expr.py +498 -0
- qiskit/circuit/classical/expr/visitors.py +375 -0
- qiskit/circuit/classical/types/__init__.py +113 -0
- qiskit/circuit/classical/types/ordering.py +229 -0
- qiskit/circuit/classical/types/types.py +153 -0
- qiskit/circuit/commutation_checker.py +133 -0
- qiskit/circuit/commutation_library.py +20 -0
- qiskit/circuit/controlflow/__init__.py +59 -0
- qiskit/circuit/controlflow/_builder_utils.py +211 -0
- qiskit/circuit/controlflow/box.py +163 -0
- qiskit/circuit/controlflow/break_loop.py +56 -0
- qiskit/circuit/controlflow/builder.py +791 -0
- qiskit/circuit/controlflow/continue_loop.py +56 -0
- qiskit/circuit/controlflow/control_flow.py +94 -0
- qiskit/circuit/controlflow/for_loop.py +218 -0
- qiskit/circuit/controlflow/if_else.py +498 -0
- qiskit/circuit/controlflow/switch_case.py +411 -0
- qiskit/circuit/controlflow/while_loop.py +166 -0
- qiskit/circuit/controlledgate.py +274 -0
- qiskit/circuit/delay.py +157 -0
- qiskit/circuit/duration.py +80 -0
- qiskit/circuit/equivalence.py +94 -0
- qiskit/circuit/equivalence_library.py +18 -0
- qiskit/circuit/exceptions.py +19 -0
- qiskit/circuit/gate.py +261 -0
- qiskit/circuit/instruction.py +564 -0
- qiskit/circuit/instructionset.py +132 -0
- qiskit/circuit/library/__init__.py +984 -0
- qiskit/circuit/library/arithmetic/__init__.py +40 -0
- qiskit/circuit/library/arithmetic/adders/__init__.py +18 -0
- qiskit/circuit/library/arithmetic/adders/adder.py +235 -0
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +123 -0
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +129 -0
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +95 -0
- qiskit/circuit/library/arithmetic/exact_reciprocal.py +131 -0
- qiskit/circuit/library/arithmetic/functional_pauli_rotations.py +114 -0
- qiskit/circuit/library/arithmetic/integer_comparator.py +200 -0
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +363 -0
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +243 -0
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +17 -0
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +145 -0
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +201 -0
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +108 -0
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +502 -0
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +387 -0
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +493 -0
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +389 -0
- qiskit/circuit/library/arithmetic/quadratic_form.py +364 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +409 -0
- qiskit/circuit/library/basis_change/__init__.py +15 -0
- qiskit/circuit/library/basis_change/qft.py +316 -0
- qiskit/circuit/library/bit_flip_oracle.py +130 -0
- qiskit/circuit/library/blueprintcircuit.py +316 -0
- qiskit/circuit/library/boolean_logic/__init__.py +18 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +157 -0
- qiskit/circuit/library/boolean_logic/quantum_and.py +204 -0
- qiskit/circuit/library/boolean_logic/quantum_or.py +206 -0
- qiskit/circuit/library/boolean_logic/quantum_xor.py +167 -0
- qiskit/circuit/library/data_preparation/__init__.py +57 -0
- qiskit/circuit/library/data_preparation/_z_feature_map.py +115 -0
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
- qiskit/circuit/library/data_preparation/initializer.py +107 -0
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +656 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +336 -0
- qiskit/circuit/library/fourier_checking.py +160 -0
- qiskit/circuit/library/generalized_gates/__init__.py +30 -0
- qiskit/circuit/library/generalized_gates/diagonal.py +159 -0
- qiskit/circuit/library/generalized_gates/gms.py +175 -0
- qiskit/circuit/library/generalized_gates/gr.py +219 -0
- qiskit/circuit/library/generalized_gates/isometry.py +370 -0
- qiskit/circuit/library/generalized_gates/linear_function.py +318 -0
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +143 -0
- qiskit/circuit/library/generalized_gates/mcmt.py +316 -0
- qiskit/circuit/library/generalized_gates/pauli.py +84 -0
- qiskit/circuit/library/generalized_gates/permutation.py +198 -0
- qiskit/circuit/library/generalized_gates/rv.py +96 -0
- qiskit/circuit/library/generalized_gates/uc.py +303 -0
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +164 -0
- qiskit/circuit/library/generalized_gates/ucrx.py +32 -0
- qiskit/circuit/library/generalized_gates/ucry.py +32 -0
- qiskit/circuit/library/generalized_gates/ucrz.py +32 -0
- qiskit/circuit/library/generalized_gates/unitary.py +217 -0
- qiskit/circuit/library/graph_state.py +172 -0
- qiskit/circuit/library/grover_operator.py +583 -0
- qiskit/circuit/library/hamiltonian_gate.py +142 -0
- qiskit/circuit/library/hidden_linear_function.py +163 -0
- qiskit/circuit/library/iqp.py +180 -0
- qiskit/circuit/library/n_local/__init__.py +45 -0
- qiskit/circuit/library/n_local/efficient_su2.py +282 -0
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +520 -0
- qiskit/circuit/library/n_local/excitation_preserving.py +303 -0
- qiskit/circuit/library/n_local/n_local.py +1477 -0
- qiskit/circuit/library/n_local/pauli_two_design.py +246 -0
- qiskit/circuit/library/n_local/qaoa_ansatz.py +367 -0
- qiskit/circuit/library/n_local/real_amplitudes.py +312 -0
- qiskit/circuit/library/n_local/two_local.py +289 -0
- qiskit/circuit/library/overlap.py +183 -0
- qiskit/circuit/library/pauli_evolution.py +201 -0
- qiskit/circuit/library/phase_estimation.py +177 -0
- qiskit/circuit/library/phase_oracle.py +239 -0
- qiskit/circuit/library/quantum_volume.py +180 -0
- qiskit/circuit/library/standard_gates/__init__.py +141 -0
- qiskit/circuit/library/standard_gates/dcx.py +77 -0
- qiskit/circuit/library/standard_gates/ecr.py +129 -0
- qiskit/circuit/library/standard_gates/equivalence_library.py +1800 -0
- qiskit/circuit/library/standard_gates/global_phase.py +84 -0
- qiskit/circuit/library/standard_gates/h.py +253 -0
- qiskit/circuit/library/standard_gates/i.py +76 -0
- qiskit/circuit/library/standard_gates/iswap.py +133 -0
- qiskit/circuit/library/standard_gates/p.py +422 -0
- qiskit/circuit/library/standard_gates/r.py +114 -0
- qiskit/circuit/library/standard_gates/rx.py +293 -0
- qiskit/circuit/library/standard_gates/rxx.py +180 -0
- qiskit/circuit/library/standard_gates/ry.py +286 -0
- qiskit/circuit/library/standard_gates/ryy.py +180 -0
- qiskit/circuit/library/standard_gates/rz.py +307 -0
- qiskit/circuit/library/standard_gates/rzx.py +226 -0
- qiskit/circuit/library/standard_gates/rzz.py +193 -0
- qiskit/circuit/library/standard_gates/s.py +419 -0
- qiskit/circuit/library/standard_gates/swap.py +281 -0
- qiskit/circuit/library/standard_gates/sx.py +310 -0
- qiskit/circuit/library/standard_gates/t.py +178 -0
- qiskit/circuit/library/standard_gates/u.py +395 -0
- qiskit/circuit/library/standard_gates/u1.py +490 -0
- qiskit/circuit/library/standard_gates/u2.py +145 -0
- qiskit/circuit/library/standard_gates/u3.py +428 -0
- qiskit/circuit/library/standard_gates/x.py +1481 -0
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +202 -0
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +236 -0
- qiskit/circuit/library/standard_gates/y.py +257 -0
- qiskit/circuit/library/standard_gates/z.py +338 -0
- qiskit/circuit/library/templates/__init__.py +92 -0
- qiskit/circuit/library/templates/clifford/__init__.py +33 -0
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +41 -0
- qiskit/circuit/library/templates/nct/__init__.py +67 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +34 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +35 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +37 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +45 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +44 -0
- qiskit/circuit/library/templates/rzx/__init__.py +25 -0
- qiskit/circuit/library/templates/rzx/rzx_cy.py +47 -0
- qiskit/circuit/library/templates/rzx/rzx_xz.py +54 -0
- qiskit/circuit/library/templates/rzx/rzx_yz.py +45 -0
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +69 -0
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +59 -0
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +59 -0
- qiskit/circuit/measure.py +53 -0
- qiskit/circuit/operation.py +68 -0
- qiskit/circuit/parameter.py +179 -0
- qiskit/circuit/parameterexpression.py +703 -0
- qiskit/circuit/parametertable.py +119 -0
- qiskit/circuit/parametervector.py +140 -0
- qiskit/circuit/quantumcircuit.py +7540 -0
- qiskit/circuit/quantumcircuitdata.py +136 -0
- qiskit/circuit/random/__init__.py +15 -0
- qiskit/circuit/random/utils.py +366 -0
- qiskit/circuit/reset.py +37 -0
- qiskit/circuit/singleton.py +600 -0
- qiskit/circuit/store.py +89 -0
- qiskit/circuit/tools/__init__.py +16 -0
- qiskit/circuit/tools/pi_check.py +193 -0
- qiskit/circuit/twirling.py +145 -0
- qiskit/compiler/__init__.py +27 -0
- qiskit/compiler/transpiler.py +375 -0
- qiskit/converters/__init__.py +74 -0
- qiskit/converters/circuit_to_dag.py +80 -0
- qiskit/converters/circuit_to_dagdependency.py +49 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +46 -0
- qiskit/converters/circuit_to_gate.py +107 -0
- qiskit/converters/circuit_to_instruction.py +142 -0
- qiskit/converters/dag_to_circuit.py +79 -0
- qiskit/converters/dag_to_dagdependency.py +54 -0
- qiskit/converters/dag_to_dagdependency_v2.py +43 -0
- qiskit/converters/dagdependency_to_circuit.py +40 -0
- qiskit/converters/dagdependency_to_dag.py +48 -0
- qiskit/dagcircuit/__init__.py +55 -0
- qiskit/dagcircuit/collect_blocks.py +407 -0
- qiskit/dagcircuit/dagcircuit.py +24 -0
- qiskit/dagcircuit/dagdependency.py +612 -0
- qiskit/dagcircuit/dagdependency_v2.py +566 -0
- qiskit/dagcircuit/dagdepnode.py +160 -0
- qiskit/dagcircuit/dagnode.py +188 -0
- qiskit/dagcircuit/exceptions.py +42 -0
- qiskit/exceptions.py +153 -0
- qiskit/passmanager/__init__.py +258 -0
- qiskit/passmanager/base_tasks.py +230 -0
- qiskit/passmanager/compilation_status.py +74 -0
- qiskit/passmanager/exceptions.py +19 -0
- qiskit/passmanager/flow_controllers.py +116 -0
- qiskit/passmanager/passmanager.py +353 -0
- qiskit/primitives/__init__.py +490 -0
- qiskit/primitives/backend_estimator_v2.py +530 -0
- qiskit/primitives/backend_sampler_v2.py +339 -0
- qiskit/primitives/base/__init__.py +20 -0
- qiskit/primitives/base/base_estimator.py +247 -0
- qiskit/primitives/base/base_primitive_job.py +78 -0
- qiskit/primitives/base/base_primitive_v1.py +45 -0
- qiskit/primitives/base/base_result_v1.py +65 -0
- qiskit/primitives/base/base_sampler.py +196 -0
- qiskit/primitives/base/estimator_result_v1.py +46 -0
- qiskit/primitives/base/sampler_result_v1.py +45 -0
- qiskit/primitives/base/validation_v1.py +250 -0
- qiskit/primitives/containers/__init__.py +26 -0
- qiskit/primitives/containers/bindings_array.py +391 -0
- qiskit/primitives/containers/bit_array.py +764 -0
- qiskit/primitives/containers/data_bin.py +175 -0
- qiskit/primitives/containers/estimator_pub.py +222 -0
- qiskit/primitives/containers/object_array.py +94 -0
- qiskit/primitives/containers/observables_array.py +296 -0
- qiskit/primitives/containers/primitive_result.py +53 -0
- qiskit/primitives/containers/pub_result.py +51 -0
- qiskit/primitives/containers/sampler_pub.py +193 -0
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +129 -0
- qiskit/primitives/primitive_job.py +81 -0
- qiskit/primitives/statevector_estimator.py +175 -0
- qiskit/primitives/statevector_sampler.py +290 -0
- qiskit/primitives/utils.py +72 -0
- qiskit/providers/__init__.py +677 -0
- qiskit/providers/backend.py +364 -0
- qiskit/providers/basic_provider/__init__.py +47 -0
- qiskit/providers/basic_provider/basic_provider.py +121 -0
- qiskit/providers/basic_provider/basic_provider_job.py +65 -0
- qiskit/providers/basic_provider/basic_provider_tools.py +218 -0
- qiskit/providers/basic_provider/basic_simulator.py +693 -0
- qiskit/providers/basic_provider/exceptions.py +30 -0
- qiskit/providers/exceptions.py +33 -0
- qiskit/providers/fake_provider/__init__.py +69 -0
- qiskit/providers/fake_provider/generic_backend_v2.py +374 -0
- qiskit/providers/fake_provider/utils/__init__.py +15 -0
- qiskit/providers/job.py +147 -0
- qiskit/providers/jobstatus.py +30 -0
- qiskit/providers/options.py +273 -0
- qiskit/providers/providerutils.py +110 -0
- qiskit/qasm/libs/dummy/stdgates.inc +75 -0
- qiskit/qasm/libs/qelib1.inc +266 -0
- qiskit/qasm/libs/stdgates.inc +82 -0
- qiskit/qasm2/__init__.py +669 -0
- qiskit/qasm2/exceptions.py +27 -0
- qiskit/qasm2/export.py +364 -0
- qiskit/qasm2/parse.py +438 -0
- qiskit/qasm3/__init__.py +372 -0
- qiskit/qasm3/ast.py +782 -0
- qiskit/qasm3/exceptions.py +27 -0
- qiskit/qasm3/experimental.py +70 -0
- qiskit/qasm3/exporter.py +1340 -0
- qiskit/qasm3/printer.py +608 -0
- qiskit/qpy/__init__.py +1965 -0
- qiskit/qpy/binary_io/__init__.py +35 -0
- qiskit/qpy/binary_io/circuits.py +1455 -0
- qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
- qiskit/qpy/binary_io/schedules.py +308 -0
- qiskit/qpy/binary_io/value.py +1165 -0
- qiskit/qpy/common.py +353 -0
- qiskit/qpy/exceptions.py +53 -0
- qiskit/qpy/formats.py +442 -0
- qiskit/qpy/interface.py +344 -0
- qiskit/qpy/type_keys.py +409 -0
- qiskit/quantum_info/__init__.py +162 -0
- qiskit/quantum_info/analysis/__init__.py +17 -0
- qiskit/quantum_info/analysis/average.py +47 -0
- qiskit/quantum_info/analysis/distance.py +104 -0
- qiskit/quantum_info/analysis/make_observable.py +44 -0
- qiskit/quantum_info/analysis/z2_symmetries.py +484 -0
- qiskit/quantum_info/operators/__init__.py +28 -0
- qiskit/quantum_info/operators/base_operator.py +145 -0
- qiskit/quantum_info/operators/channel/__init__.py +29 -0
- qiskit/quantum_info/operators/channel/chi.py +191 -0
- qiskit/quantum_info/operators/channel/choi.py +218 -0
- qiskit/quantum_info/operators/channel/kraus.py +337 -0
- qiskit/quantum_info/operators/channel/ptm.py +204 -0
- qiskit/quantum_info/operators/channel/quantum_channel.py +348 -0
- qiskit/quantum_info/operators/channel/stinespring.py +296 -0
- qiskit/quantum_info/operators/channel/superop.py +373 -0
- qiskit/quantum_info/operators/channel/transformations.py +490 -0
- qiskit/quantum_info/operators/custom_iterator.py +48 -0
- qiskit/quantum_info/operators/dihedral/__init__.py +18 -0
- qiskit/quantum_info/operators/dihedral/dihedral.py +511 -0
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +216 -0
- qiskit/quantum_info/operators/dihedral/polynomial.py +313 -0
- qiskit/quantum_info/operators/dihedral/random.py +64 -0
- qiskit/quantum_info/operators/linear_op.py +25 -0
- qiskit/quantum_info/operators/measures.py +418 -0
- qiskit/quantum_info/operators/mixins/__init__.py +52 -0
- qiskit/quantum_info/operators/mixins/adjoint.py +52 -0
- qiskit/quantum_info/operators/mixins/group.py +171 -0
- qiskit/quantum_info/operators/mixins/linear.py +84 -0
- qiskit/quantum_info/operators/mixins/multiply.py +62 -0
- qiskit/quantum_info/operators/mixins/tolerances.py +72 -0
- qiskit/quantum_info/operators/op_shape.py +525 -0
- qiskit/quantum_info/operators/operator.py +869 -0
- qiskit/quantum_info/operators/operator_utils.py +76 -0
- qiskit/quantum_info/operators/predicates.py +183 -0
- qiskit/quantum_info/operators/random.py +154 -0
- qiskit/quantum_info/operators/scalar_op.py +254 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +23 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +719 -0
- qiskit/quantum_info/operators/symplectic/clifford.py +1032 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +558 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +755 -0
- qiskit/quantum_info/operators/symplectic/pauli_list.py +1242 -0
- qiskit/quantum_info/operators/symplectic/pauli_utils.py +40 -0
- qiskit/quantum_info/operators/symplectic/random.py +117 -0
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1239 -0
- qiskit/quantum_info/operators/utils/__init__.py +20 -0
- qiskit/quantum_info/operators/utils/anti_commutator.py +36 -0
- qiskit/quantum_info/operators/utils/commutator.py +36 -0
- qiskit/quantum_info/operators/utils/double_commutator.py +76 -0
- qiskit/quantum_info/quaternion.py +156 -0
- qiskit/quantum_info/random.py +26 -0
- qiskit/quantum_info/states/__init__.py +28 -0
- qiskit/quantum_info/states/densitymatrix.py +857 -0
- qiskit/quantum_info/states/measures.py +288 -0
- qiskit/quantum_info/states/quantum_state.py +503 -0
- qiskit/quantum_info/states/random.py +157 -0
- qiskit/quantum_info/states/stabilizerstate.py +805 -0
- qiskit/quantum_info/states/statevector.py +977 -0
- qiskit/quantum_info/states/utils.py +247 -0
- qiskit/result/__init__.py +61 -0
- qiskit/result/counts.py +189 -0
- qiskit/result/distributions/__init__.py +17 -0
- qiskit/result/distributions/probability.py +100 -0
- qiskit/result/distributions/quasi.py +154 -0
- qiskit/result/exceptions.py +40 -0
- qiskit/result/models.py +241 -0
- qiskit/result/postprocess.py +239 -0
- qiskit/result/result.py +385 -0
- qiskit/result/sampled_expval.py +74 -0
- qiskit/result/utils.py +294 -0
- qiskit/synthesis/__init__.py +240 -0
- qiskit/synthesis/arithmetic/__init__.py +18 -0
- qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
- qiskit/synthesis/arithmetic/comparators/__init__.py +16 -0
- qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
- qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
- qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +103 -0
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +100 -0
- qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
- qiskit/synthesis/boolean/__init__.py +13 -0
- qiskit/synthesis/boolean/boolean_expression.py +231 -0
- qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
- qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
- qiskit/synthesis/clifford/__init__.py +19 -0
- qiskit/synthesis/clifford/clifford_decompose_ag.py +178 -0
- qiskit/synthesis/clifford/clifford_decompose_bm.py +46 -0
- qiskit/synthesis/clifford/clifford_decompose_full.py +64 -0
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +58 -0
- qiskit/synthesis/clifford/clifford_decompose_layers.py +447 -0
- qiskit/synthesis/cnotdihedral/__init__.py +17 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +52 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +141 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_two_qubits.py +266 -0
- qiskit/synthesis/discrete_basis/__init__.py +16 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +265 -0
- qiskit/synthesis/discrete_basis/gate_sequence.py +421 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +165 -0
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +240 -0
- qiskit/synthesis/evolution/__init__.py +21 -0
- qiskit/synthesis/evolution/evolution_synthesis.py +48 -0
- qiskit/synthesis/evolution/lie_trotter.py +120 -0
- qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
- qiskit/synthesis/evolution/pauli_network.py +80 -0
- qiskit/synthesis/evolution/product_formula.py +313 -0
- qiskit/synthesis/evolution/qdrift.py +130 -0
- qiskit/synthesis/evolution/suzuki_trotter.py +224 -0
- qiskit/synthesis/linear/__init__.py +26 -0
- qiskit/synthesis/linear/cnot_synth.py +69 -0
- qiskit/synthesis/linear/linear_circuits_utils.py +128 -0
- qiskit/synthesis/linear/linear_depth_lnn.py +61 -0
- qiskit/synthesis/linear/linear_matrix_utils.py +27 -0
- qiskit/synthesis/linear_phase/__init__.py +17 -0
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +206 -0
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +61 -0
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +58 -0
- qiskit/synthesis/multi_controlled/__init__.py +25 -0
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +359 -0
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
- qiskit/synthesis/one_qubit/__init__.py +15 -0
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +288 -0
- qiskit/synthesis/permutation/__init__.py +18 -0
- qiskit/synthesis/permutation/permutation_full.py +78 -0
- qiskit/synthesis/permutation/permutation_lnn.py +54 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +93 -0
- qiskit/synthesis/permutation/permutation_utils.py +16 -0
- qiskit/synthesis/qft/__init__.py +16 -0
- qiskit/synthesis/qft/qft_decompose_full.py +97 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +79 -0
- qiskit/synthesis/stabilizer/__init__.py +16 -0
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +149 -0
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +194 -0
- qiskit/synthesis/two_qubit/__init__.py +20 -0
- qiskit/synthesis/two_qubit/local_invariance.py +63 -0
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +583 -0
- qiskit/synthesis/two_qubit/xx_decompose/__init__.py +19 -0
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +300 -0
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +324 -0
- qiskit/synthesis/two_qubit/xx_decompose/embodiments.py +163 -0
- qiskit/synthesis/two_qubit/xx_decompose/paths.py +412 -0
- qiskit/synthesis/two_qubit/xx_decompose/polytopes.py +262 -0
- qiskit/synthesis/two_qubit/xx_decompose/utilities.py +40 -0
- qiskit/synthesis/two_qubit/xx_decompose/weyl.py +133 -0
- qiskit/synthesis/unitary/__init__.py +13 -0
- qiskit/synthesis/unitary/aqc/__init__.py +177 -0
- qiskit/synthesis/unitary/aqc/approximate.py +116 -0
- qiskit/synthesis/unitary/aqc/aqc.py +175 -0
- qiskit/synthesis/unitary/aqc/cnot_structures.py +300 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_circuit.py +103 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_objective.py +299 -0
- qiskit/synthesis/unitary/aqc/elementary_operations.py +108 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/__init__.py +164 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_grad_utils.py +237 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +226 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/layer.py +370 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/pmatrix.py +312 -0
- qiskit/synthesis/unitary/qsd.py +288 -0
- qiskit/transpiler/__init__.py +1345 -0
- qiskit/transpiler/basepasses.py +190 -0
- qiskit/transpiler/coupling.py +500 -0
- qiskit/transpiler/exceptions.py +59 -0
- qiskit/transpiler/instruction_durations.py +281 -0
- qiskit/transpiler/layout.py +740 -0
- qiskit/transpiler/passes/__init__.py +276 -0
- qiskit/transpiler/passes/analysis/__init__.py +23 -0
- qiskit/transpiler/passes/analysis/count_ops.py +30 -0
- qiskit/transpiler/passes/analysis/count_ops_longest_path.py +26 -0
- qiskit/transpiler/passes/analysis/dag_longest_path.py +24 -0
- qiskit/transpiler/passes/analysis/depth.py +33 -0
- qiskit/transpiler/passes/analysis/num_qubits.py +26 -0
- qiskit/transpiler/passes/analysis/num_tensor_factors.py +26 -0
- qiskit/transpiler/passes/analysis/resource_estimation.py +41 -0
- qiskit/transpiler/passes/analysis/size.py +36 -0
- qiskit/transpiler/passes/analysis/width.py +27 -0
- qiskit/transpiler/passes/basis/__init__.py +19 -0
- qiskit/transpiler/passes/basis/basis_translator.py +138 -0
- qiskit/transpiler/passes/basis/decompose.py +137 -0
- qiskit/transpiler/passes/basis/translate_parameterized.py +175 -0
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +84 -0
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +110 -0
- qiskit/transpiler/passes/layout/__init__.py +26 -0
- qiskit/transpiler/passes/layout/_csp_custom_solver.py +65 -0
- qiskit/transpiler/passes/layout/apply_layout.py +128 -0
- qiskit/transpiler/passes/layout/csp_layout.py +132 -0
- qiskit/transpiler/passes/layout/dense_layout.py +177 -0
- qiskit/transpiler/passes/layout/disjoint_utils.py +219 -0
- qiskit/transpiler/passes/layout/enlarge_with_ancilla.py +49 -0
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +116 -0
- qiskit/transpiler/passes/layout/layout_2q_distance.py +77 -0
- qiskit/transpiler/passes/layout/sabre_layout.py +506 -0
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +225 -0
- qiskit/transpiler/passes/layout/set_layout.py +69 -0
- qiskit/transpiler/passes/layout/trivial_layout.py +66 -0
- qiskit/transpiler/passes/layout/vf2_layout.py +256 -0
- qiskit/transpiler/passes/layout/vf2_post_layout.py +376 -0
- qiskit/transpiler/passes/layout/vf2_utils.py +235 -0
- qiskit/transpiler/passes/optimization/__init__.py +42 -0
- qiskit/transpiler/passes/optimization/_gate_extension.py +80 -0
- qiskit/transpiler/passes/optimization/collect_1q_runs.py +31 -0
- qiskit/transpiler/passes/optimization/collect_2q_blocks.py +35 -0
- qiskit/transpiler/passes/optimization/collect_and_collapse.py +117 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +109 -0
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +85 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +242 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +44 -0
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +82 -0
- qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +140 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +176 -0
- qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +91 -0
- qiskit/transpiler/passes/optimization/hoare_opt.py +420 -0
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +95 -0
- qiskit/transpiler/passes/optimization/light_cone.py +135 -0
- qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +267 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +250 -0
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +384 -0
- qiskit/transpiler/passes/optimization/optimize_annotated.py +449 -0
- qiskit/transpiler/passes/optimization/optimize_cliffords.py +89 -0
- qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +71 -0
- qiskit/transpiler/passes/optimization/remove_diagonal_gates_before_measure.py +41 -0
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +70 -0
- qiskit/transpiler/passes/optimization/remove_reset_in_zero_state.py +37 -0
- qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +50 -0
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +63 -0
- qiskit/transpiler/passes/optimization/template_matching/__init__.py +19 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +749 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +452 -0
- qiskit/transpiler/passes/optimization/template_matching/maximal_matches.py +77 -0
- qiskit/transpiler/passes/optimization/template_matching/template_matching.py +370 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +639 -0
- qiskit/transpiler/passes/optimization/template_optimization.py +158 -0
- qiskit/transpiler/passes/routing/__init__.py +21 -0
- qiskit/transpiler/passes/routing/algorithms/__init__.py +33 -0
- qiskit/transpiler/passes/routing/algorithms/token_swapper.py +105 -0
- qiskit/transpiler/passes/routing/algorithms/types.py +46 -0
- qiskit/transpiler/passes/routing/algorithms/util.py +103 -0
- qiskit/transpiler/passes/routing/basic_swap.py +166 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/__init__.py +25 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_block.py +60 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +397 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +145 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +306 -0
- qiskit/transpiler/passes/routing/layout_transformation.py +119 -0
- qiskit/transpiler/passes/routing/lookahead_swap.py +390 -0
- qiskit/transpiler/passes/routing/sabre_swap.py +463 -0
- qiskit/transpiler/passes/routing/star_prerouting.py +408 -0
- qiskit/transpiler/passes/routing/utils.py +35 -0
- qiskit/transpiler/passes/scheduling/__init__.py +21 -0
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +79 -0
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +70 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +251 -0
- qiskit/transpiler/passes/scheduling/padding/__init__.py +16 -0
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +284 -0
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +415 -0
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +90 -0
- qiskit/transpiler/passes/scheduling/scheduling/__init__.py +17 -0
- qiskit/transpiler/passes/scheduling/scheduling/alap.py +93 -0
- qiskit/transpiler/passes/scheduling/scheduling/asap.py +100 -0
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +88 -0
- qiskit/transpiler/passes/scheduling/scheduling/set_io_latency.py +64 -0
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +237 -0
- qiskit/transpiler/passes/synthesis/__init__.py +20 -0
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +153 -0
- qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +429 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +1963 -0
- qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py +41 -0
- qiskit/transpiler/passes/synthesis/plugin.py +738 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +313 -0
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +425 -0
- qiskit/transpiler/passes/utils/__init__.py +32 -0
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +41 -0
- qiskit/transpiler/passes/utils/check_gate_direction.py +60 -0
- qiskit/transpiler/passes/utils/check_map.py +78 -0
- qiskit/transpiler/passes/utils/contains_instruction.py +45 -0
- qiskit/transpiler/passes/utils/control_flow.py +61 -0
- qiskit/transpiler/passes/utils/dag_fixed_point.py +36 -0
- qiskit/transpiler/passes/utils/error.py +69 -0
- qiskit/transpiler/passes/utils/filter_op_nodes.py +66 -0
- qiskit/transpiler/passes/utils/fixed_point.py +48 -0
- qiskit/transpiler/passes/utils/gate_direction.py +93 -0
- qiskit/transpiler/passes/utils/gates_basis.py +51 -0
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +163 -0
- qiskit/transpiler/passes/utils/minimum_point.py +118 -0
- qiskit/transpiler/passes/utils/remove_barriers.py +50 -0
- qiskit/transpiler/passes/utils/remove_final_measurements.py +121 -0
- qiskit/transpiler/passes/utils/unroll_forloops.py +81 -0
- qiskit/transpiler/passmanager.py +503 -0
- qiskit/transpiler/passmanager_config.py +151 -0
- qiskit/transpiler/preset_passmanagers/__init__.py +93 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +993 -0
- qiskit/transpiler/preset_passmanagers/common.py +672 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +437 -0
- qiskit/transpiler/preset_passmanagers/level0.py +104 -0
- qiskit/transpiler/preset_passmanagers/level1.py +108 -0
- qiskit/transpiler/preset_passmanagers/level2.py +109 -0
- qiskit/transpiler/preset_passmanagers/level3.py +110 -0
- qiskit/transpiler/preset_passmanagers/plugin.py +346 -0
- qiskit/transpiler/target.py +905 -0
- qiskit/transpiler/timing_constraints.py +59 -0
- qiskit/user_config.py +266 -0
- qiskit/utils/__init__.py +90 -0
- qiskit/utils/classtools.py +146 -0
- qiskit/utils/deprecation.py +382 -0
- qiskit/utils/lazy_tester.py +363 -0
- qiskit/utils/optionals.py +354 -0
- qiskit/utils/parallel.py +318 -0
- qiskit/utils/units.py +146 -0
- qiskit/version.py +84 -0
- qiskit/visualization/__init__.py +290 -0
- qiskit/visualization/array.py +207 -0
- qiskit/visualization/bloch.py +778 -0
- qiskit/visualization/circuit/__init__.py +15 -0
- qiskit/visualization/circuit/_utils.py +675 -0
- qiskit/visualization/circuit/circuit_visualization.py +735 -0
- qiskit/visualization/circuit/latex.py +661 -0
- qiskit/visualization/circuit/matplotlib.py +2019 -0
- qiskit/visualization/circuit/qcstyle.py +278 -0
- qiskit/visualization/circuit/styles/__init__.py +13 -0
- qiskit/visualization/circuit/styles/bw.json +202 -0
- qiskit/visualization/circuit/styles/clifford.json +202 -0
- qiskit/visualization/circuit/styles/iqp-dark.json +214 -0
- qiskit/visualization/circuit/styles/iqp.json +214 -0
- qiskit/visualization/circuit/styles/textbook.json +202 -0
- qiskit/visualization/circuit/text.py +1849 -0
- qiskit/visualization/circuit_visualization.py +19 -0
- qiskit/visualization/counts_visualization.py +487 -0
- qiskit/visualization/dag_visualization.py +318 -0
- qiskit/visualization/exceptions.py +21 -0
- qiskit/visualization/gate_map.py +1424 -0
- qiskit/visualization/library.py +40 -0
- qiskit/visualization/pass_manager_visualization.py +312 -0
- qiskit/visualization/state_visualization.py +1546 -0
- qiskit/visualization/timeline/__init__.py +21 -0
- qiskit/visualization/timeline/core.py +495 -0
- qiskit/visualization/timeline/drawings.py +260 -0
- qiskit/visualization/timeline/generators.py +506 -0
- qiskit/visualization/timeline/interface.py +444 -0
- qiskit/visualization/timeline/layouts.py +115 -0
- qiskit/visualization/timeline/plotters/__init__.py +16 -0
- qiskit/visualization/timeline/plotters/base_plotter.py +58 -0
- qiskit/visualization/timeline/plotters/matplotlib.py +195 -0
- qiskit/visualization/timeline/stylesheet.py +301 -0
- qiskit/visualization/timeline/types.py +148 -0
- qiskit/visualization/transition_visualization.py +369 -0
- qiskit/visualization/utils.py +49 -0
- qiskit-2.0.3.dist-info/METADATA +220 -0
- qiskit-2.0.3.dist-info/RECORD +690 -0
- qiskit-2.0.3.dist-info/WHEEL +6 -0
- qiskit-2.0.3.dist-info/entry_points.txt +82 -0
- qiskit-2.0.3.dist-info/licenses/LICENSE.txt +203 -0
- qiskit-2.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,791 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Builder types for the basic control-flow constructs."""
|
14
|
+
|
15
|
+
# This file is in circuit.controlflow rather than the root of circuit because the constructs here
|
16
|
+
# are only intended to be localized to constructing the control flow instructions. We anticipate
|
17
|
+
# having a far more complete builder of all circuits, with more classical control and creation, in
|
18
|
+
# the future.
|
19
|
+
|
20
|
+
from __future__ import annotations
|
21
|
+
|
22
|
+
import abc
|
23
|
+
import itertools
|
24
|
+
import typing
|
25
|
+
from typing import Collection, Iterable, FrozenSet, Tuple, Union, Optional, Sequence
|
26
|
+
|
27
|
+
from qiskit._accelerate.circuit import CircuitData
|
28
|
+
from qiskit.circuit import Register
|
29
|
+
from qiskit.circuit.classical import expr
|
30
|
+
from qiskit.circuit import Clbit, ClassicalRegister
|
31
|
+
from qiskit.circuit.exceptions import CircuitError
|
32
|
+
from qiskit.circuit.instruction import Instruction
|
33
|
+
from qiskit.circuit.quantumcircuitdata import CircuitInstruction
|
34
|
+
from qiskit.circuit import Qubit, QuantumRegister
|
35
|
+
|
36
|
+
from ._builder_utils import condition_resources, node_resources
|
37
|
+
|
38
|
+
if typing.TYPE_CHECKING:
|
39
|
+
import qiskit
|
40
|
+
|
41
|
+
|
42
|
+
class CircuitScopeInterface(abc.ABC):
|
43
|
+
"""An interface that circuits and builder blocks explicitly fulfill, which contains the primitive
|
44
|
+
methods of circuit construction and object validation.
|
45
|
+
|
46
|
+
This allows core circuit methods to be applied to the currently open builder scope, and allows
|
47
|
+
the builders to hook into all places where circuit resources might be used. This allows the
|
48
|
+
builders to track the resources being used, without getting in the way of
|
49
|
+
:class:`.QuantumCircuit` doing its own thing.
|
50
|
+
"""
|
51
|
+
|
52
|
+
__slots__ = ()
|
53
|
+
|
54
|
+
@property
|
55
|
+
@abc.abstractmethod
|
56
|
+
def instructions(self) -> Sequence[CircuitInstruction]:
|
57
|
+
"""Indexable view onto the :class:`.CircuitInstruction`s backing this scope."""
|
58
|
+
|
59
|
+
@abc.abstractmethod
|
60
|
+
def append(
|
61
|
+
self, instruction: CircuitInstruction, *, _standard_gate=False
|
62
|
+
) -> CircuitInstruction:
|
63
|
+
"""Low-level 'append' primitive; this may assume that the qubits, clbits and operation are
|
64
|
+
all valid for the circuit.
|
65
|
+
|
66
|
+
Abstraction of :meth:`.QuantumCircuit._append` (the low-level one, not the high-level).
|
67
|
+
|
68
|
+
Args:
|
69
|
+
instruction: the resource-validated instruction context object.
|
70
|
+
|
71
|
+
Returns:
|
72
|
+
the instruction context object actually appended. This is not required to be the same
|
73
|
+
as the object given (but typically will be).
|
74
|
+
"""
|
75
|
+
|
76
|
+
@abc.abstractmethod
|
77
|
+
def extend(self, data: CircuitData):
|
78
|
+
"""Appends all instructions from ``data`` to the scope.
|
79
|
+
|
80
|
+
Args:
|
81
|
+
data: The instruction listing.
|
82
|
+
"""
|
83
|
+
|
84
|
+
@abc.abstractmethod
|
85
|
+
def resolve_classical_resource(
|
86
|
+
self, specifier: Clbit | ClassicalRegister | int
|
87
|
+
) -> Clbit | ClassicalRegister:
|
88
|
+
"""Resolve a single bit-like classical-resource specifier.
|
89
|
+
|
90
|
+
A resource refers to either a classical bit or a register, where integers index into the
|
91
|
+
classical bits of the greater circuit.
|
92
|
+
|
93
|
+
This is called whenever a classical bit or register is being used outside the standard
|
94
|
+
:class:`.Clbit` usage of instructions in :meth:`append`, such as in a legacy two-tuple
|
95
|
+
condition.
|
96
|
+
|
97
|
+
Args:
|
98
|
+
specifier: the classical resource specifier.
|
99
|
+
|
100
|
+
Returns:
|
101
|
+
the resolved resource. This cannot be an integer any more; an integer input is resolved
|
102
|
+
into a classical bit.
|
103
|
+
|
104
|
+
Raises:
|
105
|
+
CircuitError: if the resource cannot be used by the scope, such as an out-of-range index
|
106
|
+
or a :class:`.Clbit` that isn't actually in the circuit.
|
107
|
+
"""
|
108
|
+
|
109
|
+
@abc.abstractmethod
|
110
|
+
def add_uninitialized_var(self, var: expr.Var):
|
111
|
+
"""Add an uninitialized variable to the circuit scope.
|
112
|
+
|
113
|
+
The general circuit context is responsible for ensuring the variable is initialized. These
|
114
|
+
uninitialized variables are guaranteed to be standalone.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
var: the variable to add, if valid.
|
118
|
+
|
119
|
+
Raises:
|
120
|
+
CircuitError: if the variable cannot be added, such as because it invalidly shadows or
|
121
|
+
redefines an existing name.
|
122
|
+
"""
|
123
|
+
|
124
|
+
@abc.abstractmethod
|
125
|
+
def add_stretch(self, stretch: expr.Stretch):
|
126
|
+
"""Add a stretch to the circuit scope.
|
127
|
+
|
128
|
+
Args:
|
129
|
+
stretch: the stretch to add, if valid.
|
130
|
+
|
131
|
+
Raises:
|
132
|
+
CircuitError: if the stretch cannot be added, such as because it invalidly shadows or
|
133
|
+
redefines an existing name.
|
134
|
+
"""
|
135
|
+
|
136
|
+
@abc.abstractmethod
|
137
|
+
def remove_var(self, var: expr.Var):
|
138
|
+
"""Remove a variable from the locals of this scope.
|
139
|
+
|
140
|
+
This is only called in the case that an exception occurred while initializing the variable,
|
141
|
+
and is not exposed to users.
|
142
|
+
|
143
|
+
Args:
|
144
|
+
var: the variable to remove. It can be assumed that this was already the subject of an
|
145
|
+
:meth:`add_uninitialized_var` call.
|
146
|
+
"""
|
147
|
+
|
148
|
+
@abc.abstractmethod
|
149
|
+
def remove_stretch(self, stretch: expr.Stretch):
|
150
|
+
"""Remove a stretch from the locals of this scope.
|
151
|
+
|
152
|
+
This is only called in the case that an exception occurred while initializing the stretch,
|
153
|
+
and is not exposed to users.
|
154
|
+
|
155
|
+
Args:
|
156
|
+
stretch: the stretch to remove. It can be assumed that this was already the subject of an
|
157
|
+
:meth:`add_stretch` call.
|
158
|
+
"""
|
159
|
+
|
160
|
+
@abc.abstractmethod
|
161
|
+
def use_var(self, var: expr.Var):
|
162
|
+
"""Called for every standalone classical real-time variable being used by some circuit
|
163
|
+
instruction.
|
164
|
+
|
165
|
+
The given variable is guaranteed to be a stand-alone variable; bit-like resource-wrapping
|
166
|
+
variables will have been filtered out and their resources given to
|
167
|
+
:meth:`resolve_classical_resource`.
|
168
|
+
|
169
|
+
Args:
|
170
|
+
var: the variable to validate.
|
171
|
+
|
172
|
+
Raises:
|
173
|
+
CircuitError: if the variable is not valid for this scope.
|
174
|
+
"""
|
175
|
+
|
176
|
+
@abc.abstractmethod
|
177
|
+
def use_stretch(self, stretch: expr.Stretch):
|
178
|
+
"""Called for every stretch being used by some circuit instruction.
|
179
|
+
|
180
|
+
Args:
|
181
|
+
stretch: the stretch to validate.
|
182
|
+
|
183
|
+
Raises:
|
184
|
+
CircuitError: if the stretch is not valid for this scope.
|
185
|
+
"""
|
186
|
+
|
187
|
+
@abc.abstractmethod
|
188
|
+
def get_var(self, name: str) -> Optional[expr.Var]:
|
189
|
+
"""Get the variable (if any) in scope with the given name.
|
190
|
+
|
191
|
+
This should call up to the parent scope if in a control-flow builder scope, in case the
|
192
|
+
variable exists in an outer scope.
|
193
|
+
|
194
|
+
Args:
|
195
|
+
name: the name of the symbol to lookup.
|
196
|
+
|
197
|
+
Returns:
|
198
|
+
the variable if it is found, otherwise ``None``.
|
199
|
+
"""
|
200
|
+
|
201
|
+
@abc.abstractmethod
|
202
|
+
def get_stretch(self, name: str) -> Optional[expr.Stretch]:
|
203
|
+
"""Get the stretch (if any) in scope with the given name.
|
204
|
+
|
205
|
+
This should call up to the parent scope if in a control-flow builder scope, in case the
|
206
|
+
stretch exists in an outer scope.
|
207
|
+
|
208
|
+
Args:
|
209
|
+
name: the name of the symbol to lookup.
|
210
|
+
|
211
|
+
Returns:
|
212
|
+
the stretch if it is found, otherwise ``None``.
|
213
|
+
"""
|
214
|
+
|
215
|
+
@abc.abstractmethod
|
216
|
+
def use_qubit(self, qubit: Qubit):
|
217
|
+
"""Called to mark that a :class:`~.circuit.Qubit` should be considered "used" by this scope,
|
218
|
+
without appending an explicit instruction.
|
219
|
+
|
220
|
+
The subclass may assume that the ``qubit`` is valid for the root scope."""
|
221
|
+
|
222
|
+
|
223
|
+
class InstructionResources(typing.NamedTuple):
|
224
|
+
"""The quantum and classical resources used within a particular instruction.
|
225
|
+
|
226
|
+
.. warning::
|
227
|
+
|
228
|
+
This is an internal interface and no part of it should be relied upon outside of Qiskit
|
229
|
+
Terra.
|
230
|
+
|
231
|
+
Attributes:
|
232
|
+
qubits: A collection of qubits that will be used by the instruction.
|
233
|
+
clbits: A collection of clbits that will be used by the instruction.
|
234
|
+
qregs: A collection of quantum registers that are used by the instruction.
|
235
|
+
cregs: A collection of classical registers that are used by the instruction.
|
236
|
+
"""
|
237
|
+
|
238
|
+
qubits: Collection[Qubit] = ()
|
239
|
+
clbits: Collection[Clbit] = ()
|
240
|
+
qregs: Collection[QuantumRegister] = ()
|
241
|
+
cregs: Collection[ClassicalRegister] = ()
|
242
|
+
|
243
|
+
|
244
|
+
class InstructionPlaceholder(Instruction, abc.ABC):
|
245
|
+
"""A fake instruction that lies about its number of qubits and clbits.
|
246
|
+
|
247
|
+
These instances are used to temporarily represent control-flow instructions during the builder
|
248
|
+
process, when their lengths cannot be known until the end of the block. This is necessary to
|
249
|
+
allow constructs like::
|
250
|
+
|
251
|
+
with qc.for_loop(range(5)):
|
252
|
+
qc.h(0)
|
253
|
+
qc.measure(0, 0)
|
254
|
+
with qc.if_test((0, 0)):
|
255
|
+
qc.break_loop()
|
256
|
+
|
257
|
+
``qc.break_loop()`` needed to return a (mostly) functional
|
258
|
+
:obj:`~qiskit.circuit.Instruction` in order for the historical ``.InstructionSet.c_if``
|
259
|
+
to work correctly.
|
260
|
+
|
261
|
+
When appending a placeholder instruction into a circuit scope, you should create the
|
262
|
+
placeholder, and then ask it what resources it should be considered as using from the start by
|
263
|
+
calling :meth:`.InstructionPlaceholder.placeholder_instructions`. This set will be a subset of
|
264
|
+
the final resources it asks for, but it is used for initializing resources that *must* be
|
265
|
+
supplied, such as the bits used in the conditions of placeholder ``if`` statements.
|
266
|
+
|
267
|
+
.. warning::
|
268
|
+
|
269
|
+
This is an internal interface and no part of it should be relied upon outside of Qiskit
|
270
|
+
Terra.
|
271
|
+
"""
|
272
|
+
|
273
|
+
_directive = True
|
274
|
+
|
275
|
+
@abc.abstractmethod
|
276
|
+
def concrete_instruction(
|
277
|
+
self, qubits: FrozenSet[Qubit], clbits: FrozenSet[Clbit]
|
278
|
+
) -> Tuple[Instruction, InstructionResources]:
|
279
|
+
"""Get a concrete, complete instruction that is valid to act over all the given resources.
|
280
|
+
|
281
|
+
The returned resources may not be the full width of the given resources, but will certainly
|
282
|
+
be a subset of them; this can occur if (for example) a placeholder ``if`` statement is
|
283
|
+
present, but does not itself contain any placeholder instructions. For resource efficiency,
|
284
|
+
the returned :class:`.ControlFlowOp` will not unnecessarily span all resources, but only the
|
285
|
+
ones that it needs.
|
286
|
+
|
287
|
+
.. note::
|
288
|
+
|
289
|
+
The caller of this function is responsible for ensuring that the inputs to this function
|
290
|
+
are non-strict supersets of the bits returned by :meth:`placeholder_resources`.
|
291
|
+
|
292
|
+
|
293
|
+
Args:
|
294
|
+
qubits: The qubits the created instruction should be defined across.
|
295
|
+
clbits: The clbits the created instruction should be defined across.
|
296
|
+
|
297
|
+
Returns:
|
298
|
+
A full version of the relevant control-flow instruction, and the resources that it uses.
|
299
|
+
This is a "proper" instruction instance, as if it had been defined with the correct
|
300
|
+
number of qubits and clbits from the beginning.
|
301
|
+
"""
|
302
|
+
raise NotImplementedError
|
303
|
+
|
304
|
+
@abc.abstractmethod
|
305
|
+
def placeholder_resources(self) -> InstructionResources:
|
306
|
+
"""Get the qubit and clbit resources that this placeholder instruction should be considered
|
307
|
+
as using before construction.
|
308
|
+
|
309
|
+
This will likely not include *all* resources after the block has been built, but using the
|
310
|
+
output of this method ensures that all resources will pass through a
|
311
|
+
:meth:`.QuantumCircuit.append` call, even if they come from a placeholder, and consequently
|
312
|
+
will be tracked by the scope managers.
|
313
|
+
|
314
|
+
Returns:
|
315
|
+
A collection of the quantum and classical resources this placeholder instruction will
|
316
|
+
certainly use.
|
317
|
+
"""
|
318
|
+
raise NotImplementedError
|
319
|
+
|
320
|
+
# Provide some better error messages, just in case something goes wrong during development and
|
321
|
+
# the placeholder type leaks out to somewhere visible.
|
322
|
+
|
323
|
+
def repeat(self, n):
|
324
|
+
raise CircuitError("Cannot repeat a placeholder instruction.")
|
325
|
+
|
326
|
+
|
327
|
+
class ControlFlowBuilderBlock(CircuitScopeInterface):
|
328
|
+
"""A lightweight scoped block for holding instructions within a control-flow builder context.
|
329
|
+
|
330
|
+
This class is designed only to be used by :obj:`.QuantumCircuit` as an internal context for
|
331
|
+
control-flow builder instructions, and in general should never be instantiated by any code other
|
332
|
+
than that.
|
333
|
+
|
334
|
+
Note that the instructions that are added to this scope may not be valid yet, so this elides
|
335
|
+
some of the type-checking of :obj:`.QuantumCircuit` until those things are known.
|
336
|
+
|
337
|
+
The general principle of the resource tracking through these builder blocks is that every
|
338
|
+
necessary resource should pass through an :meth:`.append` call, so that at the point that
|
339
|
+
:meth:`.build` is called, the scope knows all the concrete resources that it requires. However,
|
340
|
+
the scope can also contain "placeholder" instructions, which may need extra resources filling in
|
341
|
+
from outer scopes (such as a ``break`` needing to know the width of its containing ``for``
|
342
|
+
loop). This means that :meth:`.build` takes all the *containing* scope's resources as well.
|
343
|
+
This does not break the "all resources pass through an append" rule, because the containing
|
344
|
+
scope will only begin to build its instructions once it has received them all.
|
345
|
+
|
346
|
+
In short, :meth:`.append` adds resources, and :meth:`.build` may use only a subset of the extra
|
347
|
+
ones passed. This ensures that all instructions know about all the resources they need, even in
|
348
|
+
the case of ``break``, but do not block any resources that they do *not* need.
|
349
|
+
|
350
|
+
.. warning::
|
351
|
+
|
352
|
+
This is an internal interface and no part of it should be relied upon outside of Qiskit
|
353
|
+
Terra.
|
354
|
+
"""
|
355
|
+
|
356
|
+
__slots__ = (
|
357
|
+
"_instructions",
|
358
|
+
"registers",
|
359
|
+
"global_phase",
|
360
|
+
"_allow_jumps",
|
361
|
+
"_parent",
|
362
|
+
"_built",
|
363
|
+
"_forbidden_message",
|
364
|
+
"_vars_local",
|
365
|
+
"_vars_capture",
|
366
|
+
"_stretches_local",
|
367
|
+
"_stretches_capture",
|
368
|
+
)
|
369
|
+
|
370
|
+
def __init__(
|
371
|
+
self,
|
372
|
+
qubits: Iterable[Qubit],
|
373
|
+
clbits: Iterable[Clbit],
|
374
|
+
*,
|
375
|
+
parent: CircuitScopeInterface,
|
376
|
+
registers: Iterable[Register] = (),
|
377
|
+
allow_jumps: bool = True,
|
378
|
+
forbidden_message: Optional[str] = None,
|
379
|
+
):
|
380
|
+
"""
|
381
|
+
Args:
|
382
|
+
qubits: Any qubits this scope should consider itself as using from the beginning.
|
383
|
+
clbits: Any clbits this scope should consider itself as using from the beginning. Along
|
384
|
+
with ``qubits``, this is useful for things such as ``if`` and ``while`` loop
|
385
|
+
builders, where the classical condition has associated resources, and is known when
|
386
|
+
this scope is created.
|
387
|
+
registers: Any registers this scope should consider itself as using from the
|
388
|
+
beginning. This is useful for :obj:`.IfElseOp` and :obj:`.WhileLoopOp` instances
|
389
|
+
which use a classical register as their condition.
|
390
|
+
allow_jumps: Whether this builder scope should allow ``break`` and ``continue``
|
391
|
+
statements within it. This is intended to help give sensible error messages when
|
392
|
+
dangerous behavior is encountered, such as using ``break`` inside an ``if`` context
|
393
|
+
manager that is not within a ``for`` manager. This can only be safe if the user is
|
394
|
+
going to place the resulting :obj:`.QuantumCircuit` inside a :obj:`.ForLoopOp` that
|
395
|
+
uses *exactly* the same set of resources. We cannot verify this from within the
|
396
|
+
builder interface (and it is too expensive to do when the ``for`` op is made), so we
|
397
|
+
fail safe, and require the user to use the more verbose, internal form.
|
398
|
+
parent: The scope interface of the containing scope.
|
399
|
+
forbidden_message: If a string is given here, a :exc:`.CircuitError` will be raised on
|
400
|
+
any attempts to append instructions to the scope with this message. This is used by
|
401
|
+
pseudo scopes where the state machine of the builder scopes has changed into a
|
402
|
+
position where no instructions should be accepted, such as when inside a ``switch``
|
403
|
+
but outside any cases.
|
404
|
+
"""
|
405
|
+
self._instructions = CircuitData(qubits, clbits)
|
406
|
+
self.registers = set(registers)
|
407
|
+
self.global_phase = 0.0
|
408
|
+
self._vars_local = {}
|
409
|
+
self._vars_capture = {}
|
410
|
+
self._stretches_local = {}
|
411
|
+
self._stretches_capture = {}
|
412
|
+
self._allow_jumps = allow_jumps
|
413
|
+
self._parent = parent
|
414
|
+
self._built = False
|
415
|
+
self._forbidden_message = forbidden_message
|
416
|
+
|
417
|
+
def qubits(self):
|
418
|
+
"""The set of qubits associated with this scope."""
|
419
|
+
return set(self.instructions.qubits)
|
420
|
+
|
421
|
+
def clbits(self):
|
422
|
+
"""The set of clbits associated with this scope."""
|
423
|
+
return set(self.instructions.clbits)
|
424
|
+
|
425
|
+
@property
|
426
|
+
def allow_jumps(self):
|
427
|
+
"""Whether this builder scope should allow ``break`` and ``continue`` statements within it.
|
428
|
+
|
429
|
+
This is intended to help give sensible error messages when dangerous behavior is
|
430
|
+
encountered, such as using ``break`` inside an ``if`` context manager that is not within a
|
431
|
+
``for`` manager. This can only be safe if the user is going to place the resulting
|
432
|
+
:obj:`.QuantumCircuit` inside a :obj:`.ForLoopOp` that uses *exactly* the same set of
|
433
|
+
resources. We cannot verify this from within the builder interface (and it is too expensive
|
434
|
+
to do when the ``for`` op is made), so we fail safe, and require the user to use the more
|
435
|
+
verbose, internal form.
|
436
|
+
"""
|
437
|
+
return self._allow_jumps
|
438
|
+
|
439
|
+
@property
|
440
|
+
def instructions(self):
|
441
|
+
return self._instructions
|
442
|
+
|
443
|
+
@staticmethod
|
444
|
+
def _raise_on_jump(operation):
|
445
|
+
# pylint: disable=cyclic-import
|
446
|
+
from .break_loop import BreakLoopOp, BreakLoopPlaceholder
|
447
|
+
from .continue_loop import ContinueLoopOp, ContinueLoopPlaceholder
|
448
|
+
|
449
|
+
forbidden = (BreakLoopOp, BreakLoopPlaceholder, ContinueLoopOp, ContinueLoopPlaceholder)
|
450
|
+
if isinstance(operation, forbidden):
|
451
|
+
raise CircuitError(
|
452
|
+
f"The current builder scope cannot take a '{operation.name}'"
|
453
|
+
" because it is not in a loop."
|
454
|
+
)
|
455
|
+
|
456
|
+
def append(
|
457
|
+
self, instruction: CircuitInstruction, *, _standard_gate: bool = False
|
458
|
+
) -> CircuitInstruction:
|
459
|
+
if self._forbidden_message is not None:
|
460
|
+
raise CircuitError(self._forbidden_message)
|
461
|
+
if not self._allow_jumps:
|
462
|
+
self._raise_on_jump(instruction.operation)
|
463
|
+
for b in instruction.qubits:
|
464
|
+
self.instructions.add_qubit(b, strict=False)
|
465
|
+
for b in instruction.clbits:
|
466
|
+
self.instructions.add_clbit(b, strict=False)
|
467
|
+
self._instructions.append(instruction)
|
468
|
+
return instruction
|
469
|
+
|
470
|
+
def extend(self, data: CircuitData):
|
471
|
+
if self._forbidden_message is not None:
|
472
|
+
raise CircuitError(self._forbidden_message)
|
473
|
+
if not self._allow_jumps:
|
474
|
+
data.foreach_op(self._raise_on_jump)
|
475
|
+
active_qubits, active_clbits = data.active_bits()
|
476
|
+
# Add bits in deterministic order.
|
477
|
+
for b in data.qubits:
|
478
|
+
if b in active_qubits:
|
479
|
+
self.instructions.add_qubit(b, strict=False)
|
480
|
+
for b in data.clbits:
|
481
|
+
if b in active_clbits:
|
482
|
+
self.instructions.add_clbit(b, strict=False)
|
483
|
+
self.instructions.extend(data)
|
484
|
+
|
485
|
+
def resolve_classical_resource(self, specifier):
|
486
|
+
if self._built:
|
487
|
+
raise CircuitError("Cannot add resources after the scope has been built.")
|
488
|
+
# Allow the inner resolve to propagate exceptions.
|
489
|
+
resource = self._parent.resolve_classical_resource(specifier)
|
490
|
+
if isinstance(resource, Clbit):
|
491
|
+
self.add_bits((resource,))
|
492
|
+
else:
|
493
|
+
self.add_register(resource)
|
494
|
+
return resource
|
495
|
+
|
496
|
+
def add_uninitialized_var(self, var: expr.Var):
|
497
|
+
if self._built:
|
498
|
+
raise CircuitError("Cannot add resources after the scope has been built.")
|
499
|
+
# We can shadow a name if it was declared in an outer scope, but only if we haven't already
|
500
|
+
# captured it ourselves yet.
|
501
|
+
if (previous := self._stretches_local.get(var.name)) is not None:
|
502
|
+
raise CircuitError(f"cannot add '{var}' as its name shadows the existing '{previous}'")
|
503
|
+
if (previous := self._vars_local.get(var.name)) is not None:
|
504
|
+
if previous == var:
|
505
|
+
raise CircuitError(f"'{var}' is already present in the scope")
|
506
|
+
raise CircuitError(f"cannot add '{var}' as its name shadows the existing '{previous}'")
|
507
|
+
if var.name in self._vars_capture or var.name in self._stretches_capture:
|
508
|
+
raise CircuitError(f"cannot add '{var}' as its name shadows the existing '{previous}'")
|
509
|
+
self._vars_local[var.name] = var
|
510
|
+
|
511
|
+
def add_stretch(self, stretch: expr.Stretch):
|
512
|
+
if self._built:
|
513
|
+
raise CircuitError("Cannot add resources after the scope has been built.")
|
514
|
+
# We can shadow a name if it was declared in an outer scope, but only if we haven't already
|
515
|
+
# captured it ourselves yet.
|
516
|
+
if (previous := self._vars_local.get(stretch.name)) is not None:
|
517
|
+
raise CircuitError(
|
518
|
+
f"cannot add '{stretch}' as its name shadows the existing '{previous}'"
|
519
|
+
)
|
520
|
+
if (previous := self._stretches_local.get(stretch.name)) is not None:
|
521
|
+
if previous == stretch:
|
522
|
+
raise CircuitError(f"'{stretch}' is already present in the scope")
|
523
|
+
raise CircuitError(
|
524
|
+
f"cannot add '{stretch}' as its name shadows the existing '{previous}'"
|
525
|
+
)
|
526
|
+
if stretch.name in self._vars_capture or stretch.name in self._stretches_capture:
|
527
|
+
raise CircuitError(
|
528
|
+
f"cannot add '{stretch}' as its name shadows the existing '{previous}'"
|
529
|
+
)
|
530
|
+
self._stretches_local[stretch.name] = stretch
|
531
|
+
|
532
|
+
def remove_var(self, var: expr.Var):
|
533
|
+
if self._built:
|
534
|
+
raise RuntimeError("exception handler 'remove_var' called after scope built")
|
535
|
+
self._vars_local.pop(var.name)
|
536
|
+
|
537
|
+
def remove_stretch(self, stretch: expr.Stretch):
|
538
|
+
if self._built:
|
539
|
+
raise RuntimeError("exception handler 'remove_stretch' called after scope built")
|
540
|
+
self._stretches_local.pop(stretch.name)
|
541
|
+
|
542
|
+
def get_var(self, name: str):
|
543
|
+
if name in self._stretches_local:
|
544
|
+
return None
|
545
|
+
if (out := self._vars_local.get(name)) is not None:
|
546
|
+
return out
|
547
|
+
return self._parent.get_var(name)
|
548
|
+
|
549
|
+
def get_stretch(self, name: str):
|
550
|
+
if name in self._vars_local:
|
551
|
+
return None
|
552
|
+
if (out := self._stretches_local.get(name)) is not None:
|
553
|
+
return out
|
554
|
+
return self._parent.get_stretch(name)
|
555
|
+
|
556
|
+
def use_var(self, var: expr.Var):
|
557
|
+
if (local := self._stretches_local.get(var.name)) is not None:
|
558
|
+
raise CircuitError(f"cannot use '{var}' which is shadowed by the local '{local}'")
|
559
|
+
if (local := self._vars_local.get(var.name)) is not None:
|
560
|
+
if local == var:
|
561
|
+
return
|
562
|
+
raise CircuitError(f"cannot use '{var}' which is shadowed by the local '{local}'")
|
563
|
+
if self._vars_capture.get(var.name) == var:
|
564
|
+
return
|
565
|
+
if self._parent.get_var(var.name) != var:
|
566
|
+
raise CircuitError(f"cannot close over '{var}', which is not in scope")
|
567
|
+
self._parent.use_var(var)
|
568
|
+
self._vars_capture[var.name] = var
|
569
|
+
|
570
|
+
def use_stretch(self, stretch: expr.Stretch):
|
571
|
+
if (local := self._vars_local.get(stretch.name)) is not None:
|
572
|
+
raise CircuitError(f"cannot use '{stretch}' which is shadowed by the local '{local}'")
|
573
|
+
if (local := self._stretches_local.get(stretch.name)) is not None:
|
574
|
+
if local == stretch:
|
575
|
+
return
|
576
|
+
raise CircuitError(f"cannot use '{stretch}' which is shadowed by the local '{local}'")
|
577
|
+
if self._stretches_capture.get(stretch.name) == stretch:
|
578
|
+
return
|
579
|
+
if self._parent.get_stretch(stretch.name) != stretch:
|
580
|
+
raise CircuitError(f"cannot close over '{stretch}', which is not in scope")
|
581
|
+
self._parent.use_stretch(stretch)
|
582
|
+
self._stretches_capture[stretch.name] = stretch
|
583
|
+
|
584
|
+
def use_qubit(self, qubit: Qubit):
|
585
|
+
self._instructions.add_qubit(qubit, strict=False)
|
586
|
+
|
587
|
+
def iter_local_vars(self):
|
588
|
+
"""Iterator over the variables currently declared in this scope."""
|
589
|
+
return self._vars_local.values()
|
590
|
+
|
591
|
+
def iter_local_stretches(self):
|
592
|
+
"""Iterator over the stretches currently declared in this scope."""
|
593
|
+
return self._stretches_local.values()
|
594
|
+
|
595
|
+
def iter_captured_vars(self):
|
596
|
+
"""Iterator over the variables currently captured in this scope."""
|
597
|
+
return self._vars_capture.values()
|
598
|
+
|
599
|
+
def iter_captured_stretches(self):
|
600
|
+
"""Iterator over the stretches currently captured in this scope."""
|
601
|
+
return self._stretches_capture.values()
|
602
|
+
|
603
|
+
def peek(self) -> CircuitInstruction:
|
604
|
+
"""Get the value of the most recent instruction tuple in this scope."""
|
605
|
+
if not self._instructions:
|
606
|
+
raise CircuitError("This scope contains no instructions.")
|
607
|
+
return self._instructions[-1]
|
608
|
+
|
609
|
+
def pop(self) -> CircuitInstruction:
|
610
|
+
"""Get the value of the most recent instruction in this scope, and remove it from this
|
611
|
+
object."""
|
612
|
+
if not self._instructions:
|
613
|
+
raise CircuitError("This scope contains no instructions.")
|
614
|
+
return self._instructions.pop()
|
615
|
+
|
616
|
+
def add_bits(self, bits: Iterable[Union[Qubit, Clbit]]):
|
617
|
+
"""Add extra bits to this scope that are not associated with any concrete instruction yet.
|
618
|
+
|
619
|
+
This is useful for expanding a scope's resource width when it may contain ``break`` or
|
620
|
+
``continue`` statements, or when its width needs to be expanded to match another scope's
|
621
|
+
width (as in the case of :obj:`.IfElseOp`).
|
622
|
+
|
623
|
+
Args:
|
624
|
+
bits: The qubits and clbits that should be added to a scope. It is not an error if
|
625
|
+
there are duplicates, either within the iterable or with the bits currently in
|
626
|
+
scope.
|
627
|
+
|
628
|
+
Raises:
|
629
|
+
TypeError: if the provided bit is of an incorrect type.
|
630
|
+
"""
|
631
|
+
for bit in bits:
|
632
|
+
if isinstance(bit, Qubit):
|
633
|
+
self.instructions.add_qubit(bit, strict=False)
|
634
|
+
elif isinstance(bit, Clbit):
|
635
|
+
self.instructions.add_clbit(bit, strict=False)
|
636
|
+
else:
|
637
|
+
raise TypeError(f"Can only add qubits or classical bits, but received '{bit}'.")
|
638
|
+
|
639
|
+
def add_register(self, register: Register):
|
640
|
+
"""Add a :obj:`.Register` to the set of resources used by this block, ensuring that
|
641
|
+
all bits contained within are also accounted for.
|
642
|
+
|
643
|
+
Args:
|
644
|
+
register: the register to add to the block.
|
645
|
+
"""
|
646
|
+
if register in self.registers:
|
647
|
+
# Fast return to avoid iterating through the bits.
|
648
|
+
return
|
649
|
+
self.registers.add(register)
|
650
|
+
self.add_bits(register)
|
651
|
+
|
652
|
+
def build(
|
653
|
+
self, all_qubits: FrozenSet[Qubit], all_clbits: FrozenSet[Clbit]
|
654
|
+
) -> "qiskit.circuit.QuantumCircuit":
|
655
|
+
"""Build this scoped block into a complete :obj:`.QuantumCircuit` instance.
|
656
|
+
|
657
|
+
This will build a circuit which contains all of the necessary qubits and clbits and no
|
658
|
+
others.
|
659
|
+
|
660
|
+
The ``qubits`` and ``clbits`` arguments should be sets that contains all the resources in
|
661
|
+
the outer scope; these will be passed down to inner placeholder instructions, so they can
|
662
|
+
apply themselves across the whole scope should they need to. The resulting
|
663
|
+
:obj:`.QuantumCircuit` will be defined over a (nonstrict) subset of these resources. This
|
664
|
+
is used to let ``break`` and ``continue`` span all resources, even if they are nested within
|
665
|
+
several :obj:`.IfElsePlaceholder` objects, without requiring :obj:`.IfElsePlaceholder`
|
666
|
+
objects *without* any ``break`` or ``continue`` statements to be full-width.
|
667
|
+
|
668
|
+
Args:
|
669
|
+
all_qubits: all the qubits in the containing scope of this block. The block may expand
|
670
|
+
to use some or all of these qubits, but will never gain qubits that are not in this
|
671
|
+
set.
|
672
|
+
all_clbits: all the clbits in the containing scope of this block. The block may expand
|
673
|
+
to use some or all of these clbits, but will never gain clbits that are not in this
|
674
|
+
set.
|
675
|
+
|
676
|
+
Returns:
|
677
|
+
A circuit containing concrete versions of all the instructions that were in the scope,
|
678
|
+
and using the minimal set of resources necessary to support them, within the enclosing
|
679
|
+
scope.
|
680
|
+
"""
|
681
|
+
# pylint: disable=cyclic-import
|
682
|
+
from qiskit.circuit import QuantumCircuit, SwitchCaseOp
|
683
|
+
|
684
|
+
# There's actually no real problem with building a scope more than once. This flag is more
|
685
|
+
# so _other_ operations, which aren't safe can be forbidden, such as mutating instructions
|
686
|
+
# that may have been built into other objects.
|
687
|
+
self._built = True
|
688
|
+
|
689
|
+
if self._forbidden_message is not None:
|
690
|
+
# Reaching this implies a logic error in the builder interface.
|
691
|
+
raise RuntimeError("Cannot build a forbidden scope. Please report this as a bug.")
|
692
|
+
|
693
|
+
potential_qubits = set(all_qubits) - self.qubits()
|
694
|
+
potential_clbits = set(all_clbits) - self.clbits()
|
695
|
+
|
696
|
+
# We start off by only giving the QuantumCircuit the qubits we _know_ it will need, and add
|
697
|
+
# more later as needed.
|
698
|
+
out = QuantumCircuit(
|
699
|
+
self._instructions.qubits,
|
700
|
+
self._instructions.clbits,
|
701
|
+
*self.registers,
|
702
|
+
global_phase=self.global_phase,
|
703
|
+
captures=itertools.chain(self._vars_capture.values(), self._stretches_capture.values()),
|
704
|
+
)
|
705
|
+
for var in self._vars_local.values():
|
706
|
+
# The requisite `Store` instruction to initialise the variable will have been appended
|
707
|
+
# into the instructions.
|
708
|
+
out.add_uninitialized_var(var)
|
709
|
+
|
710
|
+
for var in self._stretches_local.values():
|
711
|
+
out.add_stretch(var)
|
712
|
+
|
713
|
+
# Maps placeholder index to the newly concrete instruction.
|
714
|
+
placeholder_to_concrete = {}
|
715
|
+
|
716
|
+
def update_registers(index, op):
|
717
|
+
if isinstance(op, InstructionPlaceholder):
|
718
|
+
op, resources = op.concrete_instruction(all_qubits, all_clbits)
|
719
|
+
qubits = tuple(resources.qubits)
|
720
|
+
clbits = tuple(resources.clbits)
|
721
|
+
placeholder_to_concrete[index] = CircuitInstruction(op, qubits, clbits)
|
722
|
+
# We want to avoid iterating over the tuples unnecessarily if there's no chance
|
723
|
+
# we'll need to add bits to the circuit.
|
724
|
+
if potential_qubits and qubits:
|
725
|
+
add_qubits = potential_qubits.intersection(qubits)
|
726
|
+
if add_qubits:
|
727
|
+
potential_qubits.difference_update(add_qubits)
|
728
|
+
out.add_bits(add_qubits)
|
729
|
+
if potential_clbits and clbits:
|
730
|
+
add_clbits = potential_clbits.intersection(clbits)
|
731
|
+
if add_clbits:
|
732
|
+
potential_clbits.difference_update(add_clbits)
|
733
|
+
out.add_bits(add_clbits)
|
734
|
+
for register in itertools.chain(resources.qregs, resources.cregs):
|
735
|
+
if register not in self.registers:
|
736
|
+
# As of 2021-12-09, QuantumCircuit doesn't have an efficient way to check if
|
737
|
+
# a register is already present, so we use our own tracking.
|
738
|
+
self.add_register(register)
|
739
|
+
out.add_register(register)
|
740
|
+
if getattr(op, "_condition", None) is not None:
|
741
|
+
for register in condition_resources(op._condition).cregs:
|
742
|
+
if register not in self.registers:
|
743
|
+
self.add_register(register)
|
744
|
+
out.add_register(register)
|
745
|
+
elif isinstance(op, SwitchCaseOp):
|
746
|
+
target = op.target
|
747
|
+
if isinstance(target, Clbit):
|
748
|
+
target_registers = ()
|
749
|
+
elif isinstance(target, ClassicalRegister):
|
750
|
+
target_registers = (target,)
|
751
|
+
else:
|
752
|
+
target_registers = node_resources(target).cregs
|
753
|
+
for register in target_registers:
|
754
|
+
if register not in self.registers:
|
755
|
+
self.add_register(register)
|
756
|
+
out.add_register(register)
|
757
|
+
|
758
|
+
# Update registers and bits of 'out'.
|
759
|
+
self._instructions.foreach_op_indexed(update_registers)
|
760
|
+
|
761
|
+
# Create the concrete instruction listing.
|
762
|
+
out_data = self._instructions.copy()
|
763
|
+
out_data.replace_bits(out.qubits, out.clbits)
|
764
|
+
for i, instruction in placeholder_to_concrete.items():
|
765
|
+
out_data[i] = instruction
|
766
|
+
|
767
|
+
# Add listing to 'out'.
|
768
|
+
out._current_scope().extend(out_data)
|
769
|
+
return out
|
770
|
+
|
771
|
+
def copy(self) -> "ControlFlowBuilderBlock":
|
772
|
+
"""Return a semi-shallow copy of this builder block.
|
773
|
+
|
774
|
+
The instruction lists and sets of qubits and clbits will be new instances (so mutations will
|
775
|
+
not propagate), but any :obj:`.Instruction` instances within them will not be copied.
|
776
|
+
|
777
|
+
Returns:
|
778
|
+
a semi-shallow copy of this object.
|
779
|
+
"""
|
780
|
+
out = type(self).__new__(type(self))
|
781
|
+
out._instructions = self._instructions.copy()
|
782
|
+
out.registers = self.registers.copy()
|
783
|
+
out.global_phase = self.global_phase
|
784
|
+
out._vars_local = self._vars_local.copy()
|
785
|
+
out._vars_capture = self._vars_capture.copy()
|
786
|
+
out._stretches_local = self._stretches_local.copy()
|
787
|
+
out._stretches_capture = self._stretches_capture.copy()
|
788
|
+
out._parent = self._parent
|
789
|
+
out._allow_jumps = self._allow_jumps
|
790
|
+
out._forbidden_message = self._forbidden_message
|
791
|
+
return out
|