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,677 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017.
|
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
|
+
"""
|
14
|
+
=============================================
|
15
|
+
Providers Interface (:mod:`qiskit.providers`)
|
16
|
+
=============================================
|
17
|
+
|
18
|
+
.. currentmodule:: qiskit.providers
|
19
|
+
|
20
|
+
This module contains the classes used to build external providers for Qiskit. A
|
21
|
+
provider is anything that provides an external service to Qiskit. The typical
|
22
|
+
example of this is a Backend provider which provides
|
23
|
+
:class:`~qiskit.providers.Backend` objects which can be used for executing
|
24
|
+
:class:`~qiskit.circuit.QuantumCircuit`
|
25
|
+
objects. This module contains the abstract classes which are used to define the
|
26
|
+
interface between a provider and Qiskit.
|
27
|
+
|
28
|
+
Version Support
|
29
|
+
===============
|
30
|
+
|
31
|
+
Each providers interface abstract class is individually versioned. When we
|
32
|
+
need to make a change to an interface a new abstract class will be created to
|
33
|
+
define the new interface. These interface changes are not guaranteed to be
|
34
|
+
backwards compatible between versions.
|
35
|
+
|
36
|
+
Version Changes
|
37
|
+
----------------
|
38
|
+
|
39
|
+
Each minor version release of ``qiskit`` **may** increment the version of any
|
40
|
+
backend interface a single version number. It will be an aggregate of all
|
41
|
+
the interface changes for that release on that interface.
|
42
|
+
|
43
|
+
Version Support Policy
|
44
|
+
----------------------
|
45
|
+
|
46
|
+
To enable providers to have time to adjust to changes in this interface
|
47
|
+
Qiskit will support multiple versions of each class at once. Given the
|
48
|
+
nature of one version per release the version deprecation policy is a bit
|
49
|
+
more conservative than the standard deprecation policy. Qiskit will support a
|
50
|
+
provider interface version for a minimum of 3 minor releases or the first
|
51
|
+
release after 6 months from the release that introduced a version, whichever is
|
52
|
+
longer, prior to a potential deprecation. After that the standard deprecation
|
53
|
+
policy will apply to that interface version. This will give providers and users
|
54
|
+
sufficient time to adapt to potential breaking changes in the interface. So for
|
55
|
+
example lets say in 0.19.0 ``BackendV2`` is introduced and in the 3 months after
|
56
|
+
the release of 0.19.0 we release 0.20.0, 0.21.0, and 0.22.0, then 7 months after
|
57
|
+
0.19.0 we release 0.23.0. In 0.23.0 we can deprecate BackendV2, and it needs to
|
58
|
+
still be supported and can't be removed until the deprecation policy completes.
|
59
|
+
|
60
|
+
It's worth pointing out that Qiskit's version support policy doesn't mean
|
61
|
+
providers themselves will have the same support story, they can (and arguably
|
62
|
+
should) update to newer versions as soon as they can, the support window is
|
63
|
+
just for Qiskit's supported versions. Part of this lengthy window prior to
|
64
|
+
deprecation is to give providers enough time to do their own deprecation of a
|
65
|
+
potential end user impacting change in a user facing part of the interface
|
66
|
+
prior to bumping their version. For example, let's say we changed the signature
|
67
|
+
to ``Backend.run()`` in ``BackendV34`` in a backwards incompatible way. Before
|
68
|
+
Aer could update its :class:`~qiskit_aer.AerSimulator` class
|
69
|
+
to be based on version 34 they'd need to deprecate the old signature prior to switching
|
70
|
+
over. The changeover for Aer is not guaranteed to be lockstep with Qiskit, so we
|
71
|
+
need to ensure there is a sufficient amount of time for Aer to complete its
|
72
|
+
deprecation cycle prior to removing version 33 (ie making version 34
|
73
|
+
mandatory/the minimum version).
|
74
|
+
|
75
|
+
Abstract Classes
|
76
|
+
================
|
77
|
+
|
78
|
+
Backend
|
79
|
+
-------
|
80
|
+
|
81
|
+
.. autosummary::
|
82
|
+
:toctree: ../stubs/
|
83
|
+
|
84
|
+
Backend
|
85
|
+
BackendV2
|
86
|
+
QubitProperties
|
87
|
+
|
88
|
+
Options
|
89
|
+
-------
|
90
|
+
|
91
|
+
.. autosummary::
|
92
|
+
:toctree: ../stubs/
|
93
|
+
|
94
|
+
Options
|
95
|
+
|
96
|
+
Job
|
97
|
+
---
|
98
|
+
|
99
|
+
.. autosummary::
|
100
|
+
:toctree: ../stubs/
|
101
|
+
|
102
|
+
Job
|
103
|
+
JobV1
|
104
|
+
|
105
|
+
Job Status
|
106
|
+
----------
|
107
|
+
|
108
|
+
.. autosummary::
|
109
|
+
:toctree: ../stubs/
|
110
|
+
|
111
|
+
JobStatus
|
112
|
+
|
113
|
+
Exceptions
|
114
|
+
----------
|
115
|
+
|
116
|
+
.. autoexception:: QiskitBackendNotFoundError
|
117
|
+
.. autoexception:: JobError
|
118
|
+
.. autoexception:: JobTimeoutError
|
119
|
+
|
120
|
+
Writing a New Backend
|
121
|
+
=====================
|
122
|
+
|
123
|
+
If you have a quantum device or simulator that you would like to integrate with
|
124
|
+
Qiskit you will need to write a backend. A provider is a collection of backends
|
125
|
+
and will provide Qiskit with a
|
126
|
+
method to get available :class:`~qiskit.providers.BackendV2` objects. The
|
127
|
+
:class:`~qiskit.providers.BackendV2` object provides both information describing
|
128
|
+
a backend and its operation for the :mod:`~qiskit.transpiler` so that circuits
|
129
|
+
can be compiled to something that is optimized and can execute on the
|
130
|
+
backend. It also provides the :meth:`~qiskit.providers.BackendV2.run` method which can
|
131
|
+
run the :class:`~qiskit.circuit.QuantumCircuit` objects. This enables users and other Qiskit
|
132
|
+
APIs to get results from
|
133
|
+
executing circuits on devices in a standard
|
134
|
+
fashion regardless of how the backend is implemented. At a high level the basic
|
135
|
+
steps for writing a provider are:
|
136
|
+
|
137
|
+
* Implement a ``Provider`` class that handles access to the backend(s).
|
138
|
+
* Implement a :class:`~qiskit.providers.BackendV2` subclass and its
|
139
|
+
:meth:`~qiskit.providers.BackendV2.run` method.
|
140
|
+
|
141
|
+
* Add any custom gates for the backend's basis to the session
|
142
|
+
:class:`~qiskit.circuit.EquivalenceLibrary` instance.
|
143
|
+
|
144
|
+
* Implement a :class:`~qiskit.providers.JobV1` subclass that handles
|
145
|
+
interacting with a running job.
|
146
|
+
|
147
|
+
For a simple example of a provider, see the
|
148
|
+
`qiskit-aqt-provider <https://github.com/qiskit-community/qiskit-aqt-provider>`__
|
149
|
+
|
150
|
+
Provider
|
151
|
+
--------
|
152
|
+
|
153
|
+
A provider class serves a single purpose: to get backend objects that enable
|
154
|
+
executing circuits on a device or simulator. The expectation is that any
|
155
|
+
required credentials and/or authentication will be handled in the initialization
|
156
|
+
of a provider object. The provider object will then provide a list of backends,
|
157
|
+
and methods to filter and acquire backends (using the provided credentials if
|
158
|
+
required). An example provider class looks like::
|
159
|
+
|
160
|
+
from qiskit.providers.providerutils import filter_backends
|
161
|
+
|
162
|
+
from .backend import MyBackend
|
163
|
+
|
164
|
+
class MyProvider:
|
165
|
+
|
166
|
+
def __init__(self, token=None):
|
167
|
+
super().__init__()
|
168
|
+
self.token = token
|
169
|
+
self.backends = [MyBackend(provider=self)]
|
170
|
+
|
171
|
+
def backends(self, name=None, **kwargs):
|
172
|
+
if name:
|
173
|
+
backends = [
|
174
|
+
backend for backend in backends if backend.name() == name]
|
175
|
+
return filter_backends(backends, filters=filters, **kwargs)
|
176
|
+
|
177
|
+
Ensure that any necessary information for
|
178
|
+
authentication (if required) are present in the class and that the backends
|
179
|
+
method matches the required interface. The rest is up to the specific provider on how to implement.
|
180
|
+
|
181
|
+
Backend
|
182
|
+
-------
|
183
|
+
|
184
|
+
The backend classes are the core to the provider. These classes are what
|
185
|
+
provide the interface between Qiskit and the hardware or simulator that will
|
186
|
+
execute circuits. This includes providing the necessary information to
|
187
|
+
describe a backend to the compiler so that it can embed and optimize any
|
188
|
+
circuit for the backend. There are 4 required things in every backend object: a
|
189
|
+
:attr:`~qiskit.providers.BackendV2.target` property to define the model of the
|
190
|
+
backend for the compiler, a :attr:`~qiskit.providers.BackendV2.max_circuits`
|
191
|
+
property to define a limit on the number of circuits the backend can execute in
|
192
|
+
a single batch job (if there is no limit ``None`` can be used), a
|
193
|
+
:meth:`~qiskit.providers.BackendV2.run` method to accept job submissions, and
|
194
|
+
a :obj:`~qiskit.providers.BackendV2._default_options` method to define the
|
195
|
+
user configurable options and their default values. For example, a minimum working
|
196
|
+
example would be something like::
|
197
|
+
|
198
|
+
from qiskit.providers import BackendV2 as Backend
|
199
|
+
from qiskit.transpiler import Target
|
200
|
+
from qiskit.providers import Options
|
201
|
+
from qiskit.circuit import Parameter, Measure
|
202
|
+
from qiskit.circuit.library import PhaseGate, SXGate, UGate, CXGate, IGate
|
203
|
+
|
204
|
+
|
205
|
+
class Mybackend(Backend):
|
206
|
+
|
207
|
+
def __init__(self):
|
208
|
+
super().__init__()
|
209
|
+
|
210
|
+
# Create Target
|
211
|
+
self._target = Target("Target for My Backend")
|
212
|
+
# Instead of None for this and below instructions you can define
|
213
|
+
# a qiskit.transpiler.InstructionProperties object to define properties
|
214
|
+
# for an instruction.
|
215
|
+
lam = Parameter("λ")
|
216
|
+
p_props = {(qubit,): None for qubit in range(5)}
|
217
|
+
self._target.add_instruction(PhaseGate(lam), p_props)
|
218
|
+
sx_props = {(qubit,): None for qubit in range(5)}
|
219
|
+
self._target.add_instruction(SXGate(), sx_props)
|
220
|
+
phi = Parameter("φ")
|
221
|
+
theta = Parameter("ϴ")
|
222
|
+
u_props = {(qubit,): None for qubit in range(5)}
|
223
|
+
self._target.add_instruction(UGate(theta, phi, lam), u_props)
|
224
|
+
cx_props = {edge: None for edge in [(0, 1), (1, 2), (2, 3), (3, 4)]}
|
225
|
+
self._target.add_instruction(CXGate(), cx_props)
|
226
|
+
meas_props = {(qubit,): None for qubit in range(5)}
|
227
|
+
self._target.add_instruction(Measure(), meas_props)
|
228
|
+
id_props = {(qubit,): None for qubit in range(5)}
|
229
|
+
self._target.add_instruction(IGate(), id_props)
|
230
|
+
|
231
|
+
# Set option validators
|
232
|
+
self.options.set_validator("shots", (1, 4096))
|
233
|
+
self.options.set_validator("memory", bool)
|
234
|
+
|
235
|
+
@property
|
236
|
+
def target(self):
|
237
|
+
return self._target
|
238
|
+
|
239
|
+
@property
|
240
|
+
def max_circuits(self):
|
241
|
+
return 1024
|
242
|
+
|
243
|
+
@classmethod
|
244
|
+
def _default_options(cls):
|
245
|
+
return Options(shots=1024, memory=False)
|
246
|
+
|
247
|
+
def run(circuits, **kwargs):
|
248
|
+
# serialize circuits submit to backend and create a job
|
249
|
+
for kwarg in kwargs:
|
250
|
+
if not hasattr(kwarg, self.options):
|
251
|
+
warnings.warn(
|
252
|
+
"Option %s is not used by this backend" % kwarg,
|
253
|
+
UserWarning, stacklevel=2)
|
254
|
+
options = {
|
255
|
+
'shots': kwargs.get('shots', self.options.shots),
|
256
|
+
'memory': kwargs.get('memory', self.options.shots),
|
257
|
+
}
|
258
|
+
job_json = convert_to_wire_format(circuit, options)
|
259
|
+
job_handle = submit_to_backend(job_jsonb)
|
260
|
+
return MyJob(self. job_handle, job_json, circuit)
|
261
|
+
|
262
|
+
|
263
|
+
Backend's Transpiler Interface
|
264
|
+
------------------------------
|
265
|
+
|
266
|
+
The key piece of the :class:`~qiskit.providers.Backend` object is how it describes itself to the
|
267
|
+
compiler. This is handled with the :class:`~qiskit.transpiler.Target` class which defines
|
268
|
+
a model of a backend for the transpiler. A backend object will need to return
|
269
|
+
a :class:`~qiskit.transpiler.Target` object from the :attr:`~qiskit.providers.BackendV2.target`
|
270
|
+
attribute which the :func:`~qiskit.compiler.transpile` function will use as
|
271
|
+
its model of a backend target for compilation.
|
272
|
+
|
273
|
+
.. _custom_basis_gates:
|
274
|
+
|
275
|
+
Custom Basis Gates
|
276
|
+
^^^^^^^^^^^^^^^^^^
|
277
|
+
|
278
|
+
1. If your backend doesn't use gates in the Qiskit circuit library
|
279
|
+
(:mod:`qiskit.circuit.library`) you can integrate support for this into your
|
280
|
+
provider. The basic method for doing this is first to define a
|
281
|
+
:class:`~qiskit.circuit.Gate` subclass for each custom gate in the basis
|
282
|
+
set. For example::
|
283
|
+
|
284
|
+
import numpy as np
|
285
|
+
|
286
|
+
from qiskit.circuit import Gate
|
287
|
+
from qiskit.circuit import QuantumCircuit
|
288
|
+
|
289
|
+
class SYGate(Gate):
|
290
|
+
def __init__(self, label=None):
|
291
|
+
super().__init__("sy", 1, [], label=label)
|
292
|
+
|
293
|
+
def _define(self):
|
294
|
+
qc = QuantumCircuit(1)
|
295
|
+
qc.ry(np.pi / 2, 0)
|
296
|
+
self.definition = qc
|
297
|
+
|
298
|
+
The key thing to ensure is that for any custom gates in your Backend's basis set
|
299
|
+
your custom gate's name attribute (the first param on
|
300
|
+
``super().__init__()`` in the ``__init__`` definition above) does not conflict
|
301
|
+
with the name of any other gates. The name attribute is what is used to
|
302
|
+
identify the gate in the basis set for the transpiler. If there is a conflict
|
303
|
+
the transpiler will not know which gate to use.
|
304
|
+
|
305
|
+
2. Add the custom gate to the target for your backend. This can be done with
|
306
|
+
the :meth:`.Target.add_instruction` method. You'll need to add an instance of
|
307
|
+
``SYGate`` and its parameters to the target so the transpiler knows it
|
308
|
+
exists. For example, assuming this is part of your
|
309
|
+
:class:`~qiskit.providers.BackendV2` implementation for your backend::
|
310
|
+
|
311
|
+
from qiskit.transpiler import InstructionProperties
|
312
|
+
|
313
|
+
sy_props = {
|
314
|
+
(0,): InstructionProperties(duration=2.3e-6, error=0.0002)
|
315
|
+
(1,): InstructionProperties(duration=2.1e-6, error=0.0001)
|
316
|
+
(2,): InstructionProperties(duration=2.5e-6, error=0.0003)
|
317
|
+
(3,): InstructionProperties(duration=2.2e-6, error=0.0004)
|
318
|
+
}
|
319
|
+
self.target.add_instruction(SYGate(), sy_props)
|
320
|
+
|
321
|
+
The keys in ``sy_props`` define the qubits where the backend ``SYGate`` can
|
322
|
+
be used on, and the values define the properties of ``SYGate`` on that
|
323
|
+
qubit. For multiqubit gates the tuple keys contain all qubit combinations
|
324
|
+
the gate works on (order is significant, i.e. ``(0, 1)`` is different from
|
325
|
+
``(1, 0)``).
|
326
|
+
|
327
|
+
3. After you've defined the custom gates to use for the backend's basis set
|
328
|
+
then you need to add equivalence rules to the standard equivalence library
|
329
|
+
so that the :func:`~qiskit.compiler.transpile` function and
|
330
|
+
:mod:`~qiskit.transpiler` module can convert an arbitrary circuit using the
|
331
|
+
custom basis set. This can be done by defining equivalent circuits, in terms
|
332
|
+
of the custom gate, for standard gates. Typically if you can convert from a
|
333
|
+
:class:`~qiskit.circuit.library.CXGate` (if your basis doesn't include a
|
334
|
+
standard 2 qubit gate) and some commonly used single qubit rotation gates like
|
335
|
+
the :class:`~qiskit.circuit.library.HGate` and
|
336
|
+
:class:`~qiskit.circuit.library.UGate` that should be sufficient for the
|
337
|
+
transpiler to translate any circuit into the custom basis gates. But, the more
|
338
|
+
equivalence rules that are defined from standard gates to your basis the more
|
339
|
+
efficient translation from an arbitrary circuit to the target basis will be
|
340
|
+
(although not always, and there is a diminishing margin of return).
|
341
|
+
|
342
|
+
For example, if you were to add some rules for the above custom ``SYGate``
|
343
|
+
we could define the :class:`~qiskit.circuit.library.U2Gate` and
|
344
|
+
:class:`~qiskit.circuit.library.HGate`::
|
345
|
+
|
346
|
+
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary
|
347
|
+
from qiskit.circuit.library import HGate
|
348
|
+
from qiskit.circuit.library import ZGate
|
349
|
+
from qiskit.circuit.library import RZGate
|
350
|
+
from qiskit.circuit.library import U2Gate
|
351
|
+
|
352
|
+
|
353
|
+
# H => Z SY
|
354
|
+
q = qiskit.QuantumRegister(1, "q")
|
355
|
+
def_sy_h = qiskit.QuantumCircuit(q)
|
356
|
+
def_sy_h.append(ZGate(), [q[0]], [])
|
357
|
+
def_sy_h.append(SYGate(), [q[0]], [])
|
358
|
+
SessionEquivalenceLibrary.add_equivalence(
|
359
|
+
HGate(), def_sy_h)
|
360
|
+
|
361
|
+
# u2 => Z SY Z
|
362
|
+
phi = qiskit.circuit.Parameter('phi')
|
363
|
+
lam = qiskit.circuit.Parameter('lambda')
|
364
|
+
q = qiskit.QuantumRegister(1, "q")
|
365
|
+
def_sy_u2 = qiskit.QuantumCircuit(q)
|
366
|
+
def_sy_u2.append(RZGate(lam), [q[0]], [])
|
367
|
+
def_sy_u2.append(SYGate(), [q[0]], [])
|
368
|
+
def_sy_u2.append(RZGate(phi), [q[0]], [])
|
369
|
+
SessionEquivalenceLibrary.add_equivalence(
|
370
|
+
U2Gate(phi, lam), def_sy_u2)
|
371
|
+
|
372
|
+
|
373
|
+
You will want this to be run on import so that as soon as the provider's
|
374
|
+
package is imported it will be run. This will ensure that any time the
|
375
|
+
:class:`~qiskit.transpiler.passes.BasisTranslator` pass is run with the
|
376
|
+
custom gates the equivalence rules are defined.
|
377
|
+
|
378
|
+
It's also worth noting that depending on the basis you're using, some optimization
|
379
|
+
passes in the transpiler, such as
|
380
|
+
:class:`~qiskit.transpiler.passes.Optimize1qGatesDecomposition`, may not
|
381
|
+
be able to operate with your custom basis. For our ``SYGate`` example, the
|
382
|
+
:class:`~qiskit.transpiler.passes.Optimize1qGatesDecomposition` will not be
|
383
|
+
able to simplify runs of single qubit gates into the SY basis. This is because
|
384
|
+
the :class:`~qiskit.quantum_info.OneQubitEulerDecomposer` class does not
|
385
|
+
know how to work in the SY basis. To solve this the ``SYGate`` class would
|
386
|
+
need to be added to Qiskit and
|
387
|
+
:class:`~qiskit.quantum_info.OneQubitEulerDecomposer` updated to support
|
388
|
+
decomposing to the ``SYGate``. Longer term that is likely a better direction
|
389
|
+
for custom basis gates and contributing the definitions and support in the
|
390
|
+
transpiler will ensure that it continues to be well supported by Qiskit
|
391
|
+
moving forward.
|
392
|
+
|
393
|
+
.. _custom_transpiler_backend:
|
394
|
+
|
395
|
+
Custom Transpiler Passes
|
396
|
+
^^^^^^^^^^^^^^^^^^^^^^^^
|
397
|
+
The transpiler supports the ability for backends to provide custom transpiler
|
398
|
+
stage implementations to facilitate hardware specific optimizations and
|
399
|
+
circuit transformations. Currently there are two stages supported,
|
400
|
+
``get_translation_stage_plugin()`` and ``get_scheduling_stage_plugin()``
|
401
|
+
which allow a backend to specify string plugin names to be used as the default
|
402
|
+
translation and scheduling stages, respectively. These
|
403
|
+
hook points in a :class:`~.BackendV2` class can be used if your
|
404
|
+
backend has requirements for compilation that are not met by the
|
405
|
+
current backend/:class:`~.Target` interface. Please also consider
|
406
|
+
submitting a Github issue describing your use case as there is interest
|
407
|
+
in improving these interfaces to be able to describe more hardware
|
408
|
+
architectures in greater depth.
|
409
|
+
|
410
|
+
To leverage these hook points you just need to add the methods to your
|
411
|
+
:class:`~.BackendV2` implementation and have them return a string plugin name.
|
412
|
+
For example::
|
413
|
+
|
414
|
+
|
415
|
+
class Mybackend(BackendV2):
|
416
|
+
|
417
|
+
def get_scheduling_stage_plugin(self):
|
418
|
+
return "SpecialDD"
|
419
|
+
|
420
|
+
def get_translation_stage_plugin(self):
|
421
|
+
return "BasisTranslatorWithCustom1qOptimization"
|
422
|
+
|
423
|
+
This snippet of a backend implementation will now have the :func:`~.transpile`
|
424
|
+
function use the ``SpecialDD`` plugin for the scheduling stage and
|
425
|
+
the ``BasisTranslatorWithCustom1qOptimization`` plugin for the translation
|
426
|
+
stage by default when the target is set to ``Mybackend``. Note that users may override these choices
|
427
|
+
by explicitly selecting a different plugin name. For this interface to work though transpiler
|
428
|
+
stage plugins must be implemented for the returned plugin name. You can refer
|
429
|
+
to :mod:`qiskit.transpiler.preset_passmanagers.plugin` module documentation for
|
430
|
+
details on how to implement plugins. The typical expectation is that if your backend
|
431
|
+
requires custom passes as part of a compilation stage the provider package will
|
432
|
+
include the transpiler stage plugins that use those passes. However, this is not
|
433
|
+
required and any valid method (from a built-in method or external plugin) can
|
434
|
+
be used.
|
435
|
+
|
436
|
+
This way if these two compilation steps are **required** for running or providing
|
437
|
+
efficient output on ``Mybackend`` the transpiler will be able to perform these
|
438
|
+
custom steps without any manual user input.
|
439
|
+
|
440
|
+
.. _providers-guide-real-time-variables:
|
441
|
+
|
442
|
+
Real-time variables
|
443
|
+
^^^^^^^^^^^^^^^^^^^
|
444
|
+
|
445
|
+
The transpiler will automatically handle real-time typed classical variables (see
|
446
|
+
:mod:`qiskit.circuit.classical`) and treat the :class:`.Store` instruction as a built-in
|
447
|
+
"directive", similar to :class:`.Barrier`. No special handling from backends is necessary to permit
|
448
|
+
this.
|
449
|
+
|
450
|
+
If your backend is *unable* to handle classical variables and storage, we recommend that you comment
|
451
|
+
on this in your documentation, and insert a check into your :meth:`~.BackendV2.run` method (see
|
452
|
+
:ref:`providers-guide-backend-run`) to eagerly reject circuits containing them. You can examine
|
453
|
+
:attr:`.QuantumCircuit.num_vars` for the presence of variables at the top level. If you accept
|
454
|
+
:ref:`control-flow operations <circuit-control-flow-repr>`, you might need to recursively search the
|
455
|
+
internal :attr:`~.ControlFlowOp.blocks` of each for scope-local variables with
|
456
|
+
:attr:`.QuantumCircuit.num_declared_vars`.
|
457
|
+
|
458
|
+
For example, a function to check for the presence of any manual storage locations, or manual stores
|
459
|
+
to memory::
|
460
|
+
|
461
|
+
from qiskit.circuit import Store, ControlFlowOp, QuantumCircuit
|
462
|
+
|
463
|
+
def has_realtime_logic(circuit: QuantumCircuit) -> bool:
|
464
|
+
if circuit.num_vars:
|
465
|
+
return True
|
466
|
+
for instruction in circuit.data:
|
467
|
+
if isinstance(instruction.operation, Store):
|
468
|
+
return True
|
469
|
+
elif isinstance(instruction.operation, ControlFlowOp):
|
470
|
+
for block in instruction.operation.blocks:
|
471
|
+
if has_realtime_logic(block):
|
472
|
+
return True
|
473
|
+
return False
|
474
|
+
|
475
|
+
.. _providers-guide-backend-run:
|
476
|
+
|
477
|
+
Backend.run Method
|
478
|
+
------------------
|
479
|
+
|
480
|
+
Of key importance is the :meth:`~qiskit.providers.BackendV2.run` method, which
|
481
|
+
is used to actually submit circuits to a device or simulator. The run method
|
482
|
+
handles submitting the circuits to the backend to be executed and returning a
|
483
|
+
:class:`~qiskit.providers.Job` object. Depending on the type of backend this
|
484
|
+
typically involves serializing the circuit object into the API format used by a
|
485
|
+
backend. For example, on IBM backends from the ``qiskit-ibm-provider``
|
486
|
+
package this involves converting from a quantum circuit and options into a
|
487
|
+
:mod:`.qpy` payload embedded in JSON and submitting that to the IBM Quantum
|
488
|
+
API. Since every backend interface is different (and in the case of the local
|
489
|
+
simulators serialization may not be needed) it is expected that the backend's
|
490
|
+
:obj:`~qiskit.providers.BackendV2.run` method will handle this conversion.
|
491
|
+
|
492
|
+
An example run method would be something like::
|
493
|
+
|
494
|
+
def run(self, circuits. **kwargs):
|
495
|
+
for kwarg in kwargs:
|
496
|
+
if not hasattr(kwarg, self.options):
|
497
|
+
warnings.warn(
|
498
|
+
"Option %s is not used by this backend" % kwarg,
|
499
|
+
UserWarning, stacklevel=2)
|
500
|
+
options = {
|
501
|
+
'shots': kwargs.get('shots', self.options.shots)
|
502
|
+
'memory': kwargs.get('memory', self.options.shots),
|
503
|
+
}
|
504
|
+
job_json = convert_to_wire_format(circuit, options)
|
505
|
+
job_handle = submit_to_backend(job_jsonb)
|
506
|
+
return MyJob(self. job_handle, job_json, circuit)
|
507
|
+
|
508
|
+
Backend Options
|
509
|
+
---------------
|
510
|
+
|
511
|
+
There are often several options for a backend that control how a circuit is run.
|
512
|
+
The typical example of this is something like the number of ``shots`` which is
|
513
|
+
how many times the circuit is to be executed. The options available for a
|
514
|
+
backend are defined using an :class:`~qiskit.providers.Options` object. This
|
515
|
+
object is initially created by the
|
516
|
+
:obj:`~qiskit.providers.BackendV2._default_options` method of a Backend class.
|
517
|
+
The default options returns an initialized :class:`~qiskit.providers.Options`
|
518
|
+
object with all the default values for all the options a backend supports. For
|
519
|
+
example, if the backend supports only supports ``shots`` the
|
520
|
+
:obj:`~qiskit.providers.BackendV2._default_options` method would look like::
|
521
|
+
|
522
|
+
@classmethod
|
523
|
+
def _default_options(cls):
|
524
|
+
return Options(shots=1024)
|
525
|
+
|
526
|
+
You can also set validators on an :class:`~qiskit.providers.Options` object to
|
527
|
+
provide limits and validation on user provided values based on what's acceptable
|
528
|
+
for your backend. For example, if the ``"shots"`` option defined above can be set
|
529
|
+
to any value between 1 and 4096 you can set the validator on the options object
|
530
|
+
for you backend with::
|
531
|
+
|
532
|
+
self.options.set_validator("shots", (1, 4096))
|
533
|
+
|
534
|
+
you can refer to the :meth:`~qiskit.providers.Options.set_validator` documentation
|
535
|
+
for a full list of validation options.
|
536
|
+
|
537
|
+
|
538
|
+
Job
|
539
|
+
---
|
540
|
+
|
541
|
+
The output from the :obj:`~qiskit.providers.BackendV2.run` method is a :class:`~qiskit.providers.JobV1`
|
542
|
+
object. Each provider is expected to implement a custom job subclass that
|
543
|
+
defines the behavior for the provider. There are 2 types of jobs depending on
|
544
|
+
the backend's execution method, either a sync or async. By default jobs are
|
545
|
+
considered async and the expectation is that it represents a handle to the
|
546
|
+
async execution of the circuits submitted with ``Backend.run()``. An async
|
547
|
+
job object provides users the ability to query the status of the execution,
|
548
|
+
cancel a running job, and block until the execution is finished. The
|
549
|
+
:obj:`~qiskit.providers.JobV1.result` is the primary user facing method
|
550
|
+
which will block until the execution is complete and then will return a
|
551
|
+
:class:`~qiskit.result.Result` object with results of the job.
|
552
|
+
|
553
|
+
For some backends (mainly local simulators) the execution of circuits is a
|
554
|
+
synchronous operation and there is no need to return a handle to a running job
|
555
|
+
elsewhere. For sync jobs its expected that the
|
556
|
+
:obj:`~qiskit.providers.BackendV2.run` method on the backend will block until a
|
557
|
+
:class:`~qiskit.result.Result` object is generated and the sync job will return
|
558
|
+
with that inner :class:`~qiskit.result.Result` object.
|
559
|
+
|
560
|
+
An example job class for an async API based backend would look something like::
|
561
|
+
|
562
|
+
from qiskit.providers import JobV1 as Job
|
563
|
+
from qiskit.providers import JobError
|
564
|
+
from qiskit.providers import JobTimeoutError
|
565
|
+
from qiskit.providers.jobstatus import JobStatus
|
566
|
+
from qiskit.result import Result
|
567
|
+
|
568
|
+
|
569
|
+
class MyJob(Job):
|
570
|
+
def __init__(self, backend, job_id, job_json, circuits):
|
571
|
+
super().__init__(backend, job_id)
|
572
|
+
self._backend = backend
|
573
|
+
self.job_json = job_json
|
574
|
+
self.circuits = circuits
|
575
|
+
|
576
|
+
def _wait_for_result(self, timeout=None, wait=5):
|
577
|
+
start_time = time.time()
|
578
|
+
result = None
|
579
|
+
while True:
|
580
|
+
elapsed = time.time() - start_time
|
581
|
+
if timeout and elapsed >= timeout:
|
582
|
+
raise JobTimeoutError('Timed out waiting for result')
|
583
|
+
result = get_job_status(self._job_id)
|
584
|
+
if result['status'] == 'complete':
|
585
|
+
break
|
586
|
+
if result['status'] == 'error':
|
587
|
+
raise JobError('Job error')
|
588
|
+
time.sleep(wait)
|
589
|
+
return result
|
590
|
+
|
591
|
+
def result(self, timeout=None, wait=5):
|
592
|
+
result = self._wait_for_result(timeout, wait)
|
593
|
+
results = [{'success': True, 'shots': len(result['counts']),
|
594
|
+
'data': result['counts']}]
|
595
|
+
return Result.from_dict({
|
596
|
+
'results': results,
|
597
|
+
'backend_name': self._backend.configuration().backend_name,
|
598
|
+
'backend_version': self._backend.configuration().backend_version,
|
599
|
+
'job_id': self._job_id,
|
600
|
+
'success': True,
|
601
|
+
})
|
602
|
+
|
603
|
+
def status(self):
|
604
|
+
result = get_job_status(self._job_id)
|
605
|
+
if result['status'] == 'running':
|
606
|
+
status = JobStatus.RUNNING
|
607
|
+
elif result['status'] == 'complete':
|
608
|
+
status = JobStatus.DONE
|
609
|
+
else:
|
610
|
+
status = JobStatus.ERROR
|
611
|
+
return status
|
612
|
+
|
613
|
+
def submit(self):
|
614
|
+
raise NotImplementedError
|
615
|
+
|
616
|
+
and for a sync job::
|
617
|
+
|
618
|
+
class MySyncJob(Job):
|
619
|
+
_async = False
|
620
|
+
|
621
|
+
def __init__(self, backend, job_id, result):
|
622
|
+
super().__init__(backend, job_id)
|
623
|
+
self._result = result
|
624
|
+
|
625
|
+
def submit(self):
|
626
|
+
return
|
627
|
+
|
628
|
+
def result(self):
|
629
|
+
return self._result
|
630
|
+
|
631
|
+
def status(self):
|
632
|
+
return JobStatus.DONE
|
633
|
+
|
634
|
+
Primitives
|
635
|
+
----------
|
636
|
+
|
637
|
+
While not directly part of the provider interface, the :mod:`qiskit.primitives`
|
638
|
+
module is tightly coupled with providers. Specifically the primitive
|
639
|
+
interfaces, such as :class:`~.BaseSampler` and :class:`~.BaseEstimator`,
|
640
|
+
are designed to enable provider implementations to provide custom
|
641
|
+
implementations which are optimized for the provider's backends. This can
|
642
|
+
include customizations like circuit transformations, additional pre- and
|
643
|
+
post-processing, batching, caching, error mitigation, etc. The concept of
|
644
|
+
the :mod:`qiskit.primitives` module is to explicitly enable this as the
|
645
|
+
primitive objects are higher level abstractions to produce processed higher
|
646
|
+
level outputs (such as probability distributions and expectation values)
|
647
|
+
that abstract away the mechanics of getting the best result efficiently, to
|
648
|
+
concentrate on higher level applications using these outputs.
|
649
|
+
|
650
|
+
For example, if your backends were well suited to leverage
|
651
|
+
`mthree <https://github.com/Qiskit/qiskit-addon-mthree>`__ measurement
|
652
|
+
mitigation to improve the quality of the results, you could implement a
|
653
|
+
provider-specific :class:`~.Sampler` implementation that leverages the
|
654
|
+
``M3Mitigation`` class internally to run the circuits and return
|
655
|
+
quasi-probabilities directly from mthree in the result. Doing this would
|
656
|
+
enable algorithms to get the best results with
|
657
|
+
mitigation applied directly from your backends. You can refer to the
|
658
|
+
documentation in :mod:`qiskit.primitives` on how to write custom
|
659
|
+
implementations. Also, the built-in implementations: :class:`~.Sampler`,
|
660
|
+
:class:`~.Estimator`, :class:`~.BackendSampler`, and :class:`~.BackendEstimator`
|
661
|
+
can serve as references/models on how to implement these as well.
|
662
|
+
"""
|
663
|
+
|
664
|
+
# Providers interface
|
665
|
+
from qiskit.providers.backend import Backend
|
666
|
+
from qiskit.providers.backend import BackendV2
|
667
|
+
from qiskit.providers.backend import QubitProperties
|
668
|
+
from qiskit.providers.options import Options
|
669
|
+
from qiskit.providers.job import Job
|
670
|
+
from qiskit.providers.job import JobV1
|
671
|
+
|
672
|
+
from qiskit.providers.exceptions import (
|
673
|
+
JobError,
|
674
|
+
JobTimeoutError,
|
675
|
+
QiskitBackendNotFoundError,
|
676
|
+
)
|
677
|
+
from qiskit.providers.jobstatus import JobStatus
|