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,354 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2022.
|
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
|
+
.. currentmodule:: qiskit.utils.optionals
|
15
|
+
|
16
|
+
Qiskit has several features that are enabled only if certain *optional* dependencies
|
17
|
+
are satisfied. This module, :mod:`qiskit.utils.optionals`, has a collection of objects that can
|
18
|
+
be used to test if certain functionality is available, and optionally raise
|
19
|
+
:class:`.MissingOptionalLibraryError` if the functionality is not available.
|
20
|
+
|
21
|
+
|
22
|
+
Available Testers
|
23
|
+
=================
|
24
|
+
|
25
|
+
Qiskit Components
|
26
|
+
-----------------
|
27
|
+
|
28
|
+
.. py:data:: HAS_AER
|
29
|
+
|
30
|
+
`Qiskit Aer <https://qiskit.github.io/qiskit-aer/>` provides high-performance simulators for
|
31
|
+
the quantum circuits constructed within Qiskit.
|
32
|
+
|
33
|
+
.. py:data:: HAS_IBMQ
|
34
|
+
|
35
|
+
The :mod:`Qiskit IBMQ Provider <qiskit.providers.ibmq>` is used for accessing IBM Quantum
|
36
|
+
hardware in the IBM cloud.
|
37
|
+
|
38
|
+
.. py:data:: HAS_IGNIS
|
39
|
+
|
40
|
+
:mod:`Qiskit Ignis <qiskit.ignis>` provides tools for quantum hardware verification, noise
|
41
|
+
characterization, and error correction.
|
42
|
+
|
43
|
+
.. py:data:: HAS_TOQM
|
44
|
+
|
45
|
+
`Qiskit TOQM <https://github.com/qiskit-toqm/qiskit-toqm>`__ provides transpiler passes
|
46
|
+
for the `Time-optimal Qubit mapping algorithm <https://doi.org/10.1145/3445814.3446706>`__.
|
47
|
+
|
48
|
+
|
49
|
+
External Python Libraries
|
50
|
+
-------------------------
|
51
|
+
|
52
|
+
.. py:data:: HAS_CONSTRAINT
|
53
|
+
|
54
|
+
`python-constraint <https://github.com/python-constraint/python-constraint>`__ is a
|
55
|
+
constraint satisfaction problem solver, used in the :class:`~.CSPLayout` transpiler pass.
|
56
|
+
|
57
|
+
.. py:data:: HAS_CPLEX
|
58
|
+
|
59
|
+
The `IBM CPLEX Optimizer <https://www.ibm.com/analytics/cplex-optimizer>`__ is a
|
60
|
+
high-performance mathematical programming solver for linear, mixed-integer and quadratic
|
61
|
+
programming. This is no longer by Qiskit, but it weas historically and the optional
|
62
|
+
remains for backwards compatibility.
|
63
|
+
|
64
|
+
.. py:data:: HAS_CVXPY
|
65
|
+
|
66
|
+
`CVXPY <https://www.cvxpy.org/>`__ is a Python package for solving convex optimization
|
67
|
+
problems. It is required for calculating diamond norms with
|
68
|
+
:func:`.quantum_info.diamond_norm`.
|
69
|
+
|
70
|
+
.. py:data:: HAS_DOCPLEX
|
71
|
+
|
72
|
+
`IBM Decision Optimization CPLEX Modelling
|
73
|
+
<http://ibmdecisionoptimization.github.io/docplex-doc/>`__ is a library for prescriptive
|
74
|
+
analysis. Like CPLEX, this is no longer by Qiskit, but it weas historically and the
|
75
|
+
optional remains for backwards compatibility.
|
76
|
+
|
77
|
+
.. py:data:: HAS_FIXTURES
|
78
|
+
|
79
|
+
The test suite has additional features that are available if the optional `fixtures
|
80
|
+
<https://launchpad.net/python-fixtures>`__ module is installed. This generally also needs
|
81
|
+
:data:`HAS_TESTTOOLS` as well. This is generally only needed for Qiskit developers.
|
82
|
+
|
83
|
+
.. py:data:: HAS_IPYTHON
|
84
|
+
|
85
|
+
If `the IPython kernel <https://ipython.org/>`__ is available, certain additional
|
86
|
+
visualizations and line magics are made available.
|
87
|
+
|
88
|
+
.. py:data:: HAS_IPYWIDGETS
|
89
|
+
|
90
|
+
Monitoring widgets for jobs running on external backends can be provided if `ipywidgets
|
91
|
+
<https://ipywidgets.readthedocs.io/en/latest/>`__ is available.
|
92
|
+
|
93
|
+
.. py:data:: HAS_JAX
|
94
|
+
|
95
|
+
Some methods of gradient calculation within :mod:`.opflow.gradients` require `JAX
|
96
|
+
<https://github.com/google/jax>`__ for autodifferentiation.
|
97
|
+
|
98
|
+
.. py:data:: HAS_JUPYTER
|
99
|
+
|
100
|
+
Some of the tests require a complete `Jupyter <https://jupyter.org/>`__ installation to test
|
101
|
+
interactivity features.
|
102
|
+
|
103
|
+
.. py:data:: HAS_MATPLOTLIB
|
104
|
+
|
105
|
+
Qiskit provides several visualization tools in the :mod:`.visualization` module.
|
106
|
+
Almost all of these are built using `Matplotlib <https://matplotlib.org/>`__, which must
|
107
|
+
be installed in order to use them.
|
108
|
+
|
109
|
+
.. py:data:: HAS_NETWORKX
|
110
|
+
|
111
|
+
No longer used by Qiskit. Internally, Qiskit now uses the high-performance `rustworkx
|
112
|
+
<https://github.com/Qiskit/rustworkx>`__ library as a core dependency, and during the
|
113
|
+
change-over period, it was sometimes convenient to convert things into the Python-only
|
114
|
+
`NetworkX <https://networkx.org/>`__ format. Some tests of application modules, such as
|
115
|
+
`Qiskit Nature <https://qiskit-community.github.io/qiskit-nature/>`__ still use NetworkX.
|
116
|
+
|
117
|
+
.. py:data:: HAS_NLOPT
|
118
|
+
|
119
|
+
`NLopt <https://nlopt.readthedocs.io/en/latest/>`__ is a nonlinear optimization library,
|
120
|
+
used by the global optimizers in the :mod:`.algorithms.optimizers` module.
|
121
|
+
|
122
|
+
.. py:data:: HAS_PIL
|
123
|
+
|
124
|
+
PIL is a Python image-manipulation library. Qiskit actually uses the `pillow
|
125
|
+
<https://pillow.readthedocs.io/en/stable/>`__ fork of PIL if it is available when generating
|
126
|
+
certain visualizations, for example of both :class:`.QuantumCircuit` and
|
127
|
+
:class:`.DAGCircuit` in certain modes.
|
128
|
+
|
129
|
+
.. py:data:: HAS_PYDOT
|
130
|
+
|
131
|
+
For some graph visualizations, Qiskit uses `pydot <https://github.com/pydot/pydot>`__ as an
|
132
|
+
interface to GraphViz (see :data:`HAS_GRAPHVIZ`).
|
133
|
+
|
134
|
+
.. py:data:: HAS_PYGMENTS
|
135
|
+
|
136
|
+
Pygments is a code highlighter and formatter used by many environments that involve rich
|
137
|
+
display of code blocks, including Sphinx and Jupyter. Qiskit uses this when producing rich
|
138
|
+
output for these environments.
|
139
|
+
|
140
|
+
.. py:data:: HAS_PYLATEX
|
141
|
+
|
142
|
+
Various LaTeX-based visualizations, especially the circuit drawers, need access to the
|
143
|
+
`pylatexenc <https://github.com/phfaist/pylatexenc>`__ project to work correctly.
|
144
|
+
|
145
|
+
.. py:data:: HAS_QASM3_IMPORT
|
146
|
+
|
147
|
+
The functions :func:`.qasm3.load` and :func:`.qasm3.loads` for importing OpenQASM 3 programs
|
148
|
+
into :class:`.QuantumCircuit` instances use `an external importer package
|
149
|
+
<https://qiskit.github.io/qiskit-qasm3-import>`__.
|
150
|
+
|
151
|
+
.. py:data:: HAS_SEABORN
|
152
|
+
|
153
|
+
Qiskit provides several visualization tools in the :mod:`.visualization` module. Some
|
154
|
+
of these are built using `Seaborn <https://seaborn.pydata.org/>`__, which must be installed
|
155
|
+
in order to use them.
|
156
|
+
|
157
|
+
.. py:data:: HAS_SKLEARN
|
158
|
+
|
159
|
+
Some of the gradient functions in :mod:`.opflow.gradients` use regularisation methods from
|
160
|
+
`Scikit Learn <https://scikit-learn.org/stable/>`__.
|
161
|
+
|
162
|
+
.. py:data:: HAS_SKQUANT
|
163
|
+
|
164
|
+
Some of the optimisers in :mod:`.algorithms.optimizers` are based on those found in `Scikit
|
165
|
+
Quant <https://github.com/scikit-quant/scikit-quant>`__, which must be installed to use
|
166
|
+
them.
|
167
|
+
|
168
|
+
.. py:data:: HAS_SQSNOBFIT
|
169
|
+
|
170
|
+
`SQSnobFit <https://pypi.org/project/SQSnobFit/>`__ is a library for the "stable noisy
|
171
|
+
optimization by branch and fit" algorithm. It is used by the :class:`.SNOBFIT` optimizer.
|
172
|
+
|
173
|
+
.. py:data:: HAS_SYMENGINE
|
174
|
+
|
175
|
+
`Symengine <https://github.com/symengine/symengine>`__ is a fast C++ backend for the
|
176
|
+
symbolic-manipulation library `Sympy <https://www.sympy.org/en/index.html>`__. Qiskit uses
|
177
|
+
special methods from Symengine to accelerate its handling of
|
178
|
+
:class:`~.circuit.Parameter`\\ s if available.
|
179
|
+
|
180
|
+
.. py:data:: HAS_SYMPY
|
181
|
+
|
182
|
+
`SymPy <https://www.sympy.org/en/index.html>`__ is Python library for symbolic mathematics.
|
183
|
+
Sympy was historically used for the implementation of the :class:`.ParameterExpression`
|
184
|
+
class but isn't any longer. However it is needed for some legacy functionality that uses
|
185
|
+
:meth:`.ParameterExpression.sympify`. It is also used in some visualization functions.
|
186
|
+
|
187
|
+
.. py:data:: HAS_TESTTOOLS
|
188
|
+
|
189
|
+
Qiskit's test suite has more advanced functionality available if the optional
|
190
|
+
`testtools <https://pypi.org/project/testtools/>`__ library is installed. This is generally
|
191
|
+
only needed for Qiskit developers.
|
192
|
+
|
193
|
+
.. py:data:: HAS_TWEEDLEDUM
|
194
|
+
|
195
|
+
`Tweedledum <https://github.com/boschmitt/tweedledum>`__ is an extension library for
|
196
|
+
synthesis and optimization of circuits that may involve classical oracles. In the past
|
197
|
+
Qiskit's :class:`.PhaseOracle` used this but it is no longer used by Qiskit.
|
198
|
+
|
199
|
+
.. py:data:: HAS_Z3
|
200
|
+
|
201
|
+
`Z3 <https://github.com/Z3Prover/z3>`__ is a theorem prover, used in the
|
202
|
+
:class:`.CrosstalkAdaptiveSchedule` and :class:`.HoareOptimizer` transpiler passes.
|
203
|
+
|
204
|
+
External Command-Line Tools
|
205
|
+
---------------------------
|
206
|
+
|
207
|
+
.. py:data:: HAS_GRAPHVIZ
|
208
|
+
|
209
|
+
For some graph visualizations, Qiskit uses the `GraphViz <https://graphviz.org/>`__
|
210
|
+
visualization tool via its ``pydot`` interface (see :data:`HAS_PYDOT`).
|
211
|
+
|
212
|
+
.. py:data:: HAS_PDFLATEX
|
213
|
+
|
214
|
+
Visualization tools that use LaTeX in their output, such as the circuit drawers, require
|
215
|
+
``pdflatex`` to be available. You will generally need to ensure that you have a working
|
216
|
+
LaTeX installation available, and the ``qcircuit.tex`` package.
|
217
|
+
|
218
|
+
.. py:data:: HAS_PDFTOCAIRO
|
219
|
+
|
220
|
+
Visualization tools that convert LaTeX-generated files into rasterized images use the
|
221
|
+
``pdftocairo`` tool. This is part of the `Poppler suite of PDF tools
|
222
|
+
<https://poppler.freedesktop.org/>`__.
|
223
|
+
|
224
|
+
|
225
|
+
Lazy Checker Classes
|
226
|
+
====================
|
227
|
+
|
228
|
+
.. currentmodule:: qiskit.utils
|
229
|
+
|
230
|
+
Each of the lazy checkers is an instance of :class:`.LazyDependencyManager` in one of its two
|
231
|
+
subclasses: :class:`.LazyImportTester` and :class:`.LazySubprocessTester`. These should be imported
|
232
|
+
from :mod:`.utils` directly if required, such as::
|
233
|
+
|
234
|
+
from qiskit.utils import LazyImportTester
|
235
|
+
|
236
|
+
.. autoclass:: qiskit.utils.LazyDependencyManager
|
237
|
+
:members:
|
238
|
+
|
239
|
+
.. autoclass:: qiskit.utils.LazyImportTester
|
240
|
+
.. autoclass:: qiskit.utils.LazySubprocessTester
|
241
|
+
"""
|
242
|
+
|
243
|
+
# NOTE: If you're changing this file, sync it with `requirements-optional.txt` and potentially
|
244
|
+
# `pyproject.toml` as well.
|
245
|
+
|
246
|
+
import logging as _logging
|
247
|
+
|
248
|
+
from .lazy_tester import (
|
249
|
+
LazyImportTester as _LazyImportTester,
|
250
|
+
LazySubprocessTester as _LazySubprocessTester,
|
251
|
+
)
|
252
|
+
|
253
|
+
_logger = _logging.getLogger(__name__)
|
254
|
+
|
255
|
+
HAS_AER = _LazyImportTester(
|
256
|
+
"qiskit_aer",
|
257
|
+
name="Qiskit Aer",
|
258
|
+
install="pip install qiskit-aer",
|
259
|
+
)
|
260
|
+
HAS_IBMQ = _LazyImportTester(
|
261
|
+
"qiskit.providers.ibmq",
|
262
|
+
name="IBMQ Provider",
|
263
|
+
install="pip install qiskit-ibmq-provider",
|
264
|
+
)
|
265
|
+
HAS_IGNIS = _LazyImportTester(
|
266
|
+
"qiskit.ignis",
|
267
|
+
name="Qiskit Ignis",
|
268
|
+
install="pip install qiskit-ignis",
|
269
|
+
)
|
270
|
+
HAS_TOQM = _LazyImportTester("qiskit_toqm", name="Qiskit TOQM", install="pip install qiskit-toqm")
|
271
|
+
|
272
|
+
HAS_CONSTRAINT = _LazyImportTester(
|
273
|
+
"constraint",
|
274
|
+
name="python-constraint",
|
275
|
+
install="pip install python-constraint",
|
276
|
+
)
|
277
|
+
|
278
|
+
HAS_CPLEX = _LazyImportTester(
|
279
|
+
"cplex",
|
280
|
+
install="pip install cplex",
|
281
|
+
msg="This may not be possible for all Python versions and OSes",
|
282
|
+
)
|
283
|
+
HAS_CVXPY = _LazyImportTester("cvxpy", install="pip install cvxpy")
|
284
|
+
HAS_DOCPLEX = _LazyImportTester(
|
285
|
+
{"docplex": (), "docplex.mp.model": ("Model",)},
|
286
|
+
install="pip install docplex",
|
287
|
+
msg="This may not be possible for all Python versions and OSes",
|
288
|
+
)
|
289
|
+
HAS_FIXTURES = _LazyImportTester("fixtures", install="pip install fixtures")
|
290
|
+
HAS_IPYTHON = _LazyImportTester("IPython", install="pip install ipython")
|
291
|
+
HAS_IPYWIDGETS = _LazyImportTester("ipywidgets", install="pip install ipywidgets")
|
292
|
+
HAS_JAX = _LazyImportTester(
|
293
|
+
{"jax": ("grad", "jit"), "jax.numpy": ()},
|
294
|
+
name="jax",
|
295
|
+
install="pip install jax",
|
296
|
+
)
|
297
|
+
HAS_JUPYTER = _LazyImportTester(["jupyter", "nbformat", "nbconvert"], install="pip install jupyter")
|
298
|
+
HAS_MATPLOTLIB = _LazyImportTester(
|
299
|
+
("matplotlib.patches", "matplotlib.pyplot"),
|
300
|
+
name="matplotlib",
|
301
|
+
install="pip install matplotlib",
|
302
|
+
)
|
303
|
+
HAS_NETWORKX = _LazyImportTester("networkx", install="pip install networkx")
|
304
|
+
|
305
|
+
HAS_NLOPT = _LazyImportTester("nlopt", name="NLopt Optimizer", install="pip install nlopt")
|
306
|
+
HAS_PIL = _LazyImportTester("PIL.Image", name="pillow", install="pip install pillow")
|
307
|
+
HAS_PYDOT = _LazyImportTester("pydot", install="pip install pydot")
|
308
|
+
HAS_PYGMENTS = _LazyImportTester("pygments", install="pip install pygments")
|
309
|
+
HAS_PYLATEX = _LazyImportTester(
|
310
|
+
{
|
311
|
+
"pylatexenc.latex2text": ("LatexNodes2Text",),
|
312
|
+
"pylatexenc.latexencode": ("utf8tolatex",),
|
313
|
+
},
|
314
|
+
name="pylatexenc",
|
315
|
+
install="pip install pylatexenc",
|
316
|
+
)
|
317
|
+
HAS_QASM3_IMPORT = _LazyImportTester(
|
318
|
+
"qiskit_qasm3_import", install="pip install qiskit_qasm3_import"
|
319
|
+
)
|
320
|
+
HAS_SEABORN = _LazyImportTester("seaborn", install="pip install seaborn")
|
321
|
+
HAS_SKLEARN = _LazyImportTester(
|
322
|
+
{"sklearn.linear_model": ("Ridge", "Lasso")},
|
323
|
+
name="scikit-learn",
|
324
|
+
install="pip install scikit-learn",
|
325
|
+
)
|
326
|
+
HAS_SKQUANT = _LazyImportTester(
|
327
|
+
"skquant.opt",
|
328
|
+
name="scikit-quant",
|
329
|
+
install="pip install scikit-quant",
|
330
|
+
)
|
331
|
+
HAS_SQSNOBFIT = _LazyImportTester("SQSnobFit", install="pip install SQSnobFit")
|
332
|
+
HAS_SYMENGINE = _LazyImportTester("symengine", install="pip install symengine<0.14")
|
333
|
+
HAS_SYMPY = _LazyImportTester("sympy", install="pip install sympy")
|
334
|
+
HAS_TESTTOOLS = _LazyImportTester("testtools", install="pip install testtools")
|
335
|
+
HAS_TWEEDLEDUM = _LazyImportTester("tweedledum", install="pip install tweedledum")
|
336
|
+
HAS_Z3 = _LazyImportTester("z3", install="pip install z3-solver")
|
337
|
+
|
338
|
+
HAS_GRAPHVIZ = _LazySubprocessTester(
|
339
|
+
("dot", "-V"),
|
340
|
+
name="Graphviz",
|
341
|
+
msg=(
|
342
|
+
"To install, follow the instructions at https://graphviz.org/download/."
|
343
|
+
" Qiskit needs the Graphviz binaries, which the 'graphviz' package on pip does not install."
|
344
|
+
" You must install the actual Graphviz software"
|
345
|
+
),
|
346
|
+
)
|
347
|
+
HAS_PDFLATEX = _LazySubprocessTester(
|
348
|
+
("pdflatex", "-version"),
|
349
|
+
msg="You will likely need to install a full LaTeX distribution for your system",
|
350
|
+
)
|
351
|
+
HAS_PDFTOCAIRO = _LazySubprocessTester(
|
352
|
+
("pdftocairo", "-v"),
|
353
|
+
msg="This is part of the 'poppler' set of PDF utilities",
|
354
|
+
)
|
qiskit/utils/parallel.py
ADDED
@@ -0,0 +1,318 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2024.
|
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
|
+
# The original implementation of Qiskit's `parallel_map` in our commit c9c4ed52 was substantially
|
14
|
+
# derived from QuTiP's (https://github.com/qutip/qutip) in `qutip/parallel.py` at their commit
|
15
|
+
# f22d3cb7. It has subsequently been significantly rewritten.
|
16
|
+
#
|
17
|
+
# The original implementation was used under these licence terms:
|
18
|
+
#
|
19
|
+
# Copyright (c) 2011 and later, Paul D. Nation and Robert J. Johansson.
|
20
|
+
# All rights reserved.
|
21
|
+
#
|
22
|
+
# Redistribution and use in source and binary forms, with or without
|
23
|
+
# modification, are permitted provided that the following conditions are
|
24
|
+
# met:
|
25
|
+
#
|
26
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
27
|
+
# this list of conditions and the following disclaimer.
|
28
|
+
#
|
29
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
30
|
+
# notice, this list of conditions and the following disclaimer in the
|
31
|
+
# documentation and/or other materials provided with the distribution.
|
32
|
+
#
|
33
|
+
# 3. Neither the name of the QuTiP: Quantum Toolbox in Python nor the names
|
34
|
+
# of its contributors may be used to endorse or promote products derived
|
35
|
+
# from this software without specific prior written permission.
|
36
|
+
#
|
37
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
38
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
39
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
40
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
41
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
42
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
43
|
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
44
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
45
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
46
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
47
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
48
|
+
###############################################################################
|
49
|
+
|
50
|
+
"""
|
51
|
+
Routines for running Python functions in parallel using process pools
|
52
|
+
from the multiprocessing library.
|
53
|
+
"""
|
54
|
+
|
55
|
+
from __future__ import annotations
|
56
|
+
|
57
|
+
import contextlib
|
58
|
+
import functools
|
59
|
+
import multiprocessing
|
60
|
+
import os
|
61
|
+
import platform
|
62
|
+
import sys
|
63
|
+
import warnings
|
64
|
+
from concurrent.futures import ProcessPoolExecutor
|
65
|
+
|
66
|
+
from qiskit import user_config
|
67
|
+
|
68
|
+
|
69
|
+
CONFIG = user_config.get_config()
|
70
|
+
|
71
|
+
|
72
|
+
def _task_wrapper(param):
|
73
|
+
(task, value, task_args, task_kwargs) = param
|
74
|
+
return task(value, *task_args, **task_kwargs)
|
75
|
+
|
76
|
+
|
77
|
+
def _physical_cpus_assuming_twofold_smt():
|
78
|
+
if (sched_getaffinity := getattr(os, "sched_getaffinity", None)) is not None:
|
79
|
+
# It is callable, just pylint doesn't recognise it as `os.sched_getaffinity` because of the
|
80
|
+
# `getattr`.
|
81
|
+
# pylint: disable=not-callable
|
82
|
+
num_cpus = len(sched_getaffinity(0))
|
83
|
+
else:
|
84
|
+
num_cpus = os.cpu_count() or 1
|
85
|
+
return (num_cpus // 2) or 1
|
86
|
+
|
87
|
+
|
88
|
+
def _parallel_default():
|
89
|
+
# We default to False on `spawn`-based multiprocessing implementations, True on everything else.
|
90
|
+
if (set_start_method := multiprocessing.get_start_method(allow_none=True)) is None:
|
91
|
+
# The method hasn't been explicitly set, but it would be badly behaved of us to set it for
|
92
|
+
# the user, so handle platform defaults.
|
93
|
+
return sys.platform not in ("darwin", "win32")
|
94
|
+
return set_start_method in ("fork", "forkserver")
|
95
|
+
|
96
|
+
|
97
|
+
@functools.cache
|
98
|
+
def default_num_processes() -> int:
|
99
|
+
"""Get the number of processes that a multiprocessing parallel call will use by default.
|
100
|
+
|
101
|
+
Such functions typically also accept a ``num_processes`` keyword argument that will supersede
|
102
|
+
the value returned from this function.
|
103
|
+
|
104
|
+
In order of priority (highest to lowest), the return value will be:
|
105
|
+
|
106
|
+
1. The ``QISKIT_NUM_PROCS`` environment variable, if set.
|
107
|
+
2. The ``num_processes`` key of the Qiskit user configuration file, if set.
|
108
|
+
3. Half of the logical CPUs available to this process, if this can be determined. This is a
|
109
|
+
proxy for the number of physical CPUs, assuming two-fold simultaneous multithreading (SMT);
|
110
|
+
empirically, multiprocessing performance of Qiskit seems to be worse when attempting to use
|
111
|
+
SMT cores.
|
112
|
+
4. 1, if all else fails.
|
113
|
+
|
114
|
+
If a user-configured value is set to a number less than 1, it is treated as if it were 1.
|
115
|
+
"""
|
116
|
+
# Ignore both `None` (unset) and explicit set to empty string.
|
117
|
+
if env_num_processes := os.getenv("QISKIT_NUM_PROCS"):
|
118
|
+
try:
|
119
|
+
env_num_processes = int(env_num_processes)
|
120
|
+
except ValueError:
|
121
|
+
# Invalid: fall back to other methods.
|
122
|
+
warnings.warn(
|
123
|
+
"failed to interpret environment 'QISKIT_NUM_PROCS' as a number:"
|
124
|
+
f" '{env_num_processes}'"
|
125
|
+
)
|
126
|
+
else:
|
127
|
+
return env_num_processes if env_num_processes > 0 else 1
|
128
|
+
if (user_num_processes := CONFIG.get("num_processes", None)) is not None:
|
129
|
+
return user_num_processes if user_num_processes > 0 else 1
|
130
|
+
return _physical_cpus_assuming_twofold_smt()
|
131
|
+
|
132
|
+
|
133
|
+
def local_hardware_info():
|
134
|
+
"""Basic hardware information about the local machine.
|
135
|
+
|
136
|
+
Attempts to estimate the number of physical CPUs in the machine, even when hyperthreading is
|
137
|
+
turned on. CPU count defaults to 1 when true count can't be determined.
|
138
|
+
|
139
|
+
Returns:
|
140
|
+
dict: The hardware information.
|
141
|
+
"""
|
142
|
+
return {
|
143
|
+
"python_compiler": platform.python_compiler(),
|
144
|
+
"python_build": ", ".join(platform.python_build()),
|
145
|
+
"python_version": platform.python_version(),
|
146
|
+
"os": platform.system(),
|
147
|
+
"cpus": _physical_cpus_assuming_twofold_smt(),
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
def is_main_process() -> bool:
|
152
|
+
"""Checks whether the current process is the main one.
|
153
|
+
|
154
|
+
Since Python 3.8, this is identical to the standard Python way of calculating this::
|
155
|
+
|
156
|
+
>>> import multiprocessing
|
157
|
+
>>> multiprocessing.parent_process() is None
|
158
|
+
|
159
|
+
This function is left for backwards compatibility, but there is little reason not to use the
|
160
|
+
built-in tooling of Python.
|
161
|
+
"""
|
162
|
+
return multiprocessing.parent_process() is None
|
163
|
+
|
164
|
+
|
165
|
+
_PARALLEL_OVERRIDE = None
|
166
|
+
_PARALLEL_IGNORE_USER_SETTINGS = False
|
167
|
+
_IN_PARALLEL_ALLOW_PARALLELISM = "FALSE"
|
168
|
+
_IN_PARALLEL_FORBID_PARALLELISM = "TRUE"
|
169
|
+
|
170
|
+
|
171
|
+
@functools.cache
|
172
|
+
def should_run_in_parallel(num_processes: int | None = None) -> bool:
|
173
|
+
"""Decide whether a multiprocessing function should spawn subprocesses for parallelization.
|
174
|
+
|
175
|
+
In particular, this is how :func:`parallel_map` decides whether to use multiprocessing or not.
|
176
|
+
The ``num_processes`` argument alone does not enforce parallelism; by default, Qiskit will only
|
177
|
+
use process-based parallelism when a ``fork``-like process spawning start method is in effect.
|
178
|
+
You can override this decision either by setting the :mod:`multiprocessing` start method you
|
179
|
+
use, setting the ``QISKIT_PARALLEL`` environment variable to ``"TRUE"``, or setting
|
180
|
+
``parallel = true`` in your user settings file.
|
181
|
+
|
182
|
+
This function includes two context managers that can be used to temporarily modify the return
|
183
|
+
value of this function:
|
184
|
+
|
185
|
+
.. autofunction:: qiskit.utils::should_run_in_parallel.override
|
186
|
+
.. autofunction:: qiskit.utils::should_run_in_parallel.ignore_user_settings
|
187
|
+
|
188
|
+
Args:
|
189
|
+
num_processes: the maximum number of processes requested for use (``None`` implies the
|
190
|
+
default).
|
191
|
+
|
192
|
+
Examples:
|
193
|
+
Temporarily override the configured settings to disable parallelism::
|
194
|
+
|
195
|
+
>>> with should_run_in_parallel.override(True):
|
196
|
+
... assert should_run_in_parallel(8)
|
197
|
+
>>> with should_run_in_parallel.override(False):
|
198
|
+
... assert not should_run_in_parallel(8)
|
199
|
+
"""
|
200
|
+
# It's a configuration function with many simple choices - it'd be less clean to return late.
|
201
|
+
# pylint: disable=too-many-return-statements
|
202
|
+
num_processes = default_num_processes() if num_processes is None else num_processes
|
203
|
+
if num_processes < 2:
|
204
|
+
# There's no resources to parallelise over.
|
205
|
+
return False
|
206
|
+
if (
|
207
|
+
os.getenv("QISKIT_IN_PARALLEL", _IN_PARALLEL_ALLOW_PARALLELISM)
|
208
|
+
!= _IN_PARALLEL_ALLOW_PARALLELISM
|
209
|
+
):
|
210
|
+
# This isn't a user-set variable; we set this to talk to our own child processes.
|
211
|
+
return False
|
212
|
+
if _PARALLEL_OVERRIDE is not None:
|
213
|
+
return _PARALLEL_OVERRIDE
|
214
|
+
if _PARALLEL_IGNORE_USER_SETTINGS:
|
215
|
+
return _parallel_default()
|
216
|
+
if (env_qiskit_parallel := os.getenv("QISKIT_PARALLEL")) is not None:
|
217
|
+
return env_qiskit_parallel.lower() == "true"
|
218
|
+
if (user_qiskit_parallel := CONFIG.get("parallel_enabled", None)) is not None:
|
219
|
+
return user_qiskit_parallel
|
220
|
+
# Otherwise, fallback to the default.
|
221
|
+
return _parallel_default()
|
222
|
+
|
223
|
+
|
224
|
+
@contextlib.contextmanager
|
225
|
+
def _parallel_ignore_user_settings():
|
226
|
+
"""A context manager within which :func:`should_run_in_parallel` will ignore environmental
|
227
|
+
configuration variables.
|
228
|
+
|
229
|
+
In particular, the ``QISKIT_PARALLEL`` environment variable and the user-configuration file are
|
230
|
+
ignored within this context."""
|
231
|
+
# The way around this would be to encapsulate `should_run_in_parallel` into a class, but since
|
232
|
+
# it's a singleton, it ends up being functionally no different to a global anyway.
|
233
|
+
global _PARALLEL_IGNORE_USER_SETTINGS # pylint: disable=global-statement
|
234
|
+
|
235
|
+
should_run_in_parallel.cache_clear()
|
236
|
+
previous, _PARALLEL_IGNORE_USER_SETTINGS = _PARALLEL_IGNORE_USER_SETTINGS, True
|
237
|
+
try:
|
238
|
+
yield
|
239
|
+
finally:
|
240
|
+
_PARALLEL_IGNORE_USER_SETTINGS = previous
|
241
|
+
should_run_in_parallel.cache_clear()
|
242
|
+
|
243
|
+
|
244
|
+
@contextlib.contextmanager
|
245
|
+
def _parallel_override(value: bool):
|
246
|
+
"""A context manager within which :func:`should_run_in_parallel` will return the given
|
247
|
+
``value``.
|
248
|
+
|
249
|
+
This is not a *complete* override; Qiskit will never attempt to parallelize if only a single
|
250
|
+
process is available, and will not allow process-based parallelism at a depth greater than 1."""
|
251
|
+
# The way around this would be to encapsulate `should_run_in_parallel` into a class, but since
|
252
|
+
# it's a singleton, it ends up being functionally no different to a global anyway.
|
253
|
+
global _PARALLEL_OVERRIDE # pylint: disable=global-statement
|
254
|
+
|
255
|
+
should_run_in_parallel.cache_clear()
|
256
|
+
previous, _PARALLEL_OVERRIDE = _PARALLEL_OVERRIDE, value
|
257
|
+
try:
|
258
|
+
yield
|
259
|
+
finally:
|
260
|
+
_PARALLEL_OVERRIDE = previous
|
261
|
+
should_run_in_parallel.cache_clear()
|
262
|
+
|
263
|
+
|
264
|
+
should_run_in_parallel.ignore_user_settings = _parallel_ignore_user_settings
|
265
|
+
should_run_in_parallel.override = _parallel_override
|
266
|
+
|
267
|
+
|
268
|
+
def parallel_map(task, values, task_args=(), task_kwargs=None, num_processes=None):
|
269
|
+
"""
|
270
|
+
Parallel execution of a mapping of `values` to the function `task`. This
|
271
|
+
is functionally equivalent to::
|
272
|
+
|
273
|
+
result = [task(value, *task_args, **task_kwargs) for value in values]
|
274
|
+
|
275
|
+
This will parallelise the results if the number of ``values`` is greater than one and
|
276
|
+
:func:`should_run_in_parallel` returns ``True``. If not, it will run in serial.
|
277
|
+
|
278
|
+
Args:
|
279
|
+
task (func): Function that is to be called for each value in ``values``.
|
280
|
+
values (array_like): List or array of values for which the ``task`` function is to be
|
281
|
+
evaluated.
|
282
|
+
task_args (list): Optional additional arguments to the ``task`` function.
|
283
|
+
task_kwargs (dict): Optional additional keyword argument to the ``task`` function.
|
284
|
+
num_processes (int): Number of processes to spawn. If not given, the return value of
|
285
|
+
:func:`default_num_processes` is used.
|
286
|
+
|
287
|
+
Returns:
|
288
|
+
result: The result list contains the value of ``task(value, *task_args, **task_kwargs)`` for
|
289
|
+
each value in ``values``.
|
290
|
+
|
291
|
+
Examples:
|
292
|
+
|
293
|
+
.. plot::
|
294
|
+
:include-source:
|
295
|
+
:nofigs:
|
296
|
+
|
297
|
+
import time
|
298
|
+
from qiskit.utils import parallel_map
|
299
|
+
def func(_):
|
300
|
+
time.sleep(0.1)
|
301
|
+
return 0
|
302
|
+
parallel_map(func, list(range(10)));
|
303
|
+
"""
|
304
|
+
task_kwargs = {} if task_kwargs is None else task_kwargs
|
305
|
+
if num_processes is None:
|
306
|
+
num_processes = default_num_processes()
|
307
|
+
if len(values) < 2 or not should_run_in_parallel(num_processes):
|
308
|
+
return [task(value, *task_args, **task_kwargs) for value in values]
|
309
|
+
work_items = ((task, value, task_args, task_kwargs) for value in values)
|
310
|
+
|
311
|
+
# This isn't a user-set variable; we set this to talk to our own child processes.
|
312
|
+
previous_in_parallel = os.getenv("QISKIT_IN_PARALLEL", _IN_PARALLEL_ALLOW_PARALLELISM)
|
313
|
+
os.environ["QISKIT_IN_PARALLEL"] = _IN_PARALLEL_FORBID_PARALLELISM
|
314
|
+
try:
|
315
|
+
with ProcessPoolExecutor(max_workers=num_processes) as executor:
|
316
|
+
return list(executor.map(_task_wrapper, work_items))
|
317
|
+
finally:
|
318
|
+
os.environ["QISKIT_IN_PARALLEL"] = previous_in_parallel
|