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,225 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2023.
|
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
|
+
"""Creating Sabre starting layouts."""
|
14
|
+
|
15
|
+
import itertools
|
16
|
+
|
17
|
+
from qiskit.transpiler.basepasses import AnalysisPass
|
18
|
+
from qiskit.transpiler.coupling import CouplingMap
|
19
|
+
from qiskit.transpiler.exceptions import TranspilerError
|
20
|
+
from qiskit.transpiler.passes.layout.vf2_layout import VF2Layout
|
21
|
+
from qiskit.transpiler.target import Target
|
22
|
+
from qiskit._accelerate.error_map import ErrorMap
|
23
|
+
|
24
|
+
|
25
|
+
class SabrePreLayout(AnalysisPass):
|
26
|
+
"""Choose a starting layout to use for additional Sabre layout trials.
|
27
|
+
|
28
|
+
Property Set Values Written
|
29
|
+
---------------------------
|
30
|
+
|
31
|
+
``sabre_starting_layouts`` (``list[Layout]``)
|
32
|
+
An optional list of :class:`~.Layout` objects to use for additional Sabre layout trials.
|
33
|
+
|
34
|
+
**References:**
|
35
|
+
|
36
|
+
[1] Henry Zou and Matthew Treinish and Kevin Hartman and Alexander Ivrii and Jake Lishman.
|
37
|
+
"LightSABRE: A Lightweight and Enhanced SABRE Algorithm"
|
38
|
+
`arXiv:2409.08368 <https://doi.org/10.48550/arXiv.2409.08368>`__
|
39
|
+
"""
|
40
|
+
|
41
|
+
def __init__(
|
42
|
+
self,
|
43
|
+
coupling_map,
|
44
|
+
max_distance=2,
|
45
|
+
error_rate=0.1,
|
46
|
+
max_trials_vf2=100,
|
47
|
+
call_limit_vf2=None,
|
48
|
+
improve_layout=True,
|
49
|
+
):
|
50
|
+
"""SabrePreLayout initializer.
|
51
|
+
|
52
|
+
The pass works by augmenting the coupling map with more and more "extra" edges
|
53
|
+
until VF2 succeeds to find a perfect graph isomorphism. More precisely, the
|
54
|
+
augmented coupling map contains edges between nodes that are within a given
|
55
|
+
distance ``d`` in the original coupling map, and the value of ``d`` is increased
|
56
|
+
until an isomorphism is found.
|
57
|
+
|
58
|
+
Intuitively, a better layout involves fewer extra edges. The pass also optionally
|
59
|
+
minimizes the number of extra edges involved in the layout until a local minimum
|
60
|
+
is found. This involves removing extra edges and running VF2 to see if an
|
61
|
+
isomorphism still exists.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
coupling_map (Union[CouplingMap, Target]): directed graph representing the
|
65
|
+
original coupling map or a target modelling the backend (including its
|
66
|
+
connectivity).
|
67
|
+
max_distance (int): the maximum distance to consider for augmented coupling maps.
|
68
|
+
error_rate (float): the error rate to assign to the "extra" edges. A non-zero
|
69
|
+
error rate prioritizes VF2 to choose original edges over extra edges.
|
70
|
+
max_trials_vf2 (int): specifies the maximum number of VF2 trials. A larger number
|
71
|
+
allows VF2 to explore more layouts, eventually choosing the one with the smallest
|
72
|
+
error rate.
|
73
|
+
call_limit_vf2 (int): limits each call to VF2 by bounding the number of VF2 state visits.
|
74
|
+
improve_layout (bool): whether to improve the layout by minimizing the number of
|
75
|
+
extra edges involved. This might be time-consuming as this requires additional
|
76
|
+
VF2 calls.
|
77
|
+
|
78
|
+
Raises:
|
79
|
+
TranspilerError: At runtime, if neither ``coupling_map`` or ``target`` are provided.
|
80
|
+
"""
|
81
|
+
|
82
|
+
self.max_distance = max_distance
|
83
|
+
self.error_rate = error_rate
|
84
|
+
self.max_trials_vf2 = max_trials_vf2
|
85
|
+
self.call_limit_vf2 = call_limit_vf2
|
86
|
+
self.improve_layout = improve_layout
|
87
|
+
|
88
|
+
if isinstance(coupling_map, Target):
|
89
|
+
self.target = coupling_map
|
90
|
+
self.coupling_map = self.target.build_coupling_map()
|
91
|
+
else:
|
92
|
+
self.target = None
|
93
|
+
self.coupling_map = coupling_map
|
94
|
+
|
95
|
+
super().__init__()
|
96
|
+
|
97
|
+
def run(self, dag):
|
98
|
+
"""Run the SabrePreLayout pass on `dag`.
|
99
|
+
|
100
|
+
The discovered starting layout is written to the property set
|
101
|
+
value ``sabre_starting_layouts``.
|
102
|
+
|
103
|
+
Args:
|
104
|
+
dag (DAGCircuit): DAG to create starting layout for.
|
105
|
+
"""
|
106
|
+
|
107
|
+
if self.coupling_map is None:
|
108
|
+
raise TranspilerError(
|
109
|
+
"SabrePreLayout requires coupling_map to be used with either"
|
110
|
+
"CouplingMap or a Target."
|
111
|
+
)
|
112
|
+
|
113
|
+
starting_layout = None
|
114
|
+
cur_distance = 1
|
115
|
+
while cur_distance <= self.max_distance:
|
116
|
+
augmented_map, augmented_error_map = self._add_extra_edges(cur_distance)
|
117
|
+
pass_ = VF2Layout(
|
118
|
+
augmented_map,
|
119
|
+
seed=0,
|
120
|
+
max_trials=self.max_trials_vf2,
|
121
|
+
call_limit=self.call_limit_vf2,
|
122
|
+
)
|
123
|
+
pass_.property_set["vf2_avg_error_map"] = augmented_error_map
|
124
|
+
pass_.run(dag)
|
125
|
+
|
126
|
+
if "layout" in pass_.property_set:
|
127
|
+
starting_layout = pass_.property_set["layout"]
|
128
|
+
break
|
129
|
+
|
130
|
+
cur_distance += 1
|
131
|
+
|
132
|
+
if cur_distance > 1 and starting_layout is not None:
|
133
|
+
# optionally improve starting layout
|
134
|
+
if self.improve_layout:
|
135
|
+
starting_layout = self._minimize_extra_edges(dag, starting_layout)
|
136
|
+
# write discovered layout into the property set
|
137
|
+
if "sabre_starting_layouts" not in self.property_set:
|
138
|
+
self.property_set["sabre_starting_layouts"] = [starting_layout]
|
139
|
+
else:
|
140
|
+
self.property_set["sabre_starting_layouts"].append(starting_layout)
|
141
|
+
|
142
|
+
def _add_extra_edges(self, distance):
|
143
|
+
"""Augments the coupling map with extra edges that connect nodes ``distance``
|
144
|
+
apart in the original graph. The extra edges are assigned errors allowing VF2
|
145
|
+
to prioritize real edges over extra edges.
|
146
|
+
"""
|
147
|
+
nq = len(self.coupling_map.graph)
|
148
|
+
augmented_coupling_map = CouplingMap()
|
149
|
+
augmented_coupling_map.graph = self.coupling_map.graph.copy()
|
150
|
+
augmented_error_map = ErrorMap(nq)
|
151
|
+
|
152
|
+
for x, y in itertools.combinations(self.coupling_map.graph.node_indices(), 2):
|
153
|
+
d = self.coupling_map.distance(x, y)
|
154
|
+
if 1 < d <= distance:
|
155
|
+
error_rate = 1 - ((1 - self.error_rate) ** d)
|
156
|
+
augmented_coupling_map.add_edge(x, y)
|
157
|
+
augmented_error_map.add_error((x, y), error_rate)
|
158
|
+
augmented_coupling_map.add_edge(y, x)
|
159
|
+
augmented_error_map.add_error((y, x), error_rate)
|
160
|
+
|
161
|
+
return augmented_coupling_map, augmented_error_map
|
162
|
+
|
163
|
+
def _get_extra_edges_used(self, dag, layout):
|
164
|
+
"""Returns the set of extra edges involved in the layout."""
|
165
|
+
extra_edges_used = set()
|
166
|
+
virtual_bits = layout.get_virtual_bits()
|
167
|
+
for node in dag.two_qubit_ops():
|
168
|
+
p0 = virtual_bits[node.qargs[0]]
|
169
|
+
p1 = virtual_bits[node.qargs[1]]
|
170
|
+
if self.coupling_map.distance(p0, p1) > 1:
|
171
|
+
extra_edge = (p0, p1) if p0 < p1 else (p1, p0)
|
172
|
+
extra_edges_used.add(extra_edge)
|
173
|
+
return extra_edges_used
|
174
|
+
|
175
|
+
def _find_layout(self, dag, edges):
|
176
|
+
"""Checks if there is a layout for a given set of edges."""
|
177
|
+
cm = CouplingMap(edges)
|
178
|
+
pass_ = VF2Layout(cm, seed=0, max_trials=1, call_limit=self.call_limit_vf2)
|
179
|
+
pass_.run(dag)
|
180
|
+
return pass_.property_set.get("layout", None)
|
181
|
+
|
182
|
+
def _minimize_extra_edges(self, dag, starting_layout):
|
183
|
+
"""Minimizes the set of extra edges involved in the layout. This iteratively
|
184
|
+
removes extra edges from the coupling map and uses VF2 to check if a layout
|
185
|
+
still exists. This is reasonably efficiently as it only looks for a local
|
186
|
+
minimum.
|
187
|
+
"""
|
188
|
+
# compute the set of edges in the original coupling map
|
189
|
+
real_edges = []
|
190
|
+
for x, y in itertools.combinations(self.coupling_map.graph.node_indices(), 2):
|
191
|
+
d = self.coupling_map.distance(x, y)
|
192
|
+
if d == 1:
|
193
|
+
real_edges.append((x, y))
|
194
|
+
|
195
|
+
best_layout = starting_layout
|
196
|
+
|
197
|
+
# keeps the set of "necessary" extra edges: without a necessary edge
|
198
|
+
# a layout no longer exists
|
199
|
+
extra_edges_necessary = []
|
200
|
+
|
201
|
+
extra_edges_unprocessed_set = self._get_extra_edges_used(dag, starting_layout)
|
202
|
+
|
203
|
+
while extra_edges_unprocessed_set:
|
204
|
+
# choose some unprocessed edge
|
205
|
+
edge_chosen = next(iter(extra_edges_unprocessed_set))
|
206
|
+
extra_edges_unprocessed_set.remove(edge_chosen)
|
207
|
+
|
208
|
+
# check if a layout still exists without this edge
|
209
|
+
layout = self._find_layout(
|
210
|
+
dag, real_edges + extra_edges_necessary + list(extra_edges_unprocessed_set)
|
211
|
+
)
|
212
|
+
|
213
|
+
if layout is None:
|
214
|
+
# without this edge the layout either does not exist or is too hard to find
|
215
|
+
extra_edges_necessary.append(edge_chosen)
|
216
|
+
|
217
|
+
else:
|
218
|
+
# this edge is not necessary, furthermore we can trim the set of edges to examine based
|
219
|
+
# in the edges involved in the layout.
|
220
|
+
extra_edges_unprocessed_set = self._get_extra_edges_used(dag, layout).difference(
|
221
|
+
set(extra_edges_necessary)
|
222
|
+
)
|
223
|
+
best_layout = layout
|
224
|
+
|
225
|
+
return best_layout
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2019
|
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
|
+
"""Set the ``layout`` property to the given layout."""
|
14
|
+
from qiskit.transpiler.basepasses import AnalysisPass
|
15
|
+
from qiskit.transpiler.exceptions import InvalidLayoutError
|
16
|
+
from qiskit.transpiler.layout import Layout
|
17
|
+
|
18
|
+
|
19
|
+
class SetLayout(AnalysisPass):
|
20
|
+
"""Set the ``layout`` property to the given layout.
|
21
|
+
|
22
|
+
This pass associates a physical qubit (int) to each virtual qubit
|
23
|
+
of the circuit (Qubit) in increasing order.
|
24
|
+
"""
|
25
|
+
|
26
|
+
def __init__(self, layout):
|
27
|
+
"""SetLayout initializer.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
layout (Layout or List[int]): the layout to set. It can be:
|
31
|
+
|
32
|
+
* a :class:`Layout` instance: sets that layout.
|
33
|
+
* a list of integers: takes the index in the list as the physical position in which the
|
34
|
+
virtual qubit is going to be mapped.
|
35
|
+
|
36
|
+
"""
|
37
|
+
super().__init__()
|
38
|
+
self.layout = layout
|
39
|
+
|
40
|
+
def run(self, dag):
|
41
|
+
"""Run the SetLayout pass on ``dag``.
|
42
|
+
|
43
|
+
Args:
|
44
|
+
dag (DAGCircuit): DAG to map.
|
45
|
+
|
46
|
+
Returns:
|
47
|
+
DAGCircuit: the original DAG.
|
48
|
+
"""
|
49
|
+
if isinstance(self.layout, list):
|
50
|
+
if len(self.layout) != len(dag.qubits):
|
51
|
+
raise InvalidLayoutError(
|
52
|
+
"The length of the layout is different than the size of the "
|
53
|
+
f"circuit: {len(self.layout)} <> {len(dag.qubits)}"
|
54
|
+
)
|
55
|
+
if len(set(self.layout)) != len(self.layout):
|
56
|
+
raise InvalidLayoutError(
|
57
|
+
f"The provided layout {self.layout} contains duplicate qubits"
|
58
|
+
)
|
59
|
+
layout = Layout({phys: dag.qubits[i] for i, phys in enumerate(self.layout)})
|
60
|
+
elif isinstance(self.layout, Layout):
|
61
|
+
layout = self.layout.copy()
|
62
|
+
elif self.layout is None:
|
63
|
+
layout = None
|
64
|
+
else:
|
65
|
+
raise InvalidLayoutError(
|
66
|
+
f"SetLayout was initialized with the layout type: {type(self.layout)}"
|
67
|
+
)
|
68
|
+
self.property_set["layout"] = layout
|
69
|
+
return dag
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2018.
|
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
|
+
"""Choose a Layout by assigning ``n`` circuit qubits to device qubits ``0, .., n-1``."""
|
14
|
+
|
15
|
+
from qiskit.transpiler.layout import Layout
|
16
|
+
from qiskit.transpiler.basepasses import AnalysisPass
|
17
|
+
from qiskit.transpiler.exceptions import TranspilerError
|
18
|
+
from qiskit.transpiler.target import Target
|
19
|
+
|
20
|
+
|
21
|
+
class TrivialLayout(AnalysisPass):
|
22
|
+
"""Choose a Layout by assigning ``n`` circuit qubits to device qubits ``0, .., n-1``.
|
23
|
+
|
24
|
+
A pass for choosing a Layout of a circuit onto a Coupling graph, using a simple
|
25
|
+
round-robin order.
|
26
|
+
|
27
|
+
This pass associates a physical qubit (int) to each virtual qubit
|
28
|
+
of the circuit (Qubit) in increasing order.
|
29
|
+
|
30
|
+
Does not assume any ancilla.
|
31
|
+
"""
|
32
|
+
|
33
|
+
def __init__(self, coupling_map):
|
34
|
+
"""TrivialLayout initializer.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
coupling_map (Union[CouplingMap, Target]): directed graph representing a coupling map.
|
38
|
+
|
39
|
+
Raises:
|
40
|
+
TranspilerError: if invalid options
|
41
|
+
"""
|
42
|
+
super().__init__()
|
43
|
+
if isinstance(coupling_map, Target):
|
44
|
+
self.target = coupling_map
|
45
|
+
self.coupling_map = self.target.build_coupling_map()
|
46
|
+
else:
|
47
|
+
self.target = None
|
48
|
+
self.coupling_map = coupling_map
|
49
|
+
|
50
|
+
def run(self, dag):
|
51
|
+
"""Run the TrivialLayout pass on `dag`.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
dag (DAGCircuit): DAG to find layout for.
|
55
|
+
|
56
|
+
Raises:
|
57
|
+
TranspilerError: if dag wider than the target backend
|
58
|
+
"""
|
59
|
+
if self.target is not None:
|
60
|
+
if dag.num_qubits() > self.target.num_qubits:
|
61
|
+
raise TranspilerError("Number of qubits greater than device.")
|
62
|
+
elif dag.num_qubits() > self.coupling_map.size():
|
63
|
+
raise TranspilerError("Number of qubits greater than device.")
|
64
|
+
self.property_set["layout"] = Layout.generate_trivial_layout(
|
65
|
+
*(dag.qubits + list(dag.qregs.values()))
|
66
|
+
)
|
@@ -0,0 +1,256 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
|
14
|
+
"""VF2Layout pass to find a layout using subgraph isomorphism"""
|
15
|
+
from enum import Enum
|
16
|
+
import itertools
|
17
|
+
import logging
|
18
|
+
import time
|
19
|
+
|
20
|
+
from rustworkx import vf2_mapping
|
21
|
+
|
22
|
+
from qiskit.transpiler.layout import Layout
|
23
|
+
from qiskit.transpiler.basepasses import AnalysisPass
|
24
|
+
from qiskit.transpiler.exceptions import TranspilerError
|
25
|
+
from qiskit.transpiler.passes.layout import vf2_utils
|
26
|
+
|
27
|
+
|
28
|
+
logger = logging.getLogger(__name__)
|
29
|
+
|
30
|
+
|
31
|
+
class VF2LayoutStopReason(Enum):
|
32
|
+
"""Stop reasons for VF2Layout pass."""
|
33
|
+
|
34
|
+
SOLUTION_FOUND = "solution found"
|
35
|
+
NO_SOLUTION_FOUND = "nonexistent solution"
|
36
|
+
MORE_THAN_2Q = ">2q gates in basis"
|
37
|
+
|
38
|
+
|
39
|
+
class VF2Layout(AnalysisPass):
|
40
|
+
"""A pass for choosing a Layout of a circuit onto a Coupling graph, as
|
41
|
+
a subgraph isomorphism problem, solved by VF2++.
|
42
|
+
|
43
|
+
If a solution is found that means there is a "perfect layout" and that no
|
44
|
+
further swap mapping or routing is needed. If a solution is found the layout
|
45
|
+
will be set in the property set as ``property_set['layout']``. However, if no
|
46
|
+
solution is found, no ``property_set['layout']`` is set. The stopping reason is
|
47
|
+
set in ``property_set['VF2Layout_stop_reason']`` in all the cases and will be
|
48
|
+
one of the values enumerated in ``VF2LayoutStopReason`` which has the
|
49
|
+
following values:
|
50
|
+
|
51
|
+
* ``"solution found"``: If a perfect layout was found.
|
52
|
+
* ``"nonexistent solution"``: If no perfect layout was found.
|
53
|
+
* ``">2q gates in basis"``: If VF2Layout can't work with basis
|
54
|
+
|
55
|
+
By default, this pass will construct a heuristic scoring map based on
|
56
|
+
the error rates in the provided ``target`` (or ``properties`` if ``target``
|
57
|
+
is not provided). However, analysis passes can be run prior to this pass
|
58
|
+
and set ``vf2_avg_error_map`` in the property set with a :class:`~.ErrorMap`
|
59
|
+
instance. If a value is ``NaN`` that is treated as an ideal edge
|
60
|
+
For example if an error map is created as::
|
61
|
+
|
62
|
+
from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap
|
63
|
+
|
64
|
+
error_map = ErrorMap(3)
|
65
|
+
error_map.add_error((0, 0), 0.0024)
|
66
|
+
error_map.add_error((0, 1), 0.01)
|
67
|
+
error_map.add_error((1, 1), 0.0032)
|
68
|
+
|
69
|
+
that represents the error map for a 2 qubit target, where the avg 1q error
|
70
|
+
rate is ``0.0024`` on qubit 0 and ``0.0032`` on qubit 1. Then the avg 2q
|
71
|
+
error rate for gates that operate on (0, 1) is 0.01 and (1, 0) is not
|
72
|
+
supported by the target. This will be used for scoring if it's set as the
|
73
|
+
``vf2_avg_error_map`` key in the property set when :class:`~.VF2Layout` is run.
|
74
|
+
"""
|
75
|
+
|
76
|
+
def __init__(
|
77
|
+
self,
|
78
|
+
coupling_map=None,
|
79
|
+
strict_direction=False,
|
80
|
+
seed=None,
|
81
|
+
call_limit=None,
|
82
|
+
time_limit=None,
|
83
|
+
max_trials=None,
|
84
|
+
target=None,
|
85
|
+
):
|
86
|
+
"""Initialize a ``VF2Layout`` pass instance
|
87
|
+
|
88
|
+
Args:
|
89
|
+
coupling_map (CouplingMap): Directed graph representing a coupling map.
|
90
|
+
strict_direction (bool): If True, considers the direction of the coupling map.
|
91
|
+
Default is False.
|
92
|
+
seed (int): Sets the seed of the PRNG. -1 Means no node shuffling.
|
93
|
+
call_limit (int): The number of state visits to attempt in each execution of
|
94
|
+
VF2.
|
95
|
+
time_limit (float): The total time limit in seconds to run ``VF2Layout``
|
96
|
+
max_trials (int): The maximum number of trials to run VF2 to find
|
97
|
+
a layout. If this is not specified the number of trials will be limited
|
98
|
+
based on the number of edges in the interaction graph or the coupling graph
|
99
|
+
(whichever is larger) if no other limits are set. If set to a value <= 0 no
|
100
|
+
limit on the number of trials will be set.
|
101
|
+
target (Target): A target representing the backend device to run ``VF2Layout`` on.
|
102
|
+
If specified it will supersede a set value for
|
103
|
+
``coupling_map`` if the :class:`.Target` contains connectivity constraints. If the value
|
104
|
+
of ``target`` models an ideal backend without any constraints then the value of
|
105
|
+
``coupling_map``
|
106
|
+
will be used.
|
107
|
+
|
108
|
+
Raises:
|
109
|
+
TypeError: At runtime, if neither ``coupling_map`` or ``target`` are provided.
|
110
|
+
"""
|
111
|
+
super().__init__()
|
112
|
+
self.target = target
|
113
|
+
if (
|
114
|
+
target is not None
|
115
|
+
and (target_coupling_map := self.target.build_coupling_map()) is not None
|
116
|
+
):
|
117
|
+
self.coupling_map = target_coupling_map
|
118
|
+
else:
|
119
|
+
self.coupling_map = coupling_map
|
120
|
+
self.strict_direction = strict_direction
|
121
|
+
self.seed = seed
|
122
|
+
self.call_limit = call_limit
|
123
|
+
self.time_limit = time_limit
|
124
|
+
self.max_trials = max_trials
|
125
|
+
self.avg_error_map = None
|
126
|
+
|
127
|
+
def run(self, dag):
|
128
|
+
"""run the layout method"""
|
129
|
+
if self.coupling_map is None:
|
130
|
+
raise TranspilerError("coupling_map or target must be specified.")
|
131
|
+
self.avg_error_map = self.property_set["vf2_avg_error_map"]
|
132
|
+
if self.avg_error_map is None:
|
133
|
+
self.avg_error_map = vf2_utils.build_average_error_map(self.target, self.coupling_map)
|
134
|
+
|
135
|
+
result = vf2_utils.build_interaction_graph(dag, self.strict_direction)
|
136
|
+
if result is None:
|
137
|
+
self.property_set["VF2Layout_stop_reason"] = VF2LayoutStopReason.MORE_THAN_2Q
|
138
|
+
return
|
139
|
+
im_graph, im_graph_node_map, reverse_im_graph_node_map, free_nodes = result
|
140
|
+
scoring_edge_list = vf2_utils.build_edge_list(im_graph)
|
141
|
+
scoring_bit_list = vf2_utils.build_bit_list(im_graph, im_graph_node_map)
|
142
|
+
cm_graph, cm_nodes = vf2_utils.shuffle_coupling_graph(
|
143
|
+
self.coupling_map, self.seed, self.strict_direction
|
144
|
+
)
|
145
|
+
# Filter qubits without any supported operations. If they don't support any operations
|
146
|
+
# They're not valid for layout selection
|
147
|
+
if self.target is not None and self.target.qargs is not None:
|
148
|
+
has_operations = set(itertools.chain.from_iterable(self.target.qargs))
|
149
|
+
to_remove = set(range(len(cm_nodes))).difference(has_operations)
|
150
|
+
if to_remove:
|
151
|
+
cm_graph.remove_nodes_from([cm_nodes[i] for i in to_remove])
|
152
|
+
|
153
|
+
# To avoid trying to over optimize the result by default limit the number
|
154
|
+
# of trials based on the size of the graphs. For circuits with simple layouts
|
155
|
+
# like an all 1q circuit we don't want to sit forever trying every possible
|
156
|
+
# mapping in the search space if no other limits are set
|
157
|
+
if self.max_trials is None and self.call_limit is None and self.time_limit is None:
|
158
|
+
im_graph_edge_count = len(im_graph.edge_list())
|
159
|
+
cm_graph_edge_count = len(self.coupling_map.graph.edge_list())
|
160
|
+
self.max_trials = max(im_graph_edge_count, cm_graph_edge_count) + 15
|
161
|
+
|
162
|
+
logger.debug("Running VF2 to find mappings")
|
163
|
+
mappings = vf2_mapping(
|
164
|
+
cm_graph,
|
165
|
+
im_graph,
|
166
|
+
subgraph=True,
|
167
|
+
id_order=False,
|
168
|
+
induced=False,
|
169
|
+
call_limit=self.call_limit,
|
170
|
+
)
|
171
|
+
chosen_layout = None
|
172
|
+
chosen_layout_score = None
|
173
|
+
start_time = time.time()
|
174
|
+
trials = 0
|
175
|
+
|
176
|
+
def mapping_to_layout(layout_mapping):
|
177
|
+
return Layout({reverse_im_graph_node_map[k]: v for k, v in layout_mapping.items()})
|
178
|
+
|
179
|
+
for mapping in mappings:
|
180
|
+
trials += 1
|
181
|
+
logger.debug("Running trial: %s", trials)
|
182
|
+
stop_reason = VF2LayoutStopReason.SOLUTION_FOUND
|
183
|
+
layout_mapping = {im_i: cm_nodes[cm_i] for cm_i, im_i in mapping.items()}
|
184
|
+
|
185
|
+
# If the graphs have the same number of nodes we don't need to score or do multiple
|
186
|
+
# trials as the score heuristic currently doesn't weigh nodes based on gates on a
|
187
|
+
# qubit so the scores will always all be the same
|
188
|
+
if len(cm_graph) == len(im_graph):
|
189
|
+
chosen_layout = mapping_to_layout(layout_mapping)
|
190
|
+
break
|
191
|
+
# If there is no error map available we can just skip the scoring stage as there
|
192
|
+
# is nothing to score with, so any match is the best we can find.
|
193
|
+
if self.avg_error_map is None:
|
194
|
+
chosen_layout = mapping_to_layout(layout_mapping)
|
195
|
+
break
|
196
|
+
layout_score = vf2_utils.score_layout(
|
197
|
+
self.avg_error_map,
|
198
|
+
layout_mapping,
|
199
|
+
im_graph_node_map,
|
200
|
+
reverse_im_graph_node_map,
|
201
|
+
im_graph,
|
202
|
+
self.strict_direction,
|
203
|
+
edge_list=scoring_edge_list,
|
204
|
+
bit_list=scoring_bit_list,
|
205
|
+
)
|
206
|
+
# If the layout score is 0 we can't do any better and we'll just
|
207
|
+
# waste time finding additional mappings that will at best match
|
208
|
+
# the performance, so exit early in this case
|
209
|
+
if layout_score == 0.0:
|
210
|
+
chosen_layout = mapping_to_layout(layout_mapping)
|
211
|
+
break
|
212
|
+
logger.debug("Trial %s has score %s", trials, layout_score)
|
213
|
+
if chosen_layout is None:
|
214
|
+
chosen_layout = mapping_to_layout(layout_mapping)
|
215
|
+
chosen_layout_score = layout_score
|
216
|
+
elif layout_score < chosen_layout_score:
|
217
|
+
layout = mapping_to_layout(layout_mapping)
|
218
|
+
logger.debug(
|
219
|
+
"Found layout %s has a lower score (%s) than previous best %s (%s)",
|
220
|
+
layout,
|
221
|
+
layout_score,
|
222
|
+
chosen_layout,
|
223
|
+
chosen_layout_score,
|
224
|
+
)
|
225
|
+
chosen_layout = layout
|
226
|
+
chosen_layout_score = layout_score
|
227
|
+
if self.max_trials is not None and self.max_trials > 0 and trials >= self.max_trials:
|
228
|
+
logger.debug("Trial %s is >= configured max trials %s", trials, self.max_trials)
|
229
|
+
break
|
230
|
+
elapsed_time = time.time() - start_time
|
231
|
+
if self.time_limit is not None and elapsed_time >= self.time_limit:
|
232
|
+
logger.debug(
|
233
|
+
"VF2Layout has taken %s which exceeds configured max time: %s",
|
234
|
+
elapsed_time,
|
235
|
+
self.time_limit,
|
236
|
+
)
|
237
|
+
break
|
238
|
+
if chosen_layout is None:
|
239
|
+
stop_reason = VF2LayoutStopReason.NO_SOLUTION_FOUND
|
240
|
+
else:
|
241
|
+
chosen_layout = vf2_utils.map_free_qubits(
|
242
|
+
free_nodes,
|
243
|
+
chosen_layout,
|
244
|
+
cm_graph.num_nodes(),
|
245
|
+
reverse_im_graph_node_map,
|
246
|
+
self.avg_error_map,
|
247
|
+
)
|
248
|
+
# No free qubits for free qubit mapping
|
249
|
+
if chosen_layout is None:
|
250
|
+
self.property_set["VF2Layout_stop_reason"] = VF2LayoutStopReason.NO_SOLUTION_FOUND
|
251
|
+
return
|
252
|
+
self.property_set["layout"] = chosen_layout
|
253
|
+
for reg in dag.qregs.values():
|
254
|
+
self.property_set["layout"].add_register(reg)
|
255
|
+
|
256
|
+
self.property_set["VF2Layout_stop_reason"] = stop_reason
|